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

Unified Diff: base/containers/flat_map.h

Issue 2715433007: Add a flat_map container (Closed)
Patch Set: Fixes Created 3 years, 10 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..d034e0a9abddfa8bf9bbbc7f5dbcb33b39211fc7
--- /dev/null
+++ b/base/containers/flat_map.h
@@ -0,0 +1,212 @@
+// 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);
+
+ template <class InputIterator>
+ flat_map(InputIterator first,
+ InputIterator last,
+ const Compare& comp = Compare());
+
+ flat_map(const flat_map&);
+ flat_map(flat_map&&) noexcept;
+
+ flat_map(std::initializer_list<value_type> ilist,
+ const Compare& comp = Compare());
dyaroshev 2017/02/28 18:40:53 It would be nice to inherit all of these construct
dyaroshev 2017/03/06 17:41:55 I've checked - it doesn't work - compiler doesn't
brettw 2017/03/20 22:42:19 Thanks for checking!
+
+ ~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) 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() = 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));
dyaroshev 2017/02/28 18:40:53 This should probably just be tree::find.
+ 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_
« 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