// Copyright 2017 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_FLAT_MAP_H_
#define BASE_CONTAINERS_FLAT_MAP_H_

#include <functional>
#include <tuple>
#include <utility>

#include "base/containers/flat_tree.h"
#include "base/logging.h"
#include "base/template_util.h"
#include "nb/cpp14oncpp11.h"

namespace base {

namespace internal {

// An implementation of the flat_tree GetKeyFromValue template parameter that
// extracts the key as the first element of a pair.
template <class Key, class Mapped>
struct GetKeyFromValuePairFirst {
  const Key& operator()(const std::pair<Key, Mapped>& p) const {
    return p.first;
  }
};

}  // namespace internal

// flat_map is a container with a std::map-like interface that stores its
// contents in a sorted vector.
//
// Please see //base/containers/README.md for an overview of which container
// to select.
//
// PROS
//
//  - Good memory locality.
//  - Low overhead, especially for smaller maps.
//  - Performance is good for more workloads than you might expect (see
//    overview link above).
//  - Supports C++14 map interface.
//
// CONS
//
//  - Inserts and removals are O(n).
//
// IMPORTANT NOTES
//
//  - Iterators are invalidated across mutations.
//  - If possible, construct a flat_map in one operation by inserting into
//    a std::vector and moving that vector into the flat_map constructor.
//
// QUICK REFERENCE
//
// Most of the core functionality is inherited from flat_tree. Please see
// flat_tree.h for more details for most of these functions. As a quick
// reference, the functions available are:
//
// Constructors (inputs need not be sorted):
//   flat_map(InputIterator first, InputIterator last,
//            FlatContainerDupes = KEEP_FIRST_OF_DUPES,
//            const Compare& compare = Compare());
//   flat_map(const flat_map&);
//   flat_map(flat_map&&);
//   flat_map(std::vector<value_type>,
//            FlatContainerDupes = KEEP_FIRST_OF_DUPES,
//            const Compare& compare = Compare()); // Re-use storage.
//   flat_map(std::initializer_list<value_type> ilist,
//            FlatContainerDupes = KEEP_FIRST_OF_DUPES,
//            const Compare& comp = Compare());
//
// Assignment functions:
//   flat_map& operator=(const flat_map&);
//   flat_map& operator=(flat_map&&);
//   flat_map& operator=(initializer_list<value_type>);
//
// Memory management functions:
//   void   reserve(size_t);
//   size_t capacity() const;
//   void   shrink_to_fit();
//
// Size management functions:
//   void   clear();
//   size_t size() const;
//   size_t max_size() const;
//   bool   empty() const;
//
// Iterator functions:
//   iterator               begin();
//   const_iterator         begin() const;
//   const_iterator         cbegin() const;
//   iterator               end();
//   const_iterator         end() const;
//   const_iterator         cend() const;
//   reverse_iterator       rbegin();
//   const reverse_iterator rbegin() const;
//   const_reverse_iterator crbegin() const;
//   reverse_iterator       rend();
//   const_reverse_iterator rend() const;
//   const_reverse_iterator crend() const;
//
// Insert and accessor functions:
//   mapped_type&         operator[](const key_type&);
//   mapped_type&         operator[](key_type&&);
//   pair<iterator, bool> insert(const value_type&);
//   pair<iterator, bool> insert(value_type&&);
//   iterator             insert(const_iterator hint, const value_type&);
//   iterator             insert(const_iterator hint, value_type&&);
//   void                 insert(InputIterator first, InputIterator last,
//                               FlatContainerDupes = KEEP_FIRST_OF_DUPES);
//   pair<iterator, bool> insert_or_assign(K&&, M&&);
//   iterator             insert_or_assign(const_iterator hint, K&&, M&&);
//   pair<iterator, bool> emplace(Args&&...);
//   iterator             emplace_hint(const_iterator, Args&&...);
//   pair<iterator, bool> try_emplace(K&&, Args&&...);
//   iterator             try_emplace(const_iterator hint, K&&, Args&&...);
//
// Erase functions:
//   iterator erase(iterator);
//   iterator erase(const_iterator);
//   iterator erase(const_iterator first, const_iterator& last);
//   template <class K> size_t erase(const K& key);
//
// Comparators (see std::map documentation).
//   key_compare   key_comp() const;
//   value_compare value_comp() const;
//
// Search functions:
//   template <typename K> size_t                   count(const K&) const;
//   template <typename K> iterator                 find(const K&);
//   template <typename K> const_iterator           find(const K&) const;
//   template <typename K> pair<iterator, iterator> equal_range(const K&);
//   template <typename K> iterator                 lower_bound(const K&);
//   template <typename K> const_iterator           lower_bound(const K&) const;
//   template <typename K> iterator                 upper_bound(const K&);
//   template <typename K> const_iterator           upper_bound(const K&) const;
//
// General functions:
//   void swap(flat_map&&);
//
// Non-member operators:
//   bool operator==(const flat_map&, const flat_map);
//   bool operator!=(const flat_map&, const flat_map);
//   bool operator<(const flat_map&, const flat_map);
//   bool operator>(const flat_map&, const flat_map);
//   bool operator>=(const flat_map&, const flat_map);
//   bool operator<=(const flat_map&, const flat_map);
//
template <class Key, class Mapped, class Compare = std::less<void>>
class flat_map : public ::base::internal::flat_tree<
                     Key,
                     std::pair<Key, Mapped>,
                     ::base::internal::GetKeyFromValuePairFirst<Key, Mapped>,
                     Compare> {
 private:
  using tree = typename ::base::internal::flat_tree<
      Key,
      std::pair<Key, Mapped>,
      ::base::internal::GetKeyFromValuePairFirst<Key, Mapped>,
      Compare>;

 public:
  using key_type = typename tree::key_type;
  using mapped_type = Mapped;
  using value_type = typename tree::value_type;
  using iterator = typename tree::iterator;
  using const_iterator = typename tree::const_iterator;

  // --------------------------------------------------------------------------
  // Lifetime and assignments.
  //
  // Note: we could do away with these constructors, destructor and assignment
  // operator overloads by inheriting |tree|'s, but this breaks the GCC build
  // due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84782 (see
  // https://crbug.com/837221).

  flat_map() = default;
  explicit flat_map(const Compare& comp);

  template <class InputIterator>
  flat_map(InputIterator first,
           InputIterator last,
           FlatContainerDupes dupe_handling = KEEP_FIRST_OF_DUPES,
           const Compare& comp = Compare());

  flat_map(const flat_map&) = default;
  flat_map(flat_map&&) noexcept = default;

  flat_map(std::vector<value_type> items,
           FlatContainerDupes dupe_handling = KEEP_FIRST_OF_DUPES,
           const Compare& comp = Compare());

  flat_map(std::initializer_list<value_type> ilist,
           FlatContainerDupes dupe_handling = KEEP_FIRST_OF_DUPES,
           const Compare& comp = Compare());

  ~flat_map() = default;

  flat_map& operator=(const flat_map&) = default;
  flat_map& operator=(flat_map&&) = default;
  // Takes the first if there are duplicates in the initializer list.
  flat_map& operator=(std::initializer_list<value_type> ilist);

  // --------------------------------------------------------------------------
  // Map-specific insert operations.
  //
  // Normal insert() functions are inherited from flat_tree.
  //
  // Assume that every operation invalidates iterators and references.
  // Insertion of one element can take O(size).

  mapped_type& operator[](const key_type& key);
  mapped_type& operator[](key_type&& key);

  template <class K, class M>
  std::pair<iterator, bool> insert_or_assign(K&& key, M&& obj);
  template <class K, class M>
  iterator insert_or_assign(const_iterator hint, K&& key, M&& obj);

  template <class K, class... Args>
  std::enable_if_t<std::is_constructible<key_type, K&&>::value,
                   std::pair<iterator, bool>>
  try_emplace(K&& key, Args&&... args);

  template <class K, class... Args>
  std::enable_if_t<std::is_constructible<key_type, K&&>::value, iterator>
  try_emplace(const_iterator hint, K&& key, Args&&... args);

  // --------------------------------------------------------------------------
  // General operations.
  //
  // Assume that swap invalidates iterators and references.

  void swap(flat_map& other) noexcept;

  friend void swap(flat_map& lhs, flat_map& rhs) noexcept { lhs.swap(rhs); }
};

// ----------------------------------------------------------------------------
// Lifetime.

template <class Key, class Mapped, class Compare>
flat_map<Key, Mapped, Compare>::flat_map(const Compare& comp) : tree(comp) {}

template <class Key, class Mapped, class Compare>
template <class InputIterator>
flat_map<Key, Mapped, Compare>::flat_map(InputIterator first,
                                         InputIterator last,
                                         FlatContainerDupes dupe_handling,
                                         const Compare& comp)
    : tree(first, last, dupe_handling, comp) {}

template <class Key, class Mapped, class Compare>
flat_map<Key, Mapped, Compare>::flat_map(std::vector<value_type> items,
                                         FlatContainerDupes dupe_handling,
                                         const Compare& comp)
    : tree(std::move(items), dupe_handling, comp) {}

template <class Key, class Mapped, class Compare>
flat_map<Key, Mapped, Compare>::flat_map(
    std::initializer_list<value_type> ilist,
    FlatContainerDupes dupe_handling,
    const Compare& comp)
    : flat_map(std::begin(ilist), std::end(ilist), dupe_handling, comp) {}

// ----------------------------------------------------------------------------
// Assignments.

template <class Key, class Mapped, class Compare>
auto flat_map<Key, Mapped, Compare>::operator=(
    std::initializer_list<value_type> ilist) -> flat_map& {
  // When https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84782 gets fixed, we
  // need to remember to inherit tree::operator= to prevent
  //   flat_map<...> x;
  //   x = {...};
  // from first creating a flat_map and then move assigning it. This most
  // likely would be optimized away but still affects our debug builds.
  tree::operator=(ilist);
  return *this;
}

// ----------------------------------------------------------------------------
// Insert operations.

template <class Key, class Mapped, class Compare>
auto flat_map<Key, Mapped, Compare>::operator[](const key_type& key)
    -> mapped_type& {
  iterator found = tree::lower_bound(key);
  if (found == tree::end() || tree::key_comp()(key, found->first))
    found = tree::unsafe_emplace(found, key, mapped_type());
  return found->second;
}

template <class Key, class Mapped, class Compare>
auto flat_map<Key, Mapped, Compare>::operator[](key_type&& key)
    -> mapped_type& {
  iterator found = tree::lower_bound(key);
  if (found == tree::end() || tree::key_comp()(key, found->first))
    found = tree::unsafe_emplace(found, std::move(key), mapped_type());
  return found->second;
}

template <class Key, class Mapped, class Compare>
template <class K, class M>
auto flat_map<Key, Mapped, Compare>::insert_or_assign(K&& key, M&& obj)
    -> std::pair<iterator, bool> {
  auto result =
      tree::emplace_key_args(key, std::forward<K>(key), std::forward<M>(obj));
  if (!result.second)
    result.first->second = std::forward<M>(obj);
  return result;
}

template <class Key, class Mapped, class Compare>
template <class K, class M>
auto flat_map<Key, Mapped, Compare>::insert_or_assign(const_iterator hint,
                                                      K&& key,
                                                      M&& obj) -> iterator {
  auto result = tree::emplace_hint_key_args(hint, key, std::forward<K>(key),
                                            std::forward<M>(obj));
  if (!result.second)
    result.first->second = std::forward<M>(obj);
  return result.first;
}

template <class Key, class Mapped, class Compare>
template <class K, class... Args>
auto flat_map<Key, Mapped, Compare>::try_emplace(K&& key, Args&&... args)
    -> std::enable_if_t<std::is_constructible<key_type, K&&>::value,
                        std::pair<iterator, bool>> {
  return tree::emplace_key_args(
      key, std::piecewise_construct,
      std::forward_as_tuple(std::forward<K>(key)),
      std::forward_as_tuple(std::forward<Args>(args)...));
}

template <class Key, class Mapped, class Compare>
template <class K, class... Args>
auto flat_map<Key, Mapped, Compare>::try_emplace(const_iterator hint,
                                                 K&& key,
                                                 Args&&... args)
    -> std::enable_if_t<std::is_constructible<key_type, K&&>::value, iterator> {
  return tree::emplace_hint_key_args(
             hint, key, std::piecewise_construct,
             std::forward_as_tuple(std::forward<K>(key)),
             std::forward_as_tuple(std::forward<Args>(args)...))
      .first;
}

// ----------------------------------------------------------------------------
// General operations.

template <class Key, class Mapped, class Compare>
void flat_map<Key, Mapped, Compare>::swap(flat_map& other) noexcept {
  tree::swap(other);
}

}  // namespace base

#endif  // BASE_CONTAINERS_FLAT_MAP_H_
