// 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 <memory>
#include <utility>

#include "base/containers/hash_tables.h"
#include "base/logging.h"
#include "base/macros.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, std::unique_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_
