1*635a8641SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_CONTAINERS_FLAT_MAP_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_CONTAINERS_FLAT_MAP_H_
7*635a8641SAndroid Build Coastguard Worker
8*635a8641SAndroid Build Coastguard Worker #include <functional>
9*635a8641SAndroid Build Coastguard Worker #include <tuple>
10*635a8641SAndroid Build Coastguard Worker #include <utility>
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker #include "base/containers/flat_tree.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/template_util.h"
15*635a8641SAndroid Build Coastguard Worker
16*635a8641SAndroid Build Coastguard Worker namespace base {
17*635a8641SAndroid Build Coastguard Worker
18*635a8641SAndroid Build Coastguard Worker namespace internal {
19*635a8641SAndroid Build Coastguard Worker
20*635a8641SAndroid Build Coastguard Worker // An implementation of the flat_tree GetKeyFromValue template parameter that
21*635a8641SAndroid Build Coastguard Worker // extracts the key as the first element of a pair.
22*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped>
23*635a8641SAndroid Build Coastguard Worker struct GetKeyFromValuePairFirst {
operatorGetKeyFromValuePairFirst24*635a8641SAndroid Build Coastguard Worker const Key& operator()(const std::pair<Key, Mapped>& p) const {
25*635a8641SAndroid Build Coastguard Worker return p.first;
26*635a8641SAndroid Build Coastguard Worker }
27*635a8641SAndroid Build Coastguard Worker };
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Worker } // namespace internal
30*635a8641SAndroid Build Coastguard Worker
31*635a8641SAndroid Build Coastguard Worker // flat_map is a container with a std::map-like interface that stores its
32*635a8641SAndroid Build Coastguard Worker // contents in a sorted vector.
33*635a8641SAndroid Build Coastguard Worker //
34*635a8641SAndroid Build Coastguard Worker // Please see //base/containers/README.md for an overview of which container
35*635a8641SAndroid Build Coastguard Worker // to select.
36*635a8641SAndroid Build Coastguard Worker //
37*635a8641SAndroid Build Coastguard Worker // PROS
38*635a8641SAndroid Build Coastguard Worker //
39*635a8641SAndroid Build Coastguard Worker // - Good memory locality.
40*635a8641SAndroid Build Coastguard Worker // - Low overhead, especially for smaller maps.
41*635a8641SAndroid Build Coastguard Worker // - Performance is good for more workloads than you might expect (see
42*635a8641SAndroid Build Coastguard Worker // overview link above).
43*635a8641SAndroid Build Coastguard Worker // - Supports C++14 map interface.
44*635a8641SAndroid Build Coastguard Worker //
45*635a8641SAndroid Build Coastguard Worker // CONS
46*635a8641SAndroid Build Coastguard Worker //
47*635a8641SAndroid Build Coastguard Worker // - Inserts and removals are O(n).
48*635a8641SAndroid Build Coastguard Worker //
49*635a8641SAndroid Build Coastguard Worker // IMPORTANT NOTES
50*635a8641SAndroid Build Coastguard Worker //
51*635a8641SAndroid Build Coastguard Worker // - Iterators are invalidated across mutations.
52*635a8641SAndroid Build Coastguard Worker // - If possible, construct a flat_map in one operation by inserting into
53*635a8641SAndroid Build Coastguard Worker // a std::vector and moving that vector into the flat_map constructor.
54*635a8641SAndroid Build Coastguard Worker //
55*635a8641SAndroid Build Coastguard Worker // QUICK REFERENCE
56*635a8641SAndroid Build Coastguard Worker //
57*635a8641SAndroid Build Coastguard Worker // Most of the core functionality is inherited from flat_tree. Please see
58*635a8641SAndroid Build Coastguard Worker // flat_tree.h for more details for most of these functions. As a quick
59*635a8641SAndroid Build Coastguard Worker // reference, the functions available are:
60*635a8641SAndroid Build Coastguard Worker //
61*635a8641SAndroid Build Coastguard Worker // Constructors (inputs need not be sorted):
62*635a8641SAndroid Build Coastguard Worker // flat_map(InputIterator first, InputIterator last,
63*635a8641SAndroid Build Coastguard Worker // FlatContainerDupes = KEEP_FIRST_OF_DUPES,
64*635a8641SAndroid Build Coastguard Worker // const Compare& compare = Compare());
65*635a8641SAndroid Build Coastguard Worker // flat_map(const flat_map&);
66*635a8641SAndroid Build Coastguard Worker // flat_map(flat_map&&);
67*635a8641SAndroid Build Coastguard Worker // flat_map(std::vector<value_type>,
68*635a8641SAndroid Build Coastguard Worker // FlatContainerDupes = KEEP_FIRST_OF_DUPES,
69*635a8641SAndroid Build Coastguard Worker // const Compare& compare = Compare()); // Re-use storage.
70*635a8641SAndroid Build Coastguard Worker // flat_map(std::initializer_list<value_type> ilist,
71*635a8641SAndroid Build Coastguard Worker // FlatContainerDupes = KEEP_FIRST_OF_DUPES,
72*635a8641SAndroid Build Coastguard Worker // const Compare& comp = Compare());
73*635a8641SAndroid Build Coastguard Worker //
74*635a8641SAndroid Build Coastguard Worker // Assignment functions:
75*635a8641SAndroid Build Coastguard Worker // flat_map& operator=(const flat_map&);
76*635a8641SAndroid Build Coastguard Worker // flat_map& operator=(flat_map&&);
77*635a8641SAndroid Build Coastguard Worker // flat_map& operator=(initializer_list<value_type>);
78*635a8641SAndroid Build Coastguard Worker //
79*635a8641SAndroid Build Coastguard Worker // Memory management functions:
80*635a8641SAndroid Build Coastguard Worker // void reserve(size_t);
81*635a8641SAndroid Build Coastguard Worker // size_t capacity() const;
82*635a8641SAndroid Build Coastguard Worker // void shrink_to_fit();
83*635a8641SAndroid Build Coastguard Worker //
84*635a8641SAndroid Build Coastguard Worker // Size management functions:
85*635a8641SAndroid Build Coastguard Worker // void clear();
86*635a8641SAndroid Build Coastguard Worker // size_t size() const;
87*635a8641SAndroid Build Coastguard Worker // size_t max_size() const;
88*635a8641SAndroid Build Coastguard Worker // bool empty() const;
89*635a8641SAndroid Build Coastguard Worker //
90*635a8641SAndroid Build Coastguard Worker // Iterator functions:
91*635a8641SAndroid Build Coastguard Worker // iterator begin();
92*635a8641SAndroid Build Coastguard Worker // const_iterator begin() const;
93*635a8641SAndroid Build Coastguard Worker // const_iterator cbegin() const;
94*635a8641SAndroid Build Coastguard Worker // iterator end();
95*635a8641SAndroid Build Coastguard Worker // const_iterator end() const;
96*635a8641SAndroid Build Coastguard Worker // const_iterator cend() const;
97*635a8641SAndroid Build Coastguard Worker // reverse_iterator rbegin();
98*635a8641SAndroid Build Coastguard Worker // const reverse_iterator rbegin() const;
99*635a8641SAndroid Build Coastguard Worker // const_reverse_iterator crbegin() const;
100*635a8641SAndroid Build Coastguard Worker // reverse_iterator rend();
101*635a8641SAndroid Build Coastguard Worker // const_reverse_iterator rend() const;
102*635a8641SAndroid Build Coastguard Worker // const_reverse_iterator crend() const;
103*635a8641SAndroid Build Coastguard Worker //
104*635a8641SAndroid Build Coastguard Worker // Insert and accessor functions:
105*635a8641SAndroid Build Coastguard Worker // mapped_type& operator[](const key_type&);
106*635a8641SAndroid Build Coastguard Worker // mapped_type& operator[](key_type&&);
107*635a8641SAndroid Build Coastguard Worker // pair<iterator, bool> insert(const value_type&);
108*635a8641SAndroid Build Coastguard Worker // pair<iterator, bool> insert(value_type&&);
109*635a8641SAndroid Build Coastguard Worker // iterator insert(const_iterator hint, const value_type&);
110*635a8641SAndroid Build Coastguard Worker // iterator insert(const_iterator hint, value_type&&);
111*635a8641SAndroid Build Coastguard Worker // void insert(InputIterator first, InputIterator last,
112*635a8641SAndroid Build Coastguard Worker // FlatContainerDupes = KEEP_FIRST_OF_DUPES);
113*635a8641SAndroid Build Coastguard Worker // pair<iterator, bool> insert_or_assign(K&&, M&&);
114*635a8641SAndroid Build Coastguard Worker // iterator insert_or_assign(const_iterator hint, K&&, M&&);
115*635a8641SAndroid Build Coastguard Worker // pair<iterator, bool> emplace(Args&&...);
116*635a8641SAndroid Build Coastguard Worker // iterator emplace_hint(const_iterator, Args&&...);
117*635a8641SAndroid Build Coastguard Worker // pair<iterator, bool> try_emplace(K&&, Args&&...);
118*635a8641SAndroid Build Coastguard Worker // iterator try_emplace(const_iterator hint, K&&, Args&&...);
119*635a8641SAndroid Build Coastguard Worker //
120*635a8641SAndroid Build Coastguard Worker // Erase functions:
121*635a8641SAndroid Build Coastguard Worker // iterator erase(iterator);
122*635a8641SAndroid Build Coastguard Worker // iterator erase(const_iterator);
123*635a8641SAndroid Build Coastguard Worker // iterator erase(const_iterator first, const_iterator& last);
124*635a8641SAndroid Build Coastguard Worker // template <class K> size_t erase(const K& key);
125*635a8641SAndroid Build Coastguard Worker //
126*635a8641SAndroid Build Coastguard Worker // Comparators (see std::map documentation).
127*635a8641SAndroid Build Coastguard Worker // key_compare key_comp() const;
128*635a8641SAndroid Build Coastguard Worker // value_compare value_comp() const;
129*635a8641SAndroid Build Coastguard Worker //
130*635a8641SAndroid Build Coastguard Worker // Search functions:
131*635a8641SAndroid Build Coastguard Worker // template <typename K> size_t count(const K&) const;
132*635a8641SAndroid Build Coastguard Worker // template <typename K> iterator find(const K&);
133*635a8641SAndroid Build Coastguard Worker // template <typename K> const_iterator find(const K&) const;
134*635a8641SAndroid Build Coastguard Worker // template <typename K> pair<iterator, iterator> equal_range(const K&);
135*635a8641SAndroid Build Coastguard Worker // template <typename K> iterator lower_bound(const K&);
136*635a8641SAndroid Build Coastguard Worker // template <typename K> const_iterator lower_bound(const K&) const;
137*635a8641SAndroid Build Coastguard Worker // template <typename K> iterator upper_bound(const K&);
138*635a8641SAndroid Build Coastguard Worker // template <typename K> const_iterator upper_bound(const K&) const;
139*635a8641SAndroid Build Coastguard Worker //
140*635a8641SAndroid Build Coastguard Worker // General functions:
141*635a8641SAndroid Build Coastguard Worker // void swap(flat_map&&);
142*635a8641SAndroid Build Coastguard Worker //
143*635a8641SAndroid Build Coastguard Worker // Non-member operators:
144*635a8641SAndroid Build Coastguard Worker // bool operator==(const flat_map&, const flat_map);
145*635a8641SAndroid Build Coastguard Worker // bool operator!=(const flat_map&, const flat_map);
146*635a8641SAndroid Build Coastguard Worker // bool operator<(const flat_map&, const flat_map);
147*635a8641SAndroid Build Coastguard Worker // bool operator>(const flat_map&, const flat_map);
148*635a8641SAndroid Build Coastguard Worker // bool operator>=(const flat_map&, const flat_map);
149*635a8641SAndroid Build Coastguard Worker // bool operator<=(const flat_map&, const flat_map);
150*635a8641SAndroid Build Coastguard Worker //
151*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare = std::less<>>
152*635a8641SAndroid Build Coastguard Worker class flat_map : public ::base::internal::flat_tree<
153*635a8641SAndroid Build Coastguard Worker Key,
154*635a8641SAndroid Build Coastguard Worker std::pair<Key, Mapped>,
155*635a8641SAndroid Build Coastguard Worker ::base::internal::GetKeyFromValuePairFirst<Key, Mapped>,
156*635a8641SAndroid Build Coastguard Worker Compare> {
157*635a8641SAndroid Build Coastguard Worker private:
158*635a8641SAndroid Build Coastguard Worker using tree = typename ::base::internal::flat_tree<
159*635a8641SAndroid Build Coastguard Worker Key,
160*635a8641SAndroid Build Coastguard Worker std::pair<Key, Mapped>,
161*635a8641SAndroid Build Coastguard Worker ::base::internal::GetKeyFromValuePairFirst<Key, Mapped>,
162*635a8641SAndroid Build Coastguard Worker Compare>;
163*635a8641SAndroid Build Coastguard Worker
164*635a8641SAndroid Build Coastguard Worker public:
165*635a8641SAndroid Build Coastguard Worker using key_type = typename tree::key_type;
166*635a8641SAndroid Build Coastguard Worker using mapped_type = Mapped;
167*635a8641SAndroid Build Coastguard Worker using value_type = typename tree::value_type;
168*635a8641SAndroid Build Coastguard Worker using iterator = typename tree::iterator;
169*635a8641SAndroid Build Coastguard Worker using const_iterator = typename tree::const_iterator;
170*635a8641SAndroid Build Coastguard Worker
171*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
172*635a8641SAndroid Build Coastguard Worker // Lifetime and assignments.
173*635a8641SAndroid Build Coastguard Worker //
174*635a8641SAndroid Build Coastguard Worker // Note: we could do away with these constructors, destructor and assignment
175*635a8641SAndroid Build Coastguard Worker // operator overloads by inheriting |tree|'s, but this breaks the GCC build
176*635a8641SAndroid Build Coastguard Worker // due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84782 (see
177*635a8641SAndroid Build Coastguard Worker // https://crbug.com/837221).
178*635a8641SAndroid Build Coastguard Worker
179*635a8641SAndroid Build Coastguard Worker flat_map() = default;
180*635a8641SAndroid Build Coastguard Worker explicit flat_map(const Compare& comp);
181*635a8641SAndroid Build Coastguard Worker
182*635a8641SAndroid Build Coastguard Worker template <class InputIterator>
183*635a8641SAndroid Build Coastguard Worker flat_map(InputIterator first,
184*635a8641SAndroid Build Coastguard Worker InputIterator last,
185*635a8641SAndroid Build Coastguard Worker FlatContainerDupes dupe_handling = KEEP_FIRST_OF_DUPES,
186*635a8641SAndroid Build Coastguard Worker const Compare& comp = Compare());
187*635a8641SAndroid Build Coastguard Worker
188*635a8641SAndroid Build Coastguard Worker flat_map(const flat_map&) = default;
189*635a8641SAndroid Build Coastguard Worker flat_map(flat_map&&) noexcept = default;
190*635a8641SAndroid Build Coastguard Worker
191*635a8641SAndroid Build Coastguard Worker flat_map(std::vector<value_type> items,
192*635a8641SAndroid Build Coastguard Worker FlatContainerDupes dupe_handling = KEEP_FIRST_OF_DUPES,
193*635a8641SAndroid Build Coastguard Worker const Compare& comp = Compare());
194*635a8641SAndroid Build Coastguard Worker
195*635a8641SAndroid Build Coastguard Worker flat_map(std::initializer_list<value_type> ilist,
196*635a8641SAndroid Build Coastguard Worker FlatContainerDupes dupe_handling = KEEP_FIRST_OF_DUPES,
197*635a8641SAndroid Build Coastguard Worker const Compare& comp = Compare());
198*635a8641SAndroid Build Coastguard Worker
199*635a8641SAndroid Build Coastguard Worker ~flat_map() = default;
200*635a8641SAndroid Build Coastguard Worker
201*635a8641SAndroid Build Coastguard Worker flat_map& operator=(const flat_map&) = default;
202*635a8641SAndroid Build Coastguard Worker flat_map& operator=(flat_map&&) = default;
203*635a8641SAndroid Build Coastguard Worker // Takes the first if there are duplicates in the initializer list.
204*635a8641SAndroid Build Coastguard Worker flat_map& operator=(std::initializer_list<value_type> ilist);
205*635a8641SAndroid Build Coastguard Worker
206*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
207*635a8641SAndroid Build Coastguard Worker // Map-specific insert operations.
208*635a8641SAndroid Build Coastguard Worker //
209*635a8641SAndroid Build Coastguard Worker // Normal insert() functions are inherited from flat_tree.
210*635a8641SAndroid Build Coastguard Worker //
211*635a8641SAndroid Build Coastguard Worker // Assume that every operation invalidates iterators and references.
212*635a8641SAndroid Build Coastguard Worker // Insertion of one element can take O(size).
213*635a8641SAndroid Build Coastguard Worker
214*635a8641SAndroid Build Coastguard Worker mapped_type& operator[](const key_type& key);
215*635a8641SAndroid Build Coastguard Worker mapped_type& operator[](key_type&& key);
216*635a8641SAndroid Build Coastguard Worker
217*635a8641SAndroid Build Coastguard Worker template <class K, class M>
218*635a8641SAndroid Build Coastguard Worker std::pair<iterator, bool> insert_or_assign(K&& key, M&& obj);
219*635a8641SAndroid Build Coastguard Worker template <class K, class M>
220*635a8641SAndroid Build Coastguard Worker iterator insert_or_assign(const_iterator hint, K&& key, M&& obj);
221*635a8641SAndroid Build Coastguard Worker
222*635a8641SAndroid Build Coastguard Worker template <class K, class... Args>
223*635a8641SAndroid Build Coastguard Worker std::enable_if_t<std::is_constructible<key_type, K&&>::value,
224*635a8641SAndroid Build Coastguard Worker std::pair<iterator, bool>>
225*635a8641SAndroid Build Coastguard Worker try_emplace(K&& key, Args&&... args);
226*635a8641SAndroid Build Coastguard Worker
227*635a8641SAndroid Build Coastguard Worker template <class K, class... Args>
228*635a8641SAndroid Build Coastguard Worker std::enable_if_t<std::is_constructible<key_type, K&&>::value, iterator>
229*635a8641SAndroid Build Coastguard Worker try_emplace(const_iterator hint, K&& key, Args&&... args);
230*635a8641SAndroid Build Coastguard Worker
231*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
232*635a8641SAndroid Build Coastguard Worker // General operations.
233*635a8641SAndroid Build Coastguard Worker //
234*635a8641SAndroid Build Coastguard Worker // Assume that swap invalidates iterators and references.
235*635a8641SAndroid Build Coastguard Worker
236*635a8641SAndroid Build Coastguard Worker void swap(flat_map& other) noexcept;
237*635a8641SAndroid Build Coastguard Worker
swap(flat_map & lhs,flat_map & rhs)238*635a8641SAndroid Build Coastguard Worker friend void swap(flat_map& lhs, flat_map& rhs) noexcept { lhs.swap(rhs); }
239*635a8641SAndroid Build Coastguard Worker };
240*635a8641SAndroid Build Coastguard Worker
241*635a8641SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
242*635a8641SAndroid Build Coastguard Worker // Lifetime.
243*635a8641SAndroid Build Coastguard Worker
244*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
flat_map(const Compare & comp)245*635a8641SAndroid Build Coastguard Worker flat_map<Key, Mapped, Compare>::flat_map(const Compare& comp) : tree(comp) {}
246*635a8641SAndroid Build Coastguard Worker
247*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
248*635a8641SAndroid Build Coastguard Worker template <class InputIterator>
flat_map(InputIterator first,InputIterator last,FlatContainerDupes dupe_handling,const Compare & comp)249*635a8641SAndroid Build Coastguard Worker flat_map<Key, Mapped, Compare>::flat_map(InputIterator first,
250*635a8641SAndroid Build Coastguard Worker InputIterator last,
251*635a8641SAndroid Build Coastguard Worker FlatContainerDupes dupe_handling,
252*635a8641SAndroid Build Coastguard Worker const Compare& comp)
253*635a8641SAndroid Build Coastguard Worker : tree(first, last, dupe_handling, comp) {}
254*635a8641SAndroid Build Coastguard Worker
255*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
flat_map(std::vector<value_type> items,FlatContainerDupes dupe_handling,const Compare & comp)256*635a8641SAndroid Build Coastguard Worker flat_map<Key, Mapped, Compare>::flat_map(std::vector<value_type> items,
257*635a8641SAndroid Build Coastguard Worker FlatContainerDupes dupe_handling,
258*635a8641SAndroid Build Coastguard Worker const Compare& comp)
259*635a8641SAndroid Build Coastguard Worker : tree(std::move(items), dupe_handling, comp) {}
260*635a8641SAndroid Build Coastguard Worker
261*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
flat_map(std::initializer_list<value_type> ilist,FlatContainerDupes dupe_handling,const Compare & comp)262*635a8641SAndroid Build Coastguard Worker flat_map<Key, Mapped, Compare>::flat_map(
263*635a8641SAndroid Build Coastguard Worker std::initializer_list<value_type> ilist,
264*635a8641SAndroid Build Coastguard Worker FlatContainerDupes dupe_handling,
265*635a8641SAndroid Build Coastguard Worker const Compare& comp)
266*635a8641SAndroid Build Coastguard Worker : flat_map(std::begin(ilist), std::end(ilist), dupe_handling, comp) {}
267*635a8641SAndroid Build Coastguard Worker
268*635a8641SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
269*635a8641SAndroid Build Coastguard Worker // Assignments.
270*635a8641SAndroid Build Coastguard Worker
271*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
272*635a8641SAndroid Build Coastguard Worker auto flat_map<Key, Mapped, Compare>::operator=(
273*635a8641SAndroid Build Coastguard Worker std::initializer_list<value_type> ilist) -> flat_map& {
274*635a8641SAndroid Build Coastguard Worker // When https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84782 gets fixed, we
275*635a8641SAndroid Build Coastguard Worker // need to remember to inherit tree::operator= to prevent
276*635a8641SAndroid Build Coastguard Worker // flat_map<...> x;
277*635a8641SAndroid Build Coastguard Worker // x = {...};
278*635a8641SAndroid Build Coastguard Worker // from first creating a flat_map and then move assigning it. This most
279*635a8641SAndroid Build Coastguard Worker // likely would be optimized away but still affects our debug builds.
280*635a8641SAndroid Build Coastguard Worker tree::operator=(ilist);
281*635a8641SAndroid Build Coastguard Worker return *this;
282*635a8641SAndroid Build Coastguard Worker }
283*635a8641SAndroid Build Coastguard Worker
284*635a8641SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
285*635a8641SAndroid Build Coastguard Worker // Insert operations.
286*635a8641SAndroid Build Coastguard Worker
287*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
288*635a8641SAndroid Build Coastguard Worker auto flat_map<Key, Mapped, Compare>::operator[](const key_type& key)
289*635a8641SAndroid Build Coastguard Worker -> mapped_type& {
290*635a8641SAndroid Build Coastguard Worker iterator found = tree::lower_bound(key);
291*635a8641SAndroid Build Coastguard Worker if (found == tree::end() || tree::key_comp()(key, found->first))
292*635a8641SAndroid Build Coastguard Worker found = tree::unsafe_emplace(found, key, mapped_type());
293*635a8641SAndroid Build Coastguard Worker return found->second;
294*635a8641SAndroid Build Coastguard Worker }
295*635a8641SAndroid Build Coastguard Worker
296*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
297*635a8641SAndroid Build Coastguard Worker auto flat_map<Key, Mapped, Compare>::operator[](key_type&& key)
298*635a8641SAndroid Build Coastguard Worker -> mapped_type& {
299*635a8641SAndroid Build Coastguard Worker iterator found = tree::lower_bound(key);
300*635a8641SAndroid Build Coastguard Worker if (found == tree::end() || tree::key_comp()(key, found->first))
301*635a8641SAndroid Build Coastguard Worker found = tree::unsafe_emplace(found, std::move(key), mapped_type());
302*635a8641SAndroid Build Coastguard Worker return found->second;
303*635a8641SAndroid Build Coastguard Worker }
304*635a8641SAndroid Build Coastguard Worker
305*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
306*635a8641SAndroid Build Coastguard Worker template <class K, class M>
307*635a8641SAndroid Build Coastguard Worker auto flat_map<Key, Mapped, Compare>::insert_or_assign(K&& key, M&& obj)
308*635a8641SAndroid Build Coastguard Worker -> std::pair<iterator, bool> {
309*635a8641SAndroid Build Coastguard Worker auto result =
310*635a8641SAndroid Build Coastguard Worker tree::emplace_key_args(key, std::forward<K>(key), std::forward<M>(obj));
311*635a8641SAndroid Build Coastguard Worker if (!result.second)
312*635a8641SAndroid Build Coastguard Worker result.first->second = std::forward<M>(obj);
313*635a8641SAndroid Build Coastguard Worker return result;
314*635a8641SAndroid Build Coastguard Worker }
315*635a8641SAndroid Build Coastguard Worker
316*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
317*635a8641SAndroid Build Coastguard Worker template <class K, class M>
318*635a8641SAndroid Build Coastguard Worker auto flat_map<Key, Mapped, Compare>::insert_or_assign(const_iterator hint,
319*635a8641SAndroid Build Coastguard Worker K&& key,
320*635a8641SAndroid Build Coastguard Worker M&& obj) -> iterator {
321*635a8641SAndroid Build Coastguard Worker auto result = tree::emplace_hint_key_args(hint, key, std::forward<K>(key),
322*635a8641SAndroid Build Coastguard Worker std::forward<M>(obj));
323*635a8641SAndroid Build Coastguard Worker if (!result.second)
324*635a8641SAndroid Build Coastguard Worker result.first->second = std::forward<M>(obj);
325*635a8641SAndroid Build Coastguard Worker return result.first;
326*635a8641SAndroid Build Coastguard Worker }
327*635a8641SAndroid Build Coastguard Worker
328*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
329*635a8641SAndroid Build Coastguard Worker template <class K, class... Args>
330*635a8641SAndroid Build Coastguard Worker auto flat_map<Key, Mapped, Compare>::try_emplace(K&& key, Args&&... args)
331*635a8641SAndroid Build Coastguard Worker -> std::enable_if_t<std::is_constructible<key_type, K&&>::value,
332*635a8641SAndroid Build Coastguard Worker std::pair<iterator, bool>> {
333*635a8641SAndroid Build Coastguard Worker return tree::emplace_key_args(
334*635a8641SAndroid Build Coastguard Worker key, std::piecewise_construct,
335*635a8641SAndroid Build Coastguard Worker std::forward_as_tuple(std::forward<K>(key)),
336*635a8641SAndroid Build Coastguard Worker std::forward_as_tuple(std::forward<Args>(args)...));
337*635a8641SAndroid Build Coastguard Worker }
338*635a8641SAndroid Build Coastguard Worker
339*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
340*635a8641SAndroid Build Coastguard Worker template <class K, class... Args>
341*635a8641SAndroid Build Coastguard Worker auto flat_map<Key, Mapped, Compare>::try_emplace(const_iterator hint,
342*635a8641SAndroid Build Coastguard Worker K&& key,
343*635a8641SAndroid Build Coastguard Worker Args&&... args)
344*635a8641SAndroid Build Coastguard Worker -> std::enable_if_t<std::is_constructible<key_type, K&&>::value, iterator> {
345*635a8641SAndroid Build Coastguard Worker return tree::emplace_hint_key_args(
346*635a8641SAndroid Build Coastguard Worker hint, key, std::piecewise_construct,
347*635a8641SAndroid Build Coastguard Worker std::forward_as_tuple(std::forward<K>(key)),
348*635a8641SAndroid Build Coastguard Worker std::forward_as_tuple(std::forward<Args>(args)...))
349*635a8641SAndroid Build Coastguard Worker .first;
350*635a8641SAndroid Build Coastguard Worker }
351*635a8641SAndroid Build Coastguard Worker
352*635a8641SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
353*635a8641SAndroid Build Coastguard Worker // General operations.
354*635a8641SAndroid Build Coastguard Worker
355*635a8641SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
swap(flat_map & other)356*635a8641SAndroid Build Coastguard Worker void flat_map<Key, Mapped, Compare>::swap(flat_map& other) noexcept {
357*635a8641SAndroid Build Coastguard Worker tree::swap(other);
358*635a8641SAndroid Build Coastguard Worker }
359*635a8641SAndroid Build Coastguard Worker
360*635a8641SAndroid Build Coastguard Worker } // namespace base
361*635a8641SAndroid Build Coastguard Worker
362*635a8641SAndroid Build Coastguard Worker #endif // BASE_CONTAINERS_FLAT_MAP_H_
363