Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2187)

Unified Diff: base/containers/flat_map.h

Issue 2715433007: Add a flat_map container (Closed)
Patch Set: Comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/containers/container_test_utils.h ('k') | base/containers/flat_map_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..8ae5a50e357fcc9615dab6171037b1aedef0a969
--- /dev/null
+++ b/base/containers/flat_map.h
@@ -0,0 +1,266 @@
+// 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.
+//
+// DOCUMENTATION
+//
+// 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:
+//
+// Assignment functions:
+// flat_map& operator=(const flat_map&);
+// flat_map& operator=(flat_map&&);
+// flat_map& operator=(initializer_list<pair<Key, Mapped>>);
+//
+// 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& operator[](const Key&);
+// Mapped& operator[](Key&&);
+// pair<iterator, bool> insert(const pair<Key, Mapped>&);
+// pair<iterator, bool> insert(pair<Key, Mapped>&&);
+// pair<iterator, bool> emplace(Args&&...);
+// iterator emplace_hint(const_iterator, Args&&...);
+//
+// Erase functions:
+// iterator erase(const_iterator);
+// iterator erase(const_iterator first, const_iterator& last);
+// size_t erase(const Key& key)
+//
+// Comparators (see std::map documentation).
+// key_compare key_comp() const;
+// value_compare value_comp() const;
+//
+// Search functions:
+// size_t count(const Key&) const;
+// iterator find(const Key&);
+// const_iterator find(const Key&) const;
+// pair<iterator, iterator> equal_range(Key&)
+// iterator lower_bound(const Key&);
+// const_iterator lower_bound(const Key&) const;
+// iterator upper_bound(const Key&);
+// const_iterator upper_bound(const Key&) 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<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_type& operator[](const Key& key);
+ mapped_type& operator[](Key&& key);
+
+ // --------------------------------------------------------------------------
+ // 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_emplace(found, key, Mapped());
DaleCurtis 2017/03/29 01:16:42 Did you mean tree::unsafe_emplace() here? It doesn
dyaroshev 2017/03/29 11:13:21 And we probably don't have a test for it. I think
+ 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_emplace(found, std::move(key), Mapped());
+ 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_
« no previous file with comments | « base/containers/container_test_utils.h ('k') | base/containers/flat_map_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698