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

Unified Diff: base/containers/flat_map.h

Issue 2715433007: Add a flat_map container (Closed)
Patch Set: Fix EraseIf 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
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..b9d8de0547d5a9e5dbb0ce195cf4b8a475da9f26
--- /dev/null
+++ b/base/containers/flat_map.h
@@ -0,0 +1,211 @@
+// 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.
dyaroshev 2017/03/21 16:03:57 Nit: maybe |first|? I'm ok with either, it's just
+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>
dyaroshev 2017/03/21 16:03:57 Nit: closing brace.
+//
+// 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<
dyaroshev 2017/03/21 16:03:57 Nit: dropping |::base| should work. If this is a d
brettw 2017/03/21 18:32:51 Yes, I prefer not to reference relative namespaces
+ 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_emplace(found, 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_emplace(found, 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/03/21 16:03:57 I'm pretty sure, that it should found != tree::en
brettw 2017/03/21 18:32:51 Find should be good, I did that. I think I was cop
+ 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_

Powered by Google App Engine
This is Rietveld 408576698