| Index: base/containers/flat_map.h
|
| diff --git a/base/containers/flat_map.h b/base/containers/flat_map.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..58e9a2a0aac2d63de437c8767260d03eee582073
|
| --- /dev/null
|
| +++ b/base/containers/flat_map.h
|
| @@ -0,0 +1,214 @@
|
| +// 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 <utility>
|
| +
|
| +#include "base/containers/flat_tree.h"
|
| +#include "base/logging.h"
|
| +
|
| +namespace base {
|
| +
|
| +namespace internal {
|
| +
|
| +// An implementation of the flat_set 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
|
| +
|
| +// Overview:
|
| +// This file implements flat_map container. It is an alternative to standard
|
| +// sorted containers that stores its elements in contiguous memory (a vector>
|
| +//
|
| +// Additional documentation and usage advice is in flat_set.h.
|
| +//
|
| +// Most of the core functionality is inherited from flat_tree.
|
| +template <class Key, class Mapped, class Compare = std::less<Key>>
|
| +// Meets the requirements of Container, AssociativeContainer,
|
| +// ReversibleContainer.
|
| +// Requires: Key is Movable, Compare is a StrictWeakOrdering on Key.
|
| +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 mapped_type = Mapped;
|
| + using value_type = typename tree::value_type;
|
| +
|
| + // --------------------------------------------------------------------------
|
| + // Lifetime.
|
| + //
|
| + // Constructors that take range guarantee O(N * log(N)) + O(N) complexity
|
| + // (N is a range length). Thr range constructors are NOT stable. If there are
|
| + // duplicates an arbitrary one will be chosen.
|
| + //
|
| + // Assume that move constructors invalidate iterators and references.
|
| +
|
| + flat_map();
|
| + explicit flat_map(const Compare& comp);
|
| +
|
| + // Not stable in the presence of duplicates in the initializer list.
|
| + template <class InputIterator>
|
| + flat_map(InputIterator first,
|
| + InputIterator last,
|
| + const Compare& comp = Compare());
|
| +
|
| + flat_map(const flat_map&);
|
| + flat_map(flat_map&&);
|
| +
|
| + // Not stable in the presence of duplicates in the initializer list.
|
| + flat_map(std::initializer_list<value_type> ilist,
|
| + const Compare& comp = Compare());
|
| +
|
| + ~flat_map();
|
| +
|
| + // --------------------------------------------------------------------------
|
| + // Assignments.
|
| + //
|
| + // Assume that move assignment invalidates iterators and references.
|
| +
|
| + flat_map& operator=(const flat_map&);
|
| + flat_map& operator=(flat_map&&);
|
| + // Not stable in the presence of 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& operator[](const Key& key);
|
| + Mapped& operator[](Key&& key);
|
| +
|
| + // CHECK()s if the element does not exist.
|
| + value_type& at(const Key& key);
|
| + const value_type& at(const Key& key) const;
|
| +
|
| + // --------------------------------------------------------------------------
|
| + // General operations.
|
| + //
|
| + // Assume that swap invalidates iterators and references.
|
| +
|
| + void swap(flat_map& other);
|
| +
|
| + friend void swap(flat_map& lhs, flat_map& rhs) { lhs.swap(rhs); }
|
| +};
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Lifetime.
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +flat_map<Key, Mapped, Compare>::flat_map() = default;
|
| +
|
| +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,
|
| + const Compare& comp)
|
| + : tree(first, last, comp) {}
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +flat_map<Key, Mapped, Compare>::flat_map(const flat_map&) = default;
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +flat_map<Key, Mapped, Compare>::flat_map(flat_map&&) = default;
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +flat_map<Key, Mapped, Compare>::flat_map(
|
| + std::initializer_list<value_type> ilist,
|
| + const Compare& comp)
|
| + : flat_map(std::begin(ilist), std::end(ilist), comp) {}
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +flat_map<Key, Mapped, Compare>::~flat_map() = default;
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Assignments.
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +auto flat_map<Key, Mapped, Compare>::operator=(const flat_map&)
|
| + -> flat_map& = default;
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +auto flat_map<Key, Mapped, Compare>::operator=(flat_map &&)
|
| + -> flat_map& = default;
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +auto flat_map<Key, Mapped, Compare>::operator=(
|
| + std::initializer_list<value_type> ilist) -> flat_map& {
|
| + tree::operator=(ilist);
|
| + return *this;
|
| +}
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Insert operations.
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +auto flat_map<Key, Mapped, Compare>::operator[](const Key& key) -> Mapped& {
|
| + typename tree::iterator found = tree::lower_bound(key);
|
| + if (found == tree::end() || tree::key_comp()(key, found->first))
|
| + found = unsafe_insert_new_at(found, value_type(key, Mapped()));
|
| + return found->second;
|
| +}
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +auto flat_map<Key, Mapped, Compare>::operator[](Key&& key)
|
| + -> Mapped& {
|
| + const Key& key_ref = key;
|
| + typename tree::iterator found = tree::lower_bound(key_ref);
|
| + if (found == tree::end() || tree::key_comp()(key, found->first)) {
|
| + found = tree::unsafe_insert_new_at(found,
|
| + value_type(std::move(key), Mapped()));
|
| + }
|
| + return found->second;
|
| +}
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +auto flat_map<Key, Mapped, Compare>::at(const Key& key) -> value_type& {
|
| + typename tree::const_iterator found = tree::lower_bound(key);
|
| + CHECK(found == tree::end() || tree::key_comp()(key, found->first));
|
| + return found->second;
|
| +}
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +auto flat_map<Key, Mapped, Compare>::at(const Key& key) const
|
| + -> const value_type& {
|
| + typename tree::iterator found = tree::lower_bound(key);
|
| + CHECK(found == tree::end() || tree::key_comp()(key, found->first));
|
| + return found->second;
|
| +}
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// General operations.
|
| +
|
| +template <class Key, class Mapped, class Compare>
|
| +void flat_map<Key, Mapped, Compare>::swap(flat_map& other) {
|
| + tree::swap(other);
|
| +}
|
| +
|
| +} // namespace base
|
| +
|
| +#endif // BASE_CONTAINERS_FLAT_MAP_H_
|
|
|