1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_CONTAINERS_FLAT_TREE_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_CONTAINERS_FLAT_TREE_H_
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Worker #include <algorithm>
9*6777b538SAndroid Build Coastguard Worker #include <array>
10*6777b538SAndroid Build Coastguard Worker #include <compare>
11*6777b538SAndroid Build Coastguard Worker #include <functional>
12*6777b538SAndroid Build Coastguard Worker #include <initializer_list>
13*6777b538SAndroid Build Coastguard Worker #include <iterator>
14*6777b538SAndroid Build Coastguard Worker #include <type_traits>
15*6777b538SAndroid Build Coastguard Worker #include <utility>
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr_exclusion.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/ranges/algorithm.h"
21*6777b538SAndroid Build Coastguard Worker
22*6777b538SAndroid Build Coastguard Worker namespace base {
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard Worker // Tag type that allows skipping the sort_and_unique step when constructing a
25*6777b538SAndroid Build Coastguard Worker // flat_tree in case the underlying container is already sorted and has no
26*6777b538SAndroid Build Coastguard Worker // duplicate elements.
27*6777b538SAndroid Build Coastguard Worker struct sorted_unique_t {
28*6777b538SAndroid Build Coastguard Worker constexpr explicit sorted_unique_t() = default;
29*6777b538SAndroid Build Coastguard Worker };
30*6777b538SAndroid Build Coastguard Worker inline constexpr sorted_unique_t sorted_unique;
31*6777b538SAndroid Build Coastguard Worker
32*6777b538SAndroid Build Coastguard Worker namespace internal {
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard Worker // Helper functions used in DCHECKs below to make sure that inputs tagged with
35*6777b538SAndroid Build Coastguard Worker // sorted_unique are indeed sorted and unique.
36*6777b538SAndroid Build Coastguard Worker template <typename Range, typename Comp>
is_sorted_and_unique(const Range & range,Comp comp)37*6777b538SAndroid Build Coastguard Worker constexpr bool is_sorted_and_unique(const Range& range, Comp comp) {
38*6777b538SAndroid Build Coastguard Worker // Being unique implies that there are no adjacent elements that
39*6777b538SAndroid Build Coastguard Worker // compare equal. So this checks that each element is strictly less
40*6777b538SAndroid Build Coastguard Worker // than the element after it.
41*6777b538SAndroid Build Coastguard Worker return ranges::adjacent_find(range, std::not_fn(comp)) == ranges::end(range);
42*6777b538SAndroid Build Coastguard Worker }
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker // Helper inspired by C++20's std::to_array to convert a C-style array to a
45*6777b538SAndroid Build Coastguard Worker // std::array. As opposed to the C++20 version this implementation does not
46*6777b538SAndroid Build Coastguard Worker // provide an overload for rvalues and does not strip cv qualifers from the
47*6777b538SAndroid Build Coastguard Worker // returned std::array::value_type. The returned value_type needs to be
48*6777b538SAndroid Build Coastguard Worker // specified explicitly, allowing the construction of std::arrays with const
49*6777b538SAndroid Build Coastguard Worker // elements.
50*6777b538SAndroid Build Coastguard Worker //
51*6777b538SAndroid Build Coastguard Worker // Reference: https://en.cppreference.com/w/cpp/container/array/to_array
52*6777b538SAndroid Build Coastguard Worker template <typename U, typename T, size_t N, size_t... I>
ToArrayImpl(const T (& data)[N],std::index_sequence<I...>)53*6777b538SAndroid Build Coastguard Worker constexpr std::array<U, N> ToArrayImpl(const T (&data)[N],
54*6777b538SAndroid Build Coastguard Worker std::index_sequence<I...>) {
55*6777b538SAndroid Build Coastguard Worker return {{data[I]...}};
56*6777b538SAndroid Build Coastguard Worker }
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker template <typename U, typename T, size_t N>
ToArray(const T (& data)[N])59*6777b538SAndroid Build Coastguard Worker constexpr std::array<U, N> ToArray(const T (&data)[N]) {
60*6777b538SAndroid Build Coastguard Worker return ToArrayImpl<U>(data, std::make_index_sequence<N>());
61*6777b538SAndroid Build Coastguard Worker }
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker // Helper that calls `container.reserve(std::size(source))`.
64*6777b538SAndroid Build Coastguard Worker template <typename T, typename U>
ReserveIfSupported(T & container,const U & source)65*6777b538SAndroid Build Coastguard Worker void ReserveIfSupported(T& container, const U& source) {
66*6777b538SAndroid Build Coastguard Worker if constexpr (requires { container.reserve(std::size(source)); }) {
67*6777b538SAndroid Build Coastguard Worker container.reserve(std::size(source));
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker // Implementation -------------------------------------------------------------
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker // Implementation for the sorted associative flat_set and flat_map using a
74*6777b538SAndroid Build Coastguard Worker // sorted vector as the backing store. Do not use directly.
75*6777b538SAndroid Build Coastguard Worker //
76*6777b538SAndroid Build Coastguard Worker // The use of "value" in this is like std::map uses, meaning it's the thing
77*6777b538SAndroid Build Coastguard Worker // contained (in the case of map it's a <Key, Mapped> pair). The Key is how
78*6777b538SAndroid Build Coastguard Worker // things are looked up. In the case of a set, Key == Value. In the case of
79*6777b538SAndroid Build Coastguard Worker // a map, the Key is a component of a Value.
80*6777b538SAndroid Build Coastguard Worker //
81*6777b538SAndroid Build Coastguard Worker // The helper class GetKeyFromValue provides the means to extract a key from a
82*6777b538SAndroid Build Coastguard Worker // value for comparison purposes. It should implement:
83*6777b538SAndroid Build Coastguard Worker // const Key& operator()(const Value&).
84*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
85*6777b538SAndroid Build Coastguard Worker class flat_tree {
86*6777b538SAndroid Build Coastguard Worker public:
87*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
88*6777b538SAndroid Build Coastguard Worker // Types.
89*6777b538SAndroid Build Coastguard Worker //
90*6777b538SAndroid Build Coastguard Worker using key_type = Key;
91*6777b538SAndroid Build Coastguard Worker using key_compare = KeyCompare;
92*6777b538SAndroid Build Coastguard Worker using value_type = typename Container::value_type;
93*6777b538SAndroid Build Coastguard Worker
94*6777b538SAndroid Build Coastguard Worker // Wraps the templated key comparison to compare values.
95*6777b538SAndroid Build Coastguard Worker struct value_compare {
operatorvalue_compare96*6777b538SAndroid Build Coastguard Worker constexpr bool operator()(const value_type& left,
97*6777b538SAndroid Build Coastguard Worker const value_type& right) const {
98*6777b538SAndroid Build Coastguard Worker GetKeyFromValue extractor;
99*6777b538SAndroid Build Coastguard Worker return comp(extractor(left), extractor(right));
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker NO_UNIQUE_ADDRESS key_compare comp;
103*6777b538SAndroid Build Coastguard Worker };
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker using pointer = typename Container::pointer;
106*6777b538SAndroid Build Coastguard Worker using const_pointer = typename Container::const_pointer;
107*6777b538SAndroid Build Coastguard Worker using reference = typename Container::reference;
108*6777b538SAndroid Build Coastguard Worker using const_reference = typename Container::const_reference;
109*6777b538SAndroid Build Coastguard Worker using size_type = typename Container::size_type;
110*6777b538SAndroid Build Coastguard Worker using difference_type = typename Container::difference_type;
111*6777b538SAndroid Build Coastguard Worker using iterator = typename Container::iterator;
112*6777b538SAndroid Build Coastguard Worker using const_iterator = typename Container::const_iterator;
113*6777b538SAndroid Build Coastguard Worker using reverse_iterator = typename Container::reverse_iterator;
114*6777b538SAndroid Build Coastguard Worker using const_reverse_iterator = typename Container::const_reverse_iterator;
115*6777b538SAndroid Build Coastguard Worker using container_type = Container;
116*6777b538SAndroid Build Coastguard Worker
117*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
118*6777b538SAndroid Build Coastguard Worker // Lifetime.
119*6777b538SAndroid Build Coastguard Worker //
120*6777b538SAndroid Build Coastguard Worker // Constructors that take range guarantee O(N * log^2(N)) + O(N) complexity
121*6777b538SAndroid Build Coastguard Worker // and take O(N * log(N)) + O(N) if extra memory is available (N is a range
122*6777b538SAndroid Build Coastguard Worker // length).
123*6777b538SAndroid Build Coastguard Worker //
124*6777b538SAndroid Build Coastguard Worker // Assume that move constructors invalidate iterators and references.
125*6777b538SAndroid Build Coastguard Worker //
126*6777b538SAndroid Build Coastguard Worker // The constructors that take ranges, lists, and vectors do not require that
127*6777b538SAndroid Build Coastguard Worker // the input be sorted.
128*6777b538SAndroid Build Coastguard Worker //
129*6777b538SAndroid Build Coastguard Worker // When passing the base::sorted_unique tag as the first argument no sort and
130*6777b538SAndroid Build Coastguard Worker // unique step takes places. This is useful if the underlying container
131*6777b538SAndroid Build Coastguard Worker // already has the required properties.
132*6777b538SAndroid Build Coastguard Worker
133*6777b538SAndroid Build Coastguard Worker flat_tree() = default;
134*6777b538SAndroid Build Coastguard Worker flat_tree(const flat_tree&) = default;
135*6777b538SAndroid Build Coastguard Worker flat_tree(flat_tree&&) = default;
136*6777b538SAndroid Build Coastguard Worker
137*6777b538SAndroid Build Coastguard Worker explicit flat_tree(const key_compare& comp);
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker template <class InputIterator>
140*6777b538SAndroid Build Coastguard Worker flat_tree(InputIterator first,
141*6777b538SAndroid Build Coastguard Worker InputIterator last,
142*6777b538SAndroid Build Coastguard Worker const key_compare& comp = key_compare());
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker flat_tree(const container_type& items,
145*6777b538SAndroid Build Coastguard Worker const key_compare& comp = key_compare());
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard Worker flat_tree(container_type&& items, const key_compare& comp = key_compare());
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker flat_tree(std::initializer_list<value_type> ilist,
150*6777b538SAndroid Build Coastguard Worker const key_compare& comp = key_compare());
151*6777b538SAndroid Build Coastguard Worker
152*6777b538SAndroid Build Coastguard Worker template <class InputIterator>
153*6777b538SAndroid Build Coastguard Worker flat_tree(sorted_unique_t,
154*6777b538SAndroid Build Coastguard Worker InputIterator first,
155*6777b538SAndroid Build Coastguard Worker InputIterator last,
156*6777b538SAndroid Build Coastguard Worker const key_compare& comp = key_compare());
157*6777b538SAndroid Build Coastguard Worker
158*6777b538SAndroid Build Coastguard Worker flat_tree(sorted_unique_t,
159*6777b538SAndroid Build Coastguard Worker const container_type& items,
160*6777b538SAndroid Build Coastguard Worker const key_compare& comp = key_compare());
161*6777b538SAndroid Build Coastguard Worker
162*6777b538SAndroid Build Coastguard Worker constexpr flat_tree(sorted_unique_t,
163*6777b538SAndroid Build Coastguard Worker container_type&& items,
164*6777b538SAndroid Build Coastguard Worker const key_compare& comp = key_compare());
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard Worker flat_tree(sorted_unique_t,
167*6777b538SAndroid Build Coastguard Worker std::initializer_list<value_type> ilist,
168*6777b538SAndroid Build Coastguard Worker const key_compare& comp = key_compare());
169*6777b538SAndroid Build Coastguard Worker
170*6777b538SAndroid Build Coastguard Worker ~flat_tree() = default;
171*6777b538SAndroid Build Coastguard Worker
172*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
173*6777b538SAndroid Build Coastguard Worker // Assignments.
174*6777b538SAndroid Build Coastguard Worker //
175*6777b538SAndroid Build Coastguard Worker // Assume that move assignment invalidates iterators and references.
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker flat_tree& operator=(const flat_tree&) = default;
178*6777b538SAndroid Build Coastguard Worker flat_tree& operator=(flat_tree&&) = default;
179*6777b538SAndroid Build Coastguard Worker // Takes the first if there are duplicates in the initializer list.
180*6777b538SAndroid Build Coastguard Worker flat_tree& operator=(std::initializer_list<value_type> ilist);
181*6777b538SAndroid Build Coastguard Worker
182*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
183*6777b538SAndroid Build Coastguard Worker // Memory management.
184*6777b538SAndroid Build Coastguard Worker //
185*6777b538SAndroid Build Coastguard Worker // Beware that shrink_to_fit() simply forwards the request to the
186*6777b538SAndroid Build Coastguard Worker // container_type and its implementation is free to optimize otherwise and
187*6777b538SAndroid Build Coastguard Worker // leave capacity() to be greater that its size.
188*6777b538SAndroid Build Coastguard Worker //
189*6777b538SAndroid Build Coastguard Worker // reserve() and shrink_to_fit() invalidate iterators and references.
190*6777b538SAndroid Build Coastguard Worker
191*6777b538SAndroid Build Coastguard Worker void reserve(size_type new_capacity);
192*6777b538SAndroid Build Coastguard Worker size_type capacity() const;
193*6777b538SAndroid Build Coastguard Worker void shrink_to_fit();
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
196*6777b538SAndroid Build Coastguard Worker // Size management.
197*6777b538SAndroid Build Coastguard Worker //
198*6777b538SAndroid Build Coastguard Worker // clear() leaves the capacity() of the flat_tree unchanged.
199*6777b538SAndroid Build Coastguard Worker
200*6777b538SAndroid Build Coastguard Worker void clear();
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard Worker constexpr size_type size() const;
203*6777b538SAndroid Build Coastguard Worker constexpr size_type max_size() const;
204*6777b538SAndroid Build Coastguard Worker constexpr bool empty() const;
205*6777b538SAndroid Build Coastguard Worker
206*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
207*6777b538SAndroid Build Coastguard Worker // Iterators.
208*6777b538SAndroid Build Coastguard Worker //
209*6777b538SAndroid Build Coastguard Worker // Iterators follow the ordering defined by the key comparator used in
210*6777b538SAndroid Build Coastguard Worker // construction of the flat_tree.
211*6777b538SAndroid Build Coastguard Worker
212*6777b538SAndroid Build Coastguard Worker iterator begin();
213*6777b538SAndroid Build Coastguard Worker constexpr const_iterator begin() const;
214*6777b538SAndroid Build Coastguard Worker const_iterator cbegin() const;
215*6777b538SAndroid Build Coastguard Worker
216*6777b538SAndroid Build Coastguard Worker iterator end();
217*6777b538SAndroid Build Coastguard Worker constexpr const_iterator end() const;
218*6777b538SAndroid Build Coastguard Worker const_iterator cend() const;
219*6777b538SAndroid Build Coastguard Worker
220*6777b538SAndroid Build Coastguard Worker reverse_iterator rbegin();
221*6777b538SAndroid Build Coastguard Worker const_reverse_iterator rbegin() const;
222*6777b538SAndroid Build Coastguard Worker const_reverse_iterator crbegin() const;
223*6777b538SAndroid Build Coastguard Worker
224*6777b538SAndroid Build Coastguard Worker reverse_iterator rend();
225*6777b538SAndroid Build Coastguard Worker const_reverse_iterator rend() const;
226*6777b538SAndroid Build Coastguard Worker const_reverse_iterator crend() const;
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
229*6777b538SAndroid Build Coastguard Worker // Insert operations.
230*6777b538SAndroid Build Coastguard Worker //
231*6777b538SAndroid Build Coastguard Worker // Assume that every operation invalidates iterators and references.
232*6777b538SAndroid Build Coastguard Worker // Insertion of one element can take O(size). Capacity of flat_tree grows in
233*6777b538SAndroid Build Coastguard Worker // an implementation-defined manner.
234*6777b538SAndroid Build Coastguard Worker //
235*6777b538SAndroid Build Coastguard Worker // NOTE: Prefer to build a new flat_tree from a std::vector (or similar)
236*6777b538SAndroid Build Coastguard Worker // instead of calling insert() repeatedly.
237*6777b538SAndroid Build Coastguard Worker
238*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> insert(const value_type& val);
239*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> insert(value_type&& val);
240*6777b538SAndroid Build Coastguard Worker
241*6777b538SAndroid Build Coastguard Worker iterator insert(const_iterator position_hint, const value_type& x);
242*6777b538SAndroid Build Coastguard Worker iterator insert(const_iterator position_hint, value_type&& x);
243*6777b538SAndroid Build Coastguard Worker
244*6777b538SAndroid Build Coastguard Worker // This method inserts the values from the range [first, last) into the
245*6777b538SAndroid Build Coastguard Worker // current tree.
246*6777b538SAndroid Build Coastguard Worker template <class InputIterator>
247*6777b538SAndroid Build Coastguard Worker void insert(InputIterator first, InputIterator last);
248*6777b538SAndroid Build Coastguard Worker
249*6777b538SAndroid Build Coastguard Worker template <class... Args>
250*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> emplace(Args&&... args);
251*6777b538SAndroid Build Coastguard Worker
252*6777b538SAndroid Build Coastguard Worker template <class... Args>
253*6777b538SAndroid Build Coastguard Worker iterator emplace_hint(const_iterator position_hint, Args&&... args);
254*6777b538SAndroid Build Coastguard Worker
255*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
256*6777b538SAndroid Build Coastguard Worker // Underlying type operations.
257*6777b538SAndroid Build Coastguard Worker //
258*6777b538SAndroid Build Coastguard Worker // Assume that either operation invalidates iterators and references.
259*6777b538SAndroid Build Coastguard Worker
260*6777b538SAndroid Build Coastguard Worker // Extracts the container_type and returns it to the caller. Ensures that
261*6777b538SAndroid Build Coastguard Worker // `this` is `empty()` afterwards.
262*6777b538SAndroid Build Coastguard Worker container_type extract() &&;
263*6777b538SAndroid Build Coastguard Worker
264*6777b538SAndroid Build Coastguard Worker // Replaces the container_type with `body`. Expects that `body` is sorted
265*6777b538SAndroid Build Coastguard Worker // and has no repeated elements with regard to value_comp().
266*6777b538SAndroid Build Coastguard Worker void replace(container_type&& body);
267*6777b538SAndroid Build Coastguard Worker
268*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
269*6777b538SAndroid Build Coastguard Worker // Erase operations.
270*6777b538SAndroid Build Coastguard Worker //
271*6777b538SAndroid Build Coastguard Worker // Assume that every operation invalidates iterators and references.
272*6777b538SAndroid Build Coastguard Worker //
273*6777b538SAndroid Build Coastguard Worker // erase(position), erase(first, last) can take O(size).
274*6777b538SAndroid Build Coastguard Worker // erase(key) may take O(size) + O(log(size)).
275*6777b538SAndroid Build Coastguard Worker //
276*6777b538SAndroid Build Coastguard Worker // Prefer base::EraseIf() or some other variation on erase(remove(), end())
277*6777b538SAndroid Build Coastguard Worker // idiom when deleting multiple non-consecutive elements.
278*6777b538SAndroid Build Coastguard Worker
279*6777b538SAndroid Build Coastguard Worker iterator erase(iterator position);
280*6777b538SAndroid Build Coastguard Worker // Artificially templatized to break ambiguity if `iterator` and
281*6777b538SAndroid Build Coastguard Worker // `const_iterator` are the same type.
282*6777b538SAndroid Build Coastguard Worker template <typename DummyT = void>
283*6777b538SAndroid Build Coastguard Worker iterator erase(const_iterator position);
284*6777b538SAndroid Build Coastguard Worker iterator erase(const_iterator first, const_iterator last);
285*6777b538SAndroid Build Coastguard Worker size_type erase(const Key& key);
286*6777b538SAndroid Build Coastguard Worker template <typename K>
287*6777b538SAndroid Build Coastguard Worker size_type erase(const K& key);
288*6777b538SAndroid Build Coastguard Worker
289*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
290*6777b538SAndroid Build Coastguard Worker // Comparators.
291*6777b538SAndroid Build Coastguard Worker
292*6777b538SAndroid Build Coastguard Worker constexpr key_compare key_comp() const;
293*6777b538SAndroid Build Coastguard Worker constexpr value_compare value_comp() const;
294*6777b538SAndroid Build Coastguard Worker
295*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
296*6777b538SAndroid Build Coastguard Worker // Search operations.
297*6777b538SAndroid Build Coastguard Worker //
298*6777b538SAndroid Build Coastguard Worker // Search operations have O(log(size)) complexity.
299*6777b538SAndroid Build Coastguard Worker
300*6777b538SAndroid Build Coastguard Worker size_type count(const Key& key) const;
301*6777b538SAndroid Build Coastguard Worker template <typename K>
302*6777b538SAndroid Build Coastguard Worker size_type count(const K& key) const;
303*6777b538SAndroid Build Coastguard Worker
304*6777b538SAndroid Build Coastguard Worker iterator find(const Key& key);
305*6777b538SAndroid Build Coastguard Worker const_iterator find(const Key& key) const;
306*6777b538SAndroid Build Coastguard Worker template <typename K>
307*6777b538SAndroid Build Coastguard Worker iterator find(const K& key);
308*6777b538SAndroid Build Coastguard Worker template <typename K>
309*6777b538SAndroid Build Coastguard Worker const_iterator find(const K& key) const;
310*6777b538SAndroid Build Coastguard Worker
311*6777b538SAndroid Build Coastguard Worker bool contains(const Key& key) const;
312*6777b538SAndroid Build Coastguard Worker template <typename K>
313*6777b538SAndroid Build Coastguard Worker bool contains(const K& key) const;
314*6777b538SAndroid Build Coastguard Worker
315*6777b538SAndroid Build Coastguard Worker std::pair<iterator, iterator> equal_range(const Key& key);
316*6777b538SAndroid Build Coastguard Worker std::pair<const_iterator, const_iterator> equal_range(const Key& key) const;
317*6777b538SAndroid Build Coastguard Worker template <typename K>
318*6777b538SAndroid Build Coastguard Worker std::pair<iterator, iterator> equal_range(const K& key);
319*6777b538SAndroid Build Coastguard Worker template <typename K>
320*6777b538SAndroid Build Coastguard Worker std::pair<const_iterator, const_iterator> equal_range(const K& key) const;
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard Worker iterator lower_bound(const Key& key);
323*6777b538SAndroid Build Coastguard Worker const_iterator lower_bound(const Key& key) const;
324*6777b538SAndroid Build Coastguard Worker template <typename K>
325*6777b538SAndroid Build Coastguard Worker iterator lower_bound(const K& key);
326*6777b538SAndroid Build Coastguard Worker template <typename K>
327*6777b538SAndroid Build Coastguard Worker const_iterator lower_bound(const K& key) const;
328*6777b538SAndroid Build Coastguard Worker
329*6777b538SAndroid Build Coastguard Worker iterator upper_bound(const Key& key);
330*6777b538SAndroid Build Coastguard Worker const_iterator upper_bound(const Key& key) const;
331*6777b538SAndroid Build Coastguard Worker template <typename K>
332*6777b538SAndroid Build Coastguard Worker iterator upper_bound(const K& key);
333*6777b538SAndroid Build Coastguard Worker template <typename K>
334*6777b538SAndroid Build Coastguard Worker const_iterator upper_bound(const K& key) const;
335*6777b538SAndroid Build Coastguard Worker
336*6777b538SAndroid Build Coastguard Worker // --------------------------------------------------------------------------
337*6777b538SAndroid Build Coastguard Worker // General operations.
338*6777b538SAndroid Build Coastguard Worker //
339*6777b538SAndroid Build Coastguard Worker // Assume that swap invalidates iterators and references.
340*6777b538SAndroid Build Coastguard Worker //
341*6777b538SAndroid Build Coastguard Worker // Implementation note: currently we use operator==() and operator<() on
342*6777b538SAndroid Build Coastguard Worker // std::vector, because they have the same contract we need, so we use them
343*6777b538SAndroid Build Coastguard Worker // directly for brevity and in case it is more optimal than calling equal()
344*6777b538SAndroid Build Coastguard Worker // and lexicograhpical_compare(). If the underlying container type is changed,
345*6777b538SAndroid Build Coastguard Worker // this code may need to be modified.
346*6777b538SAndroid Build Coastguard Worker
347*6777b538SAndroid Build Coastguard Worker void swap(flat_tree& other) noexcept;
348*6777b538SAndroid Build Coastguard Worker
349*6777b538SAndroid Build Coastguard Worker friend bool operator==(const flat_tree& lhs, const flat_tree& rhs) {
350*6777b538SAndroid Build Coastguard Worker return lhs.body_ == rhs.body_;
351*6777b538SAndroid Build Coastguard Worker }
352*6777b538SAndroid Build Coastguard Worker
353*6777b538SAndroid Build Coastguard Worker friend auto operator<=>(const flat_tree& lhs, const flat_tree& rhs) {
354*6777b538SAndroid Build Coastguard Worker return lhs.body_ <=> rhs.body_;
355*6777b538SAndroid Build Coastguard Worker }
356*6777b538SAndroid Build Coastguard Worker
swap(flat_tree & lhs,flat_tree & rhs)357*6777b538SAndroid Build Coastguard Worker friend void swap(flat_tree& lhs, flat_tree& rhs) noexcept { lhs.swap(rhs); }
358*6777b538SAndroid Build Coastguard Worker
359*6777b538SAndroid Build Coastguard Worker protected:
360*6777b538SAndroid Build Coastguard Worker // Emplaces a new item into the tree that is known not to be in it. This
361*6777b538SAndroid Build Coastguard Worker // is for implementing map operator[].
362*6777b538SAndroid Build Coastguard Worker template <class... Args>
363*6777b538SAndroid Build Coastguard Worker iterator unsafe_emplace(const_iterator position, Args&&... args);
364*6777b538SAndroid Build Coastguard Worker
365*6777b538SAndroid Build Coastguard Worker // Attempts to emplace a new element with key |key|. Only if |key| is not yet
366*6777b538SAndroid Build Coastguard Worker // present, construct value_type from |args| and insert it. Returns an
367*6777b538SAndroid Build Coastguard Worker // iterator to the element with key |key| and a bool indicating whether an
368*6777b538SAndroid Build Coastguard Worker // insertion happened.
369*6777b538SAndroid Build Coastguard Worker template <class K, class... Args>
370*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> emplace_key_args(const K& key, Args&&... args);
371*6777b538SAndroid Build Coastguard Worker
372*6777b538SAndroid Build Coastguard Worker // Similar to |emplace_key_args|, but checks |hint| first as a possible
373*6777b538SAndroid Build Coastguard Worker // insertion position.
374*6777b538SAndroid Build Coastguard Worker template <class K, class... Args>
375*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> emplace_hint_key_args(const_iterator hint,
376*6777b538SAndroid Build Coastguard Worker const K& key,
377*6777b538SAndroid Build Coastguard Worker Args&&... args);
378*6777b538SAndroid Build Coastguard Worker
379*6777b538SAndroid Build Coastguard Worker private:
380*6777b538SAndroid Build Coastguard Worker // Helper class for e.g. lower_bound that can compare a value on the left
381*6777b538SAndroid Build Coastguard Worker // to a key on the right.
382*6777b538SAndroid Build Coastguard Worker struct KeyValueCompare {
383*6777b538SAndroid Build Coastguard Worker // The key comparison object must outlive this class.
KeyValueCompareKeyValueCompare384*6777b538SAndroid Build Coastguard Worker explicit KeyValueCompare(const key_compare& comp) : comp_(comp) {}
385*6777b538SAndroid Build Coastguard Worker
386*6777b538SAndroid Build Coastguard Worker template <typename T, typename U>
operatorKeyValueCompare387*6777b538SAndroid Build Coastguard Worker bool operator()(const T& lhs, const U& rhs) const {
388*6777b538SAndroid Build Coastguard Worker return comp_(extract_if_value_type(lhs), extract_if_value_type(rhs));
389*6777b538SAndroid Build Coastguard Worker }
390*6777b538SAndroid Build Coastguard Worker
391*6777b538SAndroid Build Coastguard Worker private:
extract_if_value_typeKeyValueCompare392*6777b538SAndroid Build Coastguard Worker const key_type& extract_if_value_type(const value_type& v) const {
393*6777b538SAndroid Build Coastguard Worker GetKeyFromValue extractor;
394*6777b538SAndroid Build Coastguard Worker return extractor(v);
395*6777b538SAndroid Build Coastguard Worker }
396*6777b538SAndroid Build Coastguard Worker
397*6777b538SAndroid Build Coastguard Worker template <typename K>
extract_if_value_typeKeyValueCompare398*6777b538SAndroid Build Coastguard Worker const K& extract_if_value_type(const K& k) const {
399*6777b538SAndroid Build Coastguard Worker return k;
400*6777b538SAndroid Build Coastguard Worker }
401*6777b538SAndroid Build Coastguard Worker // RAW_PTR_EXCLUSION: Binary size increase. There's also little value to
402*6777b538SAndroid Build Coastguard Worker // rewriting this member as it points to `flat_tree::comp_` and flat_tree
403*6777b538SAndroid Build Coastguard Worker // itself should be holding raw_ptr/raw_ref if necessary.
404*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const key_compare& comp_;
405*6777b538SAndroid Build Coastguard Worker };
406*6777b538SAndroid Build Coastguard Worker
const_cast_it(const_iterator c_it)407*6777b538SAndroid Build Coastguard Worker iterator const_cast_it(const_iterator c_it) {
408*6777b538SAndroid Build Coastguard Worker auto distance = std::distance(cbegin(), c_it);
409*6777b538SAndroid Build Coastguard Worker return std::next(begin(), distance);
410*6777b538SAndroid Build Coastguard Worker }
411*6777b538SAndroid Build Coastguard Worker
412*6777b538SAndroid Build Coastguard Worker // This method is inspired by both std::map::insert(P&&) and
413*6777b538SAndroid Build Coastguard Worker // std::map::insert_or_assign(const K&, V&&). It inserts val if an equivalent
414*6777b538SAndroid Build Coastguard Worker // element is not present yet, otherwise it overwrites. It returns an iterator
415*6777b538SAndroid Build Coastguard Worker // to the modified element and a flag indicating whether insertion or
416*6777b538SAndroid Build Coastguard Worker // assignment happened.
417*6777b538SAndroid Build Coastguard Worker template <class V>
insert_or_assign(V && val)418*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> insert_or_assign(V&& val) {
419*6777b538SAndroid Build Coastguard Worker auto position = lower_bound(GetKeyFromValue()(val));
420*6777b538SAndroid Build Coastguard Worker
421*6777b538SAndroid Build Coastguard Worker if (position == end() || value_comp()(val, *position))
422*6777b538SAndroid Build Coastguard Worker return {body_.emplace(position, std::forward<V>(val)), true};
423*6777b538SAndroid Build Coastguard Worker
424*6777b538SAndroid Build Coastguard Worker *position = std::forward<V>(val);
425*6777b538SAndroid Build Coastguard Worker return {position, false};
426*6777b538SAndroid Build Coastguard Worker }
427*6777b538SAndroid Build Coastguard Worker
428*6777b538SAndroid Build Coastguard Worker // This method is similar to insert_or_assign, with the following differences:
429*6777b538SAndroid Build Coastguard Worker // - Instead of searching [begin(), end()) it only searches [first, last).
430*6777b538SAndroid Build Coastguard Worker // - In case no equivalent element is found, val is appended to the end of the
431*6777b538SAndroid Build Coastguard Worker // underlying body and an iterator to the next bigger element in [first,
432*6777b538SAndroid Build Coastguard Worker // last) is returned.
433*6777b538SAndroid Build Coastguard Worker template <class V>
append_or_assign(iterator first,iterator last,V && val)434*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> append_or_assign(iterator first,
435*6777b538SAndroid Build Coastguard Worker iterator last,
436*6777b538SAndroid Build Coastguard Worker V&& val) {
437*6777b538SAndroid Build Coastguard Worker auto position = std::lower_bound(first, last, val, value_comp());
438*6777b538SAndroid Build Coastguard Worker
439*6777b538SAndroid Build Coastguard Worker if (position == last || value_comp()(val, *position)) {
440*6777b538SAndroid Build Coastguard Worker // emplace_back might invalidate position, which is why distance needs to
441*6777b538SAndroid Build Coastguard Worker // be cached.
442*6777b538SAndroid Build Coastguard Worker const difference_type distance = std::distance(begin(), position);
443*6777b538SAndroid Build Coastguard Worker body_.emplace_back(std::forward<V>(val));
444*6777b538SAndroid Build Coastguard Worker return {std::next(begin(), distance), true};
445*6777b538SAndroid Build Coastguard Worker }
446*6777b538SAndroid Build Coastguard Worker
447*6777b538SAndroid Build Coastguard Worker *position = std::forward<V>(val);
448*6777b538SAndroid Build Coastguard Worker return {position, false};
449*6777b538SAndroid Build Coastguard Worker }
450*6777b538SAndroid Build Coastguard Worker
451*6777b538SAndroid Build Coastguard Worker // This method is similar to insert, with the following differences:
452*6777b538SAndroid Build Coastguard Worker // - Instead of searching [begin(), end()) it only searches [first, last).
453*6777b538SAndroid Build Coastguard Worker // - In case no equivalent element is found, val is appended to the end of the
454*6777b538SAndroid Build Coastguard Worker // underlying body and an iterator to the next bigger element in [first,
455*6777b538SAndroid Build Coastguard Worker // last) is returned.
456*6777b538SAndroid Build Coastguard Worker template <class V>
append_unique(iterator first,iterator last,V && val)457*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> append_unique(iterator first,
458*6777b538SAndroid Build Coastguard Worker iterator last,
459*6777b538SAndroid Build Coastguard Worker V&& val) {
460*6777b538SAndroid Build Coastguard Worker auto position = std::lower_bound(first, last, val, value_comp());
461*6777b538SAndroid Build Coastguard Worker
462*6777b538SAndroid Build Coastguard Worker if (position == last || value_comp()(val, *position)) {
463*6777b538SAndroid Build Coastguard Worker // emplace_back might invalidate position, which is why distance needs to
464*6777b538SAndroid Build Coastguard Worker // be cached.
465*6777b538SAndroid Build Coastguard Worker const difference_type distance = std::distance(begin(), position);
466*6777b538SAndroid Build Coastguard Worker body_.emplace_back(std::forward<V>(val));
467*6777b538SAndroid Build Coastguard Worker return {std::next(begin(), distance), true};
468*6777b538SAndroid Build Coastguard Worker }
469*6777b538SAndroid Build Coastguard Worker
470*6777b538SAndroid Build Coastguard Worker return {position, false};
471*6777b538SAndroid Build Coastguard Worker }
472*6777b538SAndroid Build Coastguard Worker
sort_and_unique(iterator first,iterator last)473*6777b538SAndroid Build Coastguard Worker void sort_and_unique(iterator first, iterator last) {
474*6777b538SAndroid Build Coastguard Worker // Preserve stability for the unique code below.
475*6777b538SAndroid Build Coastguard Worker std::stable_sort(first, last, value_comp());
476*6777b538SAndroid Build Coastguard Worker
477*6777b538SAndroid Build Coastguard Worker // lhs is already <= rhs due to sort, therefore !(lhs < rhs) <=> lhs == rhs.
478*6777b538SAndroid Build Coastguard Worker auto equal_comp = std::not_fn(value_comp());
479*6777b538SAndroid Build Coastguard Worker erase(std::unique(first, last, equal_comp), last);
480*6777b538SAndroid Build Coastguard Worker }
481*6777b538SAndroid Build Coastguard Worker
sort_and_unique()482*6777b538SAndroid Build Coastguard Worker void sort_and_unique() { sort_and_unique(begin(), end()); }
483*6777b538SAndroid Build Coastguard Worker
484*6777b538SAndroid Build Coastguard Worker // To support comparators that may not be possible to default-construct, we
485*6777b538SAndroid Build Coastguard Worker // have to store an instance of Compare. Since Compare commonly is stateless,
486*6777b538SAndroid Build Coastguard Worker // we use the NO_UNIQUE_ADDRESS attribute to save space.
487*6777b538SAndroid Build Coastguard Worker NO_UNIQUE_ADDRESS key_compare comp_;
488*6777b538SAndroid Build Coastguard Worker // Declare after |key_compare_comp_| to workaround GCC ICE. For details
489*6777b538SAndroid Build Coastguard Worker // see https://crbug.com/1156268
490*6777b538SAndroid Build Coastguard Worker container_type body_;
491*6777b538SAndroid Build Coastguard Worker
492*6777b538SAndroid Build Coastguard Worker // If the compare is not transparent we want to construct key_type once.
493*6777b538SAndroid Build Coastguard Worker template <typename K>
494*6777b538SAndroid Build Coastguard Worker using KeyTypeOrK = std::conditional_t<requires {
495*6777b538SAndroid Build Coastguard Worker typename key_compare::is_transparent;
496*6777b538SAndroid Build Coastguard Worker }, K, key_type>;
497*6777b538SAndroid Build Coastguard Worker };
498*6777b538SAndroid Build Coastguard Worker
499*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
500*6777b538SAndroid Build Coastguard Worker // Lifetime.
501*6777b538SAndroid Build Coastguard Worker
502*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
flat_tree(const KeyCompare & comp)503*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
504*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
505*6777b538SAndroid Build Coastguard Worker : comp_(comp) {}
506*6777b538SAndroid Build Coastguard Worker
507*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
508*6777b538SAndroid Build Coastguard Worker template <class InputIterator>
flat_tree(InputIterator first,InputIterator last,const KeyCompare & comp)509*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
510*6777b538SAndroid Build Coastguard Worker InputIterator first,
511*6777b538SAndroid Build Coastguard Worker InputIterator last,
512*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
513*6777b538SAndroid Build Coastguard Worker : comp_(comp), body_(first, last) {
514*6777b538SAndroid Build Coastguard Worker sort_and_unique();
515*6777b538SAndroid Build Coastguard Worker }
516*6777b538SAndroid Build Coastguard Worker
517*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
flat_tree(const container_type & items,const KeyCompare & comp)518*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
519*6777b538SAndroid Build Coastguard Worker const container_type& items,
520*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
521*6777b538SAndroid Build Coastguard Worker : comp_(comp), body_(items) {
522*6777b538SAndroid Build Coastguard Worker sort_and_unique();
523*6777b538SAndroid Build Coastguard Worker }
524*6777b538SAndroid Build Coastguard Worker
525*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
flat_tree(container_type && items,const KeyCompare & comp)526*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
527*6777b538SAndroid Build Coastguard Worker container_type&& items,
528*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
529*6777b538SAndroid Build Coastguard Worker : comp_(comp), body_(std::move(items)) {
530*6777b538SAndroid Build Coastguard Worker sort_and_unique();
531*6777b538SAndroid Build Coastguard Worker }
532*6777b538SAndroid Build Coastguard Worker
533*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
flat_tree(std::initializer_list<value_type> ilist,const KeyCompare & comp)534*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
535*6777b538SAndroid Build Coastguard Worker std::initializer_list<value_type> ilist,
536*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
537*6777b538SAndroid Build Coastguard Worker : flat_tree(std::begin(ilist), std::end(ilist), comp) {}
538*6777b538SAndroid Build Coastguard Worker
539*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
540*6777b538SAndroid Build Coastguard Worker template <class InputIterator>
flat_tree(sorted_unique_t,InputIterator first,InputIterator last,const KeyCompare & comp)541*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
542*6777b538SAndroid Build Coastguard Worker sorted_unique_t,
543*6777b538SAndroid Build Coastguard Worker InputIterator first,
544*6777b538SAndroid Build Coastguard Worker InputIterator last,
545*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
546*6777b538SAndroid Build Coastguard Worker : comp_(comp), body_(first, last) {
547*6777b538SAndroid Build Coastguard Worker DCHECK(is_sorted_and_unique(*this, value_comp()));
548*6777b538SAndroid Build Coastguard Worker }
549*6777b538SAndroid Build Coastguard Worker
550*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
flat_tree(sorted_unique_t,const container_type & items,const KeyCompare & comp)551*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
552*6777b538SAndroid Build Coastguard Worker sorted_unique_t,
553*6777b538SAndroid Build Coastguard Worker const container_type& items,
554*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
555*6777b538SAndroid Build Coastguard Worker : comp_(comp), body_(items) {
556*6777b538SAndroid Build Coastguard Worker DCHECK(is_sorted_and_unique(*this, value_comp()));
557*6777b538SAndroid Build Coastguard Worker }
558*6777b538SAndroid Build Coastguard Worker
559*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
flat_tree(sorted_unique_t,container_type && items,const KeyCompare & comp)560*6777b538SAndroid Build Coastguard Worker constexpr flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
561*6777b538SAndroid Build Coastguard Worker sorted_unique_t,
562*6777b538SAndroid Build Coastguard Worker container_type&& items,
563*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
564*6777b538SAndroid Build Coastguard Worker : comp_(comp), body_(std::move(items)) {
565*6777b538SAndroid Build Coastguard Worker DCHECK(is_sorted_and_unique(*this, value_comp()));
566*6777b538SAndroid Build Coastguard Worker }
567*6777b538SAndroid Build Coastguard Worker
568*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
flat_tree(sorted_unique_t,std::initializer_list<value_type> ilist,const KeyCompare & comp)569*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::flat_tree(
570*6777b538SAndroid Build Coastguard Worker sorted_unique_t,
571*6777b538SAndroid Build Coastguard Worker std::initializer_list<value_type> ilist,
572*6777b538SAndroid Build Coastguard Worker const KeyCompare& comp)
573*6777b538SAndroid Build Coastguard Worker : flat_tree(sorted_unique, std::begin(ilist), std::end(ilist), comp) {}
574*6777b538SAndroid Build Coastguard Worker
575*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
576*6777b538SAndroid Build Coastguard Worker // Assignments.
577*6777b538SAndroid Build Coastguard Worker
578*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
579*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::operator=(
580*6777b538SAndroid Build Coastguard Worker std::initializer_list<value_type> ilist) -> flat_tree& {
581*6777b538SAndroid Build Coastguard Worker body_ = ilist;
582*6777b538SAndroid Build Coastguard Worker sort_and_unique();
583*6777b538SAndroid Build Coastguard Worker return *this;
584*6777b538SAndroid Build Coastguard Worker }
585*6777b538SAndroid Build Coastguard Worker
586*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
587*6777b538SAndroid Build Coastguard Worker // Memory management.
588*6777b538SAndroid Build Coastguard Worker
589*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
reserve(size_type new_capacity)590*6777b538SAndroid Build Coastguard Worker void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::reserve(
591*6777b538SAndroid Build Coastguard Worker size_type new_capacity) {
592*6777b538SAndroid Build Coastguard Worker body_.reserve(new_capacity);
593*6777b538SAndroid Build Coastguard Worker }
594*6777b538SAndroid Build Coastguard Worker
595*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
596*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::capacity() const
597*6777b538SAndroid Build Coastguard Worker -> size_type {
598*6777b538SAndroid Build Coastguard Worker return body_.capacity();
599*6777b538SAndroid Build Coastguard Worker }
600*6777b538SAndroid Build Coastguard Worker
601*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
shrink_to_fit()602*6777b538SAndroid Build Coastguard Worker void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::shrink_to_fit() {
603*6777b538SAndroid Build Coastguard Worker body_.shrink_to_fit();
604*6777b538SAndroid Build Coastguard Worker }
605*6777b538SAndroid Build Coastguard Worker
606*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
607*6777b538SAndroid Build Coastguard Worker // Size management.
608*6777b538SAndroid Build Coastguard Worker
609*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
clear()610*6777b538SAndroid Build Coastguard Worker void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::clear() {
611*6777b538SAndroid Build Coastguard Worker body_.clear();
612*6777b538SAndroid Build Coastguard Worker }
613*6777b538SAndroid Build Coastguard Worker
614*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
615*6777b538SAndroid Build Coastguard Worker constexpr auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::size()
616*6777b538SAndroid Build Coastguard Worker const -> size_type {
617*6777b538SAndroid Build Coastguard Worker return body_.size();
618*6777b538SAndroid Build Coastguard Worker }
619*6777b538SAndroid Build Coastguard Worker
620*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
621*6777b538SAndroid Build Coastguard Worker constexpr auto
622*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::max_size() const
623*6777b538SAndroid Build Coastguard Worker -> size_type {
624*6777b538SAndroid Build Coastguard Worker return body_.max_size();
625*6777b538SAndroid Build Coastguard Worker }
626*6777b538SAndroid Build Coastguard Worker
627*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
empty()628*6777b538SAndroid Build Coastguard Worker constexpr bool flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::empty()
629*6777b538SAndroid Build Coastguard Worker const {
630*6777b538SAndroid Build Coastguard Worker return body_.empty();
631*6777b538SAndroid Build Coastguard Worker }
632*6777b538SAndroid Build Coastguard Worker
633*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
634*6777b538SAndroid Build Coastguard Worker // Iterators.
635*6777b538SAndroid Build Coastguard Worker
636*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
637*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::begin()
638*6777b538SAndroid Build Coastguard Worker -> iterator {
639*6777b538SAndroid Build Coastguard Worker return body_.begin();
640*6777b538SAndroid Build Coastguard Worker }
641*6777b538SAndroid Build Coastguard Worker
642*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
643*6777b538SAndroid Build Coastguard Worker constexpr auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::begin()
644*6777b538SAndroid Build Coastguard Worker const -> const_iterator {
645*6777b538SAndroid Build Coastguard Worker return ranges::begin(body_);
646*6777b538SAndroid Build Coastguard Worker }
647*6777b538SAndroid Build Coastguard Worker
648*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
649*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::cbegin() const
650*6777b538SAndroid Build Coastguard Worker -> const_iterator {
651*6777b538SAndroid Build Coastguard Worker return body_.cbegin();
652*6777b538SAndroid Build Coastguard Worker }
653*6777b538SAndroid Build Coastguard Worker
654*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
655*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::end() -> iterator {
656*6777b538SAndroid Build Coastguard Worker return body_.end();
657*6777b538SAndroid Build Coastguard Worker }
658*6777b538SAndroid Build Coastguard Worker
659*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
660*6777b538SAndroid Build Coastguard Worker constexpr auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::end()
661*6777b538SAndroid Build Coastguard Worker const -> const_iterator {
662*6777b538SAndroid Build Coastguard Worker return ranges::end(body_);
663*6777b538SAndroid Build Coastguard Worker }
664*6777b538SAndroid Build Coastguard Worker
665*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
666*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::cend() const
667*6777b538SAndroid Build Coastguard Worker -> const_iterator {
668*6777b538SAndroid Build Coastguard Worker return body_.cend();
669*6777b538SAndroid Build Coastguard Worker }
670*6777b538SAndroid Build Coastguard Worker
671*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
672*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::rbegin()
673*6777b538SAndroid Build Coastguard Worker -> reverse_iterator {
674*6777b538SAndroid Build Coastguard Worker return body_.rbegin();
675*6777b538SAndroid Build Coastguard Worker }
676*6777b538SAndroid Build Coastguard Worker
677*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
678*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::rbegin() const
679*6777b538SAndroid Build Coastguard Worker -> const_reverse_iterator {
680*6777b538SAndroid Build Coastguard Worker return body_.rbegin();
681*6777b538SAndroid Build Coastguard Worker }
682*6777b538SAndroid Build Coastguard Worker
683*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
684*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::crbegin() const
685*6777b538SAndroid Build Coastguard Worker -> const_reverse_iterator {
686*6777b538SAndroid Build Coastguard Worker return body_.crbegin();
687*6777b538SAndroid Build Coastguard Worker }
688*6777b538SAndroid Build Coastguard Worker
689*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
690*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::rend()
691*6777b538SAndroid Build Coastguard Worker -> reverse_iterator {
692*6777b538SAndroid Build Coastguard Worker return body_.rend();
693*6777b538SAndroid Build Coastguard Worker }
694*6777b538SAndroid Build Coastguard Worker
695*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
696*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::rend() const
697*6777b538SAndroid Build Coastguard Worker -> const_reverse_iterator {
698*6777b538SAndroid Build Coastguard Worker return body_.rend();
699*6777b538SAndroid Build Coastguard Worker }
700*6777b538SAndroid Build Coastguard Worker
701*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
702*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::crend() const
703*6777b538SAndroid Build Coastguard Worker -> const_reverse_iterator {
704*6777b538SAndroid Build Coastguard Worker return body_.crend();
705*6777b538SAndroid Build Coastguard Worker }
706*6777b538SAndroid Build Coastguard Worker
707*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
708*6777b538SAndroid Build Coastguard Worker // Insert operations.
709*6777b538SAndroid Build Coastguard Worker //
710*6777b538SAndroid Build Coastguard Worker // Currently we use position_hint the same way as eastl or boost:
711*6777b538SAndroid Build Coastguard Worker // https://github.com/electronicarts/EASTL/blob/master/include/EASTL/vector_set.h#L493
712*6777b538SAndroid Build Coastguard Worker
713*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
714*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::insert(
715*6777b538SAndroid Build Coastguard Worker const value_type& val) -> std::pair<iterator, bool> {
716*6777b538SAndroid Build Coastguard Worker return emplace_key_args(GetKeyFromValue()(val), val);
717*6777b538SAndroid Build Coastguard Worker }
718*6777b538SAndroid Build Coastguard Worker
719*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
720*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::insert(
721*6777b538SAndroid Build Coastguard Worker value_type&& val) -> std::pair<iterator, bool> {
722*6777b538SAndroid Build Coastguard Worker return emplace_key_args(GetKeyFromValue()(val), std::move(val));
723*6777b538SAndroid Build Coastguard Worker }
724*6777b538SAndroid Build Coastguard Worker
725*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
726*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::insert(
727*6777b538SAndroid Build Coastguard Worker const_iterator position_hint,
728*6777b538SAndroid Build Coastguard Worker const value_type& val) -> iterator {
729*6777b538SAndroid Build Coastguard Worker return emplace_hint_key_args(position_hint, GetKeyFromValue()(val), val)
730*6777b538SAndroid Build Coastguard Worker .first;
731*6777b538SAndroid Build Coastguard Worker }
732*6777b538SAndroid Build Coastguard Worker
733*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
734*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::insert(
735*6777b538SAndroid Build Coastguard Worker const_iterator position_hint,
736*6777b538SAndroid Build Coastguard Worker value_type&& val) -> iterator {
737*6777b538SAndroid Build Coastguard Worker return emplace_hint_key_args(position_hint, GetKeyFromValue()(val),
738*6777b538SAndroid Build Coastguard Worker std::move(val))
739*6777b538SAndroid Build Coastguard Worker .first;
740*6777b538SAndroid Build Coastguard Worker }
741*6777b538SAndroid Build Coastguard Worker
742*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
743*6777b538SAndroid Build Coastguard Worker template <class InputIterator>
insert(InputIterator first,InputIterator last)744*6777b538SAndroid Build Coastguard Worker void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::insert(
745*6777b538SAndroid Build Coastguard Worker InputIterator first,
746*6777b538SAndroid Build Coastguard Worker InputIterator last) {
747*6777b538SAndroid Build Coastguard Worker if (first == last)
748*6777b538SAndroid Build Coastguard Worker return;
749*6777b538SAndroid Build Coastguard Worker
750*6777b538SAndroid Build Coastguard Worker // Dispatch to single element insert if the input range contains a single
751*6777b538SAndroid Build Coastguard Worker // element.
752*6777b538SAndroid Build Coastguard Worker if (std::forward_iterator<InputIterator> && std::next(first) == last) {
753*6777b538SAndroid Build Coastguard Worker insert(end(), *first);
754*6777b538SAndroid Build Coastguard Worker return;
755*6777b538SAndroid Build Coastguard Worker }
756*6777b538SAndroid Build Coastguard Worker
757*6777b538SAndroid Build Coastguard Worker // Provide a convenience lambda to obtain an iterator pointing past the last
758*6777b538SAndroid Build Coastguard Worker // old element. This needs to be dymanic due to possible re-allocations.
759*6777b538SAndroid Build Coastguard Worker auto middle = [this, size = size()] {
760*6777b538SAndroid Build Coastguard Worker return std::next(begin(), static_cast<difference_type>(size));
761*6777b538SAndroid Build Coastguard Worker };
762*6777b538SAndroid Build Coastguard Worker
763*6777b538SAndroid Build Coastguard Worker // For batch updates initialize the first insertion point.
764*6777b538SAndroid Build Coastguard Worker auto pos_first_new = static_cast<difference_type>(size());
765*6777b538SAndroid Build Coastguard Worker
766*6777b538SAndroid Build Coastguard Worker // Loop over the input range while appending new values and overwriting
767*6777b538SAndroid Build Coastguard Worker // existing ones, if applicable. Keep track of the first insertion point.
768*6777b538SAndroid Build Coastguard Worker for (; first != last; ++first) {
769*6777b538SAndroid Build Coastguard Worker std::pair<iterator, bool> result = append_unique(begin(), middle(), *first);
770*6777b538SAndroid Build Coastguard Worker if (result.second) {
771*6777b538SAndroid Build Coastguard Worker pos_first_new =
772*6777b538SAndroid Build Coastguard Worker std::min(pos_first_new, std::distance(begin(), result.first));
773*6777b538SAndroid Build Coastguard Worker }
774*6777b538SAndroid Build Coastguard Worker }
775*6777b538SAndroid Build Coastguard Worker
776*6777b538SAndroid Build Coastguard Worker // The new elements might be unordered and contain duplicates, so post-process
777*6777b538SAndroid Build Coastguard Worker // the just inserted elements and merge them with the rest, inserting them at
778*6777b538SAndroid Build Coastguard Worker // the previously found spot.
779*6777b538SAndroid Build Coastguard Worker sort_and_unique(middle(), end());
780*6777b538SAndroid Build Coastguard Worker std::inplace_merge(std::next(begin(), pos_first_new), middle(), end(),
781*6777b538SAndroid Build Coastguard Worker value_comp());
782*6777b538SAndroid Build Coastguard Worker }
783*6777b538SAndroid Build Coastguard Worker
784*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
785*6777b538SAndroid Build Coastguard Worker template <class... Args>
786*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::emplace(
787*6777b538SAndroid Build Coastguard Worker Args&&... args) -> std::pair<iterator, bool> {
788*6777b538SAndroid Build Coastguard Worker return insert(value_type(std::forward<Args>(args)...));
789*6777b538SAndroid Build Coastguard Worker }
790*6777b538SAndroid Build Coastguard Worker
791*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
792*6777b538SAndroid Build Coastguard Worker template <class... Args>
793*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::emplace_hint(
794*6777b538SAndroid Build Coastguard Worker const_iterator position_hint,
795*6777b538SAndroid Build Coastguard Worker Args&&... args) -> iterator {
796*6777b538SAndroid Build Coastguard Worker return insert(position_hint, value_type(std::forward<Args>(args)...));
797*6777b538SAndroid Build Coastguard Worker }
798*6777b538SAndroid Build Coastguard Worker
799*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
800*6777b538SAndroid Build Coastguard Worker // Underlying type operations.
801*6777b538SAndroid Build Coastguard Worker
802*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
803*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::
804*6777b538SAndroid Build Coastguard Worker extract() && -> container_type {
805*6777b538SAndroid Build Coastguard Worker return std::exchange(body_, container_type());
806*6777b538SAndroid Build Coastguard Worker }
807*6777b538SAndroid Build Coastguard Worker
808*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
replace(container_type && body)809*6777b538SAndroid Build Coastguard Worker void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::replace(
810*6777b538SAndroid Build Coastguard Worker container_type&& body) {
811*6777b538SAndroid Build Coastguard Worker // Ensure that `body` is sorted and has no repeated elements according to
812*6777b538SAndroid Build Coastguard Worker // `value_comp()`.
813*6777b538SAndroid Build Coastguard Worker DCHECK(is_sorted_and_unique(body, value_comp()));
814*6777b538SAndroid Build Coastguard Worker body_ = std::move(body);
815*6777b538SAndroid Build Coastguard Worker }
816*6777b538SAndroid Build Coastguard Worker
817*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
818*6777b538SAndroid Build Coastguard Worker // Erase operations.
819*6777b538SAndroid Build Coastguard Worker
820*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
821*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::erase(
822*6777b538SAndroid Build Coastguard Worker iterator position) -> iterator {
823*6777b538SAndroid Build Coastguard Worker CHECK(position != body_.end());
824*6777b538SAndroid Build Coastguard Worker return body_.erase(position);
825*6777b538SAndroid Build Coastguard Worker }
826*6777b538SAndroid Build Coastguard Worker
827*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
828*6777b538SAndroid Build Coastguard Worker template <typename DummyT>
829*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::erase(
830*6777b538SAndroid Build Coastguard Worker const_iterator position) -> iterator {
831*6777b538SAndroid Build Coastguard Worker CHECK(position != body_.end());
832*6777b538SAndroid Build Coastguard Worker return body_.erase(position);
833*6777b538SAndroid Build Coastguard Worker }
834*6777b538SAndroid Build Coastguard Worker
835*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
836*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::erase(
837*6777b538SAndroid Build Coastguard Worker const Key& val) -> size_type {
838*6777b538SAndroid Build Coastguard Worker auto eq_range = equal_range(val);
839*6777b538SAndroid Build Coastguard Worker auto res =
840*6777b538SAndroid Build Coastguard Worker static_cast<size_type>(std::distance(eq_range.first, eq_range.second));
841*6777b538SAndroid Build Coastguard Worker erase(eq_range.first, eq_range.second);
842*6777b538SAndroid Build Coastguard Worker return res;
843*6777b538SAndroid Build Coastguard Worker }
844*6777b538SAndroid Build Coastguard Worker
845*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
846*6777b538SAndroid Build Coastguard Worker template <typename K>
847*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::erase(const K& val)
848*6777b538SAndroid Build Coastguard Worker -> size_type {
849*6777b538SAndroid Build Coastguard Worker auto eq_range = equal_range(val);
850*6777b538SAndroid Build Coastguard Worker auto res =
851*6777b538SAndroid Build Coastguard Worker static_cast<size_type>(std::distance(eq_range.first, eq_range.second));
852*6777b538SAndroid Build Coastguard Worker erase(eq_range.first, eq_range.second);
853*6777b538SAndroid Build Coastguard Worker return res;
854*6777b538SAndroid Build Coastguard Worker }
855*6777b538SAndroid Build Coastguard Worker
856*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
857*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::erase(
858*6777b538SAndroid Build Coastguard Worker const_iterator first,
859*6777b538SAndroid Build Coastguard Worker const_iterator last) -> iterator {
860*6777b538SAndroid Build Coastguard Worker return body_.erase(first, last);
861*6777b538SAndroid Build Coastguard Worker }
862*6777b538SAndroid Build Coastguard Worker
863*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
864*6777b538SAndroid Build Coastguard Worker // Comparators.
865*6777b538SAndroid Build Coastguard Worker
866*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
867*6777b538SAndroid Build Coastguard Worker constexpr auto
868*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::key_comp() const
869*6777b538SAndroid Build Coastguard Worker -> key_compare {
870*6777b538SAndroid Build Coastguard Worker return comp_;
871*6777b538SAndroid Build Coastguard Worker }
872*6777b538SAndroid Build Coastguard Worker
873*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
874*6777b538SAndroid Build Coastguard Worker constexpr auto
875*6777b538SAndroid Build Coastguard Worker flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::value_comp() const
876*6777b538SAndroid Build Coastguard Worker -> value_compare {
877*6777b538SAndroid Build Coastguard Worker return value_compare{comp_};
878*6777b538SAndroid Build Coastguard Worker }
879*6777b538SAndroid Build Coastguard Worker
880*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
881*6777b538SAndroid Build Coastguard Worker // Search operations.
882*6777b538SAndroid Build Coastguard Worker
883*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
884*6777b538SAndroid Build Coastguard Worker template <typename K>
885*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::count(
886*6777b538SAndroid Build Coastguard Worker const K& key) const -> size_type {
887*6777b538SAndroid Build Coastguard Worker auto eq_range = equal_range(key);
888*6777b538SAndroid Build Coastguard Worker return static_cast<size_type>(std::distance(eq_range.first, eq_range.second));
889*6777b538SAndroid Build Coastguard Worker }
890*6777b538SAndroid Build Coastguard Worker
891*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
892*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::count(
893*6777b538SAndroid Build Coastguard Worker const Key& key) const -> size_type {
894*6777b538SAndroid Build Coastguard Worker auto eq_range = equal_range(key);
895*6777b538SAndroid Build Coastguard Worker return static_cast<size_type>(std::distance(eq_range.first, eq_range.second));
896*6777b538SAndroid Build Coastguard Worker }
897*6777b538SAndroid Build Coastguard Worker
898*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
899*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::find(
900*6777b538SAndroid Build Coastguard Worker const Key& key) -> iterator {
901*6777b538SAndroid Build Coastguard Worker return const_cast_it(std::as_const(*this).find(key));
902*6777b538SAndroid Build Coastguard Worker }
903*6777b538SAndroid Build Coastguard Worker
904*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
905*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::find(
906*6777b538SAndroid Build Coastguard Worker const Key& key) const -> const_iterator {
907*6777b538SAndroid Build Coastguard Worker auto eq_range = equal_range(key);
908*6777b538SAndroid Build Coastguard Worker return (eq_range.first == eq_range.second) ? end() : eq_range.first;
909*6777b538SAndroid Build Coastguard Worker }
910*6777b538SAndroid Build Coastguard Worker
911*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
912*6777b538SAndroid Build Coastguard Worker template <typename K>
913*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::find(const K& key)
914*6777b538SAndroid Build Coastguard Worker -> iterator {
915*6777b538SAndroid Build Coastguard Worker return const_cast_it(std::as_const(*this).find(key));
916*6777b538SAndroid Build Coastguard Worker }
917*6777b538SAndroid Build Coastguard Worker
918*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
919*6777b538SAndroid Build Coastguard Worker template <typename K>
920*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::find(
921*6777b538SAndroid Build Coastguard Worker const K& key) const -> const_iterator {
922*6777b538SAndroid Build Coastguard Worker auto eq_range = equal_range(key);
923*6777b538SAndroid Build Coastguard Worker return (eq_range.first == eq_range.second) ? end() : eq_range.first;
924*6777b538SAndroid Build Coastguard Worker }
925*6777b538SAndroid Build Coastguard Worker
926*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
contains(const Key & key)927*6777b538SAndroid Build Coastguard Worker bool flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::contains(
928*6777b538SAndroid Build Coastguard Worker const Key& key) const {
929*6777b538SAndroid Build Coastguard Worker auto lower = lower_bound(key);
930*6777b538SAndroid Build Coastguard Worker return lower != end() && !comp_(key, GetKeyFromValue()(*lower));
931*6777b538SAndroid Build Coastguard Worker }
932*6777b538SAndroid Build Coastguard Worker
933*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
934*6777b538SAndroid Build Coastguard Worker template <typename K>
contains(const K & key)935*6777b538SAndroid Build Coastguard Worker bool flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::contains(
936*6777b538SAndroid Build Coastguard Worker const K& key) const {
937*6777b538SAndroid Build Coastguard Worker auto lower = lower_bound(key);
938*6777b538SAndroid Build Coastguard Worker return lower != end() && !comp_(key, GetKeyFromValue()(*lower));
939*6777b538SAndroid Build Coastguard Worker }
940*6777b538SAndroid Build Coastguard Worker
941*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
942*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::equal_range(
943*6777b538SAndroid Build Coastguard Worker const Key& key) -> std::pair<iterator, iterator> {
944*6777b538SAndroid Build Coastguard Worker auto res = std::as_const(*this).equal_range(key);
945*6777b538SAndroid Build Coastguard Worker return {const_cast_it(res.first), const_cast_it(res.second)};
946*6777b538SAndroid Build Coastguard Worker }
947*6777b538SAndroid Build Coastguard Worker
948*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
949*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::equal_range(
950*6777b538SAndroid Build Coastguard Worker const Key& key) const -> std::pair<const_iterator, const_iterator> {
951*6777b538SAndroid Build Coastguard Worker auto lower = lower_bound(key);
952*6777b538SAndroid Build Coastguard Worker
953*6777b538SAndroid Build Coastguard Worker KeyValueCompare comp(comp_);
954*6777b538SAndroid Build Coastguard Worker if (lower == end() || comp(key, *lower))
955*6777b538SAndroid Build Coastguard Worker return {lower, lower};
956*6777b538SAndroid Build Coastguard Worker
957*6777b538SAndroid Build Coastguard Worker return {lower, std::next(lower)};
958*6777b538SAndroid Build Coastguard Worker }
959*6777b538SAndroid Build Coastguard Worker
960*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
961*6777b538SAndroid Build Coastguard Worker template <typename K>
962*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::equal_range(
963*6777b538SAndroid Build Coastguard Worker const K& key) -> std::pair<iterator, iterator> {
964*6777b538SAndroid Build Coastguard Worker auto res = std::as_const(*this).equal_range(key);
965*6777b538SAndroid Build Coastguard Worker return {const_cast_it(res.first), const_cast_it(res.second)};
966*6777b538SAndroid Build Coastguard Worker }
967*6777b538SAndroid Build Coastguard Worker
968*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
969*6777b538SAndroid Build Coastguard Worker template <typename K>
970*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::equal_range(
971*6777b538SAndroid Build Coastguard Worker const K& key) const -> std::pair<const_iterator, const_iterator> {
972*6777b538SAndroid Build Coastguard Worker auto lower = lower_bound(key);
973*6777b538SAndroid Build Coastguard Worker
974*6777b538SAndroid Build Coastguard Worker KeyValueCompare comp(comp_);
975*6777b538SAndroid Build Coastguard Worker if (lower == end() || comp(key, *lower))
976*6777b538SAndroid Build Coastguard Worker return {lower, lower};
977*6777b538SAndroid Build Coastguard Worker
978*6777b538SAndroid Build Coastguard Worker return {lower, std::next(lower)};
979*6777b538SAndroid Build Coastguard Worker }
980*6777b538SAndroid Build Coastguard Worker
981*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
982*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::lower_bound(
983*6777b538SAndroid Build Coastguard Worker const Key& key) -> iterator {
984*6777b538SAndroid Build Coastguard Worker return const_cast_it(std::as_const(*this).lower_bound(key));
985*6777b538SAndroid Build Coastguard Worker }
986*6777b538SAndroid Build Coastguard Worker
987*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
988*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::lower_bound(
989*6777b538SAndroid Build Coastguard Worker const Key& key) const -> const_iterator {
990*6777b538SAndroid Build Coastguard Worker KeyValueCompare comp(comp_);
991*6777b538SAndroid Build Coastguard Worker return ranges::lower_bound(*this, key, comp);
992*6777b538SAndroid Build Coastguard Worker }
993*6777b538SAndroid Build Coastguard Worker
994*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
995*6777b538SAndroid Build Coastguard Worker template <typename K>
996*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::lower_bound(
997*6777b538SAndroid Build Coastguard Worker const K& key) -> iterator {
998*6777b538SAndroid Build Coastguard Worker return const_cast_it(std::as_const(*this).lower_bound(key));
999*6777b538SAndroid Build Coastguard Worker }
1000*6777b538SAndroid Build Coastguard Worker
1001*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
1002*6777b538SAndroid Build Coastguard Worker template <typename K>
1003*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::lower_bound(
1004*6777b538SAndroid Build Coastguard Worker const K& key) const -> const_iterator {
1005*6777b538SAndroid Build Coastguard Worker static_assert(std::is_convertible_v<const KeyTypeOrK<K>&, const K&>,
1006*6777b538SAndroid Build Coastguard Worker "Requested type cannot be bound to the container's key_type "
1007*6777b538SAndroid Build Coastguard Worker "which is required for a non-transparent compare.");
1008*6777b538SAndroid Build Coastguard Worker
1009*6777b538SAndroid Build Coastguard Worker const KeyTypeOrK<K>& key_ref = key;
1010*6777b538SAndroid Build Coastguard Worker
1011*6777b538SAndroid Build Coastguard Worker KeyValueCompare comp(comp_);
1012*6777b538SAndroid Build Coastguard Worker return ranges::lower_bound(*this, key_ref, comp);
1013*6777b538SAndroid Build Coastguard Worker }
1014*6777b538SAndroid Build Coastguard Worker
1015*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
1016*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::upper_bound(
1017*6777b538SAndroid Build Coastguard Worker const Key& key) -> iterator {
1018*6777b538SAndroid Build Coastguard Worker return const_cast_it(std::as_const(*this).upper_bound(key));
1019*6777b538SAndroid Build Coastguard Worker }
1020*6777b538SAndroid Build Coastguard Worker
1021*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
1022*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::upper_bound(
1023*6777b538SAndroid Build Coastguard Worker const Key& key) const -> const_iterator {
1024*6777b538SAndroid Build Coastguard Worker KeyValueCompare comp(comp_);
1025*6777b538SAndroid Build Coastguard Worker return ranges::upper_bound(*this, key, comp);
1026*6777b538SAndroid Build Coastguard Worker }
1027*6777b538SAndroid Build Coastguard Worker
1028*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
1029*6777b538SAndroid Build Coastguard Worker template <typename K>
1030*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::upper_bound(
1031*6777b538SAndroid Build Coastguard Worker const K& key) -> iterator {
1032*6777b538SAndroid Build Coastguard Worker return const_cast_it(std::as_const(*this).upper_bound(key));
1033*6777b538SAndroid Build Coastguard Worker }
1034*6777b538SAndroid Build Coastguard Worker
1035*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
1036*6777b538SAndroid Build Coastguard Worker template <typename K>
1037*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::upper_bound(
1038*6777b538SAndroid Build Coastguard Worker const K& key) const -> const_iterator {
1039*6777b538SAndroid Build Coastguard Worker static_assert(std::is_convertible_v<const KeyTypeOrK<K>&, const K&>,
1040*6777b538SAndroid Build Coastguard Worker "Requested type cannot be bound to the container's key_type "
1041*6777b538SAndroid Build Coastguard Worker "which is required for a non-transparent compare.");
1042*6777b538SAndroid Build Coastguard Worker
1043*6777b538SAndroid Build Coastguard Worker const KeyTypeOrK<K>& key_ref = key;
1044*6777b538SAndroid Build Coastguard Worker
1045*6777b538SAndroid Build Coastguard Worker KeyValueCompare comp(comp_);
1046*6777b538SAndroid Build Coastguard Worker return ranges::upper_bound(*this, key_ref, comp);
1047*6777b538SAndroid Build Coastguard Worker }
1048*6777b538SAndroid Build Coastguard Worker
1049*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
1050*6777b538SAndroid Build Coastguard Worker // General operations.
1051*6777b538SAndroid Build Coastguard Worker
1052*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
swap(flat_tree & other)1053*6777b538SAndroid Build Coastguard Worker void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::swap(
1054*6777b538SAndroid Build Coastguard Worker flat_tree& other) noexcept {
1055*6777b538SAndroid Build Coastguard Worker std::swap(*this, other);
1056*6777b538SAndroid Build Coastguard Worker }
1057*6777b538SAndroid Build Coastguard Worker
1058*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
1059*6777b538SAndroid Build Coastguard Worker template <class... Args>
1060*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::unsafe_emplace(
1061*6777b538SAndroid Build Coastguard Worker const_iterator position,
1062*6777b538SAndroid Build Coastguard Worker Args&&... args) -> iterator {
1063*6777b538SAndroid Build Coastguard Worker return body_.emplace(position, std::forward<Args>(args)...);
1064*6777b538SAndroid Build Coastguard Worker }
1065*6777b538SAndroid Build Coastguard Worker
1066*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
1067*6777b538SAndroid Build Coastguard Worker template <class K, class... Args>
1068*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::emplace_key_args(
1069*6777b538SAndroid Build Coastguard Worker const K& key,
1070*6777b538SAndroid Build Coastguard Worker Args&&... args) -> std::pair<iterator, bool> {
1071*6777b538SAndroid Build Coastguard Worker auto lower = lower_bound(key);
1072*6777b538SAndroid Build Coastguard Worker if (lower == end() || comp_(key, GetKeyFromValue()(*lower)))
1073*6777b538SAndroid Build Coastguard Worker return {unsafe_emplace(lower, std::forward<Args>(args)...), true};
1074*6777b538SAndroid Build Coastguard Worker return {lower, false};
1075*6777b538SAndroid Build Coastguard Worker }
1076*6777b538SAndroid Build Coastguard Worker
1077*6777b538SAndroid Build Coastguard Worker template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
1078*6777b538SAndroid Build Coastguard Worker template <class K, class... Args>
1079*6777b538SAndroid Build Coastguard Worker auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::
1080*6777b538SAndroid Build Coastguard Worker emplace_hint_key_args(const_iterator hint, const K& key, Args&&... args)
1081*6777b538SAndroid Build Coastguard Worker -> std::pair<iterator, bool> {
1082*6777b538SAndroid Build Coastguard Worker KeyValueCompare comp(comp_);
1083*6777b538SAndroid Build Coastguard Worker if ((hint == begin() || comp(*std::prev(hint), key))) {
1084*6777b538SAndroid Build Coastguard Worker if (hint == end() || comp(key, *hint)) {
1085*6777b538SAndroid Build Coastguard Worker // *(hint - 1) < key < *hint => key did not exist and hint is correct.
1086*6777b538SAndroid Build Coastguard Worker return {unsafe_emplace(hint, std::forward<Args>(args)...), true};
1087*6777b538SAndroid Build Coastguard Worker }
1088*6777b538SAndroid Build Coastguard Worker if (!comp(*hint, key)) {
1089*6777b538SAndroid Build Coastguard Worker // key == *hint => no-op, return correct hint.
1090*6777b538SAndroid Build Coastguard Worker return {const_cast_it(hint), false};
1091*6777b538SAndroid Build Coastguard Worker }
1092*6777b538SAndroid Build Coastguard Worker }
1093*6777b538SAndroid Build Coastguard Worker // hint was not helpful, dispatch to hintless version.
1094*6777b538SAndroid Build Coastguard Worker return emplace_key_args(key, std::forward<Args>(args)...);
1095*6777b538SAndroid Build Coastguard Worker }
1096*6777b538SAndroid Build Coastguard Worker
1097*6777b538SAndroid Build Coastguard Worker } // namespace internal
1098*6777b538SAndroid Build Coastguard Worker
1099*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
1100*6777b538SAndroid Build Coastguard Worker // Free functions.
1101*6777b538SAndroid Build Coastguard Worker
1102*6777b538SAndroid Build Coastguard Worker // Erases all elements that match predicate. It has O(size) complexity.
1103*6777b538SAndroid Build Coastguard Worker template <class Key,
1104*6777b538SAndroid Build Coastguard Worker class GetKeyFromValue,
1105*6777b538SAndroid Build Coastguard Worker class KeyCompare,
1106*6777b538SAndroid Build Coastguard Worker class Container,
1107*6777b538SAndroid Build Coastguard Worker typename Predicate>
EraseIf(base::internal::flat_tree<Key,GetKeyFromValue,KeyCompare,Container> & container,Predicate pred)1108*6777b538SAndroid Build Coastguard Worker size_t EraseIf(
1109*6777b538SAndroid Build Coastguard Worker base::internal::flat_tree<Key, GetKeyFromValue, KeyCompare, Container>&
1110*6777b538SAndroid Build Coastguard Worker container,
1111*6777b538SAndroid Build Coastguard Worker Predicate pred) {
1112*6777b538SAndroid Build Coastguard Worker auto it = ranges::remove_if(container, pred);
1113*6777b538SAndroid Build Coastguard Worker size_t removed = std::distance(it, container.end());
1114*6777b538SAndroid Build Coastguard Worker container.erase(it, container.end());
1115*6777b538SAndroid Build Coastguard Worker return removed;
1116*6777b538SAndroid Build Coastguard Worker }
1117*6777b538SAndroid Build Coastguard Worker
1118*6777b538SAndroid Build Coastguard Worker } // namespace base
1119*6777b538SAndroid Build Coastguard Worker
1120*6777b538SAndroid Build Coastguard Worker #endif // BASE_CONTAINERS_FLAT_TREE_H_
1121