// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_CONTAINERS_SCOPED_PTR_HASH_MAP_H_
#define BASE_CONTAINERS_SCOPED_PTR_HASH_MAP_H_

#include <stddef.h>

#include <algorithm>
#include <utility>

#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"

namespace base {

// Deprecated. Use std::unordered_map instead. https://crbug.com/579229
//
// This type acts like a hash_map<K, scoped_ptr<V, D> >, based on top of
// base::hash_map. The ScopedPtrHashMap has ownership of all values in the data
// structure.
template <typename Key, typename ScopedPtr>
class ScopedPtrHashMap {
  typedef base::hash_map<Key, typename ScopedPtr::element_type*> Container;

 public:
  typedef typename Container::key_type key_type;
  typedef typename Container::mapped_type mapped_type;
  typedef typename Container::value_type value_type;
  typedef typename Container::iterator iterator;
  typedef typename Container::const_iterator const_iterator;

  ScopedPtrHashMap() {}

  ~ScopedPtrHashMap() { clear(); }

  void swap(ScopedPtrHashMap<Key, ScopedPtr>& other) {
    data_.swap(other.data_);
  }

  // Replaces value but not key if key is already present.
  iterator set(const Key& key, ScopedPtr data) {
    iterator it = find(key);
    if (it != end()) {
      // Let ScopedPtr decide how to delete. For example, it may use custom
      // deleter.
      ScopedPtr(it->second).reset();
      it->second = data.release();
      return it;
    }

    return data_.insert(std::make_pair(key, data.release())).first;
  }

  // Does nothing if key is already present
  std::pair<iterator, bool> add(const Key& key, ScopedPtr data) {
    std::pair<iterator, bool> result =
        data_.insert(std::make_pair(key, data.get()));
    if (result.second)
      ::ignore_result(data.release());
    return result;
  }

  void erase(iterator it) {
    // Let ScopedPtr decide how to delete.
    ScopedPtr(it->second).reset();
    data_.erase(it);
  }

  size_t erase(const Key& k) {
    iterator it = data_.find(k);
    if (it == data_.end())
      return 0;
    erase(it);
    return 1;
  }

  ScopedPtr take(iterator it) {
    DCHECK(it != data_.end());
    if (it == data_.end())
      return ScopedPtr();

    ScopedPtr ret(it->second);
    it->second = NULL;
    return ret;
  }

  ScopedPtr take(const Key& k) {
    iterator it = find(k);
    if (it == data_.end())
      return ScopedPtr();

    return take(it);
  }

  ScopedPtr take_and_erase(iterator it) {
    DCHECK(it != data_.end());
    if (it == data_.end())
      return ScopedPtr();

    ScopedPtr ret(it->second);
    data_.erase(it);
    return ret;
  }

  ScopedPtr take_and_erase(const Key& k) {
    iterator it = find(k);
    if (it == data_.end())
      return ScopedPtr();

    return take_and_erase(it);
  }

  // Returns the element in the hash_map that matches the given key.
  // If no such element exists it returns NULL.
  typename ScopedPtr::element_type* get(const Key& k) const {
    const_iterator it = find(k);
    if (it == end())
      return NULL;
    return it->second;
  }

  inline bool contains(const Key& k) const { return data_.count(k) > 0; }

  inline void clear() {
    auto it = data_.begin();
    while (it != data_.end()) {
      // NOTE: Like STLDeleteContainerPointers, deleting behind the iterator.
      // Deleting the value does not always invalidate the iterator, but it may
      // do so if the key is a pointer into the value object.
      auto temp = it;
      ++it;
      // Let ScopedPtr decide how to delete.
      ScopedPtr(temp->second).reset();
    }
    data_.clear();
  }

  inline const_iterator find(const Key& k) const { return data_.find(k); }
  inline iterator find(const Key& k) { return data_.find(k); }

  inline size_t count(const Key& k) const { return data_.count(k); }
  inline std::pair<const_iterator, const_iterator> equal_range(
      const Key& k) const {
    return data_.equal_range(k);
  }
  inline std::pair<iterator, iterator> equal_range(const Key& k) {
    return data_.equal_range(k);
  }

  inline size_t size() const { return data_.size(); }
  inline size_t max_size() const { return data_.max_size(); }

  inline bool empty() const { return data_.empty(); }

  inline size_t bucket_count() const { return data_.bucket_count(); }
  inline void resize(size_t size) { return data_.resize(size); }

  inline iterator begin() { return data_.begin(); }
  inline const_iterator begin() const { return data_.begin(); }
  inline iterator end() { return data_.end(); }
  inline const_iterator end() const { return data_.end(); }

 private:
  Container data_;

  DISALLOW_COPY_AND_ASSIGN(ScopedPtrHashMap);
};

}  // namespace base

#endif  // BASE_CONTAINERS_SCOPED_PTR_HASH_MAP_H_
