xref: /aosp_15_r20/external/abseil-cpp/absl/container/btree_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2018 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #include "absl/container/btree_test.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include <algorithm>
18*9356374aSAndroid Build Coastguard Worker #include <array>
19*9356374aSAndroid Build Coastguard Worker #include <cstdint>
20*9356374aSAndroid Build Coastguard Worker #include <functional>
21*9356374aSAndroid Build Coastguard Worker #include <iostream>
22*9356374aSAndroid Build Coastguard Worker #include <iterator>
23*9356374aSAndroid Build Coastguard Worker #include <limits>
24*9356374aSAndroid Build Coastguard Worker #include <map>
25*9356374aSAndroid Build Coastguard Worker #include <memory>
26*9356374aSAndroid Build Coastguard Worker #include <numeric>
27*9356374aSAndroid Build Coastguard Worker #include <stdexcept>
28*9356374aSAndroid Build Coastguard Worker #include <string>
29*9356374aSAndroid Build Coastguard Worker #include <type_traits>
30*9356374aSAndroid Build Coastguard Worker #include <utility>
31*9356374aSAndroid Build Coastguard Worker #include <vector>
32*9356374aSAndroid Build Coastguard Worker 
33*9356374aSAndroid Build Coastguard Worker #include "gmock/gmock.h"
34*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
35*9356374aSAndroid Build Coastguard Worker #include "absl/algorithm/container.h"
36*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/raw_logging.h"
37*9356374aSAndroid Build Coastguard Worker #include "absl/base/macros.h"
38*9356374aSAndroid Build Coastguard Worker #include "absl/container/btree_map.h"
39*9356374aSAndroid Build Coastguard Worker #include "absl/container/btree_set.h"
40*9356374aSAndroid Build Coastguard Worker #include "absl/container/internal/test_allocator.h"
41*9356374aSAndroid Build Coastguard Worker #include "absl/container/internal/test_instance_tracker.h"
42*9356374aSAndroid Build Coastguard Worker #include "absl/flags/flag.h"
43*9356374aSAndroid Build Coastguard Worker #include "absl/hash/hash_testing.h"
44*9356374aSAndroid Build Coastguard Worker #include "absl/memory/memory.h"
45*9356374aSAndroid Build Coastguard Worker #include "absl/random/random.h"
46*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_cat.h"
47*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_split.h"
48*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
49*9356374aSAndroid Build Coastguard Worker #include "absl/types/compare.h"
50*9356374aSAndroid Build Coastguard Worker #include "absl/types/optional.h"
51*9356374aSAndroid Build Coastguard Worker 
52*9356374aSAndroid Build Coastguard Worker ABSL_FLAG(int, test_values, 10000, "The number of values to use for tests");
53*9356374aSAndroid Build Coastguard Worker 
54*9356374aSAndroid Build Coastguard Worker namespace absl {
55*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
56*9356374aSAndroid Build Coastguard Worker namespace container_internal {
57*9356374aSAndroid Build Coastguard Worker namespace {
58*9356374aSAndroid Build Coastguard Worker 
59*9356374aSAndroid Build Coastguard Worker using ::absl::test_internal::CopyableMovableInstance;
60*9356374aSAndroid Build Coastguard Worker using ::absl::test_internal::InstanceTracker;
61*9356374aSAndroid Build Coastguard Worker using ::absl::test_internal::MovableOnlyInstance;
62*9356374aSAndroid Build Coastguard Worker using ::testing::ElementsAre;
63*9356374aSAndroid Build Coastguard Worker using ::testing::ElementsAreArray;
64*9356374aSAndroid Build Coastguard Worker using ::testing::IsEmpty;
65*9356374aSAndroid Build Coastguard Worker using ::testing::IsNull;
66*9356374aSAndroid Build Coastguard Worker using ::testing::Pair;
67*9356374aSAndroid Build Coastguard Worker using ::testing::SizeIs;
68*9356374aSAndroid Build Coastguard Worker 
69*9356374aSAndroid Build Coastguard Worker template <typename T, typename U>
CheckPairEquals(const T & x,const U & y)70*9356374aSAndroid Build Coastguard Worker void CheckPairEquals(const T &x, const U &y) {
71*9356374aSAndroid Build Coastguard Worker   ABSL_INTERNAL_CHECK(x == y, "Values are unequal.");
72*9356374aSAndroid Build Coastguard Worker }
73*9356374aSAndroid Build Coastguard Worker 
74*9356374aSAndroid Build Coastguard Worker template <typename T, typename U, typename V, typename W>
CheckPairEquals(const std::pair<T,U> & x,const std::pair<V,W> & y)75*9356374aSAndroid Build Coastguard Worker void CheckPairEquals(const std::pair<T, U> &x, const std::pair<V, W> &y) {
76*9356374aSAndroid Build Coastguard Worker   CheckPairEquals(x.first, y.first);
77*9356374aSAndroid Build Coastguard Worker   CheckPairEquals(x.second, y.second);
78*9356374aSAndroid Build Coastguard Worker }
79*9356374aSAndroid Build Coastguard Worker }  // namespace
80*9356374aSAndroid Build Coastguard Worker 
81*9356374aSAndroid Build Coastguard Worker // The base class for a sorted associative container checker. TreeType is the
82*9356374aSAndroid Build Coastguard Worker // container type to check and CheckerType is the container type to check
83*9356374aSAndroid Build Coastguard Worker // against. TreeType is expected to be btree_{set,map,multiset,multimap} and
84*9356374aSAndroid Build Coastguard Worker // CheckerType is expected to be {set,map,multiset,multimap}.
85*9356374aSAndroid Build Coastguard Worker template <typename TreeType, typename CheckerType>
86*9356374aSAndroid Build Coastguard Worker class base_checker {
87*9356374aSAndroid Build Coastguard Worker  public:
88*9356374aSAndroid Build Coastguard Worker   using key_type = typename TreeType::key_type;
89*9356374aSAndroid Build Coastguard Worker   using value_type = typename TreeType::value_type;
90*9356374aSAndroid Build Coastguard Worker   using key_compare = typename TreeType::key_compare;
91*9356374aSAndroid Build Coastguard Worker   using pointer = typename TreeType::pointer;
92*9356374aSAndroid Build Coastguard Worker   using const_pointer = typename TreeType::const_pointer;
93*9356374aSAndroid Build Coastguard Worker   using reference = typename TreeType::reference;
94*9356374aSAndroid Build Coastguard Worker   using const_reference = typename TreeType::const_reference;
95*9356374aSAndroid Build Coastguard Worker   using size_type = typename TreeType::size_type;
96*9356374aSAndroid Build Coastguard Worker   using difference_type = typename TreeType::difference_type;
97*9356374aSAndroid Build Coastguard Worker   using iterator = typename TreeType::iterator;
98*9356374aSAndroid Build Coastguard Worker   using const_iterator = typename TreeType::const_iterator;
99*9356374aSAndroid Build Coastguard Worker   using reverse_iterator = typename TreeType::reverse_iterator;
100*9356374aSAndroid Build Coastguard Worker   using const_reverse_iterator = typename TreeType::const_reverse_iterator;
101*9356374aSAndroid Build Coastguard Worker 
102*9356374aSAndroid Build Coastguard Worker  public:
base_checker()103*9356374aSAndroid Build Coastguard Worker   base_checker() : const_tree_(tree_) {}
base_checker(const base_checker & other)104*9356374aSAndroid Build Coastguard Worker   base_checker(const base_checker &other)
105*9356374aSAndroid Build Coastguard Worker       : tree_(other.tree_), const_tree_(tree_), checker_(other.checker_) {}
106*9356374aSAndroid Build Coastguard Worker   template <typename InputIterator>
base_checker(InputIterator b,InputIterator e)107*9356374aSAndroid Build Coastguard Worker   base_checker(InputIterator b, InputIterator e)
108*9356374aSAndroid Build Coastguard Worker       : tree_(b, e), const_tree_(tree_), checker_(b, e) {}
109*9356374aSAndroid Build Coastguard Worker 
begin()110*9356374aSAndroid Build Coastguard Worker   iterator begin() { return tree_.begin(); }
begin() const111*9356374aSAndroid Build Coastguard Worker   const_iterator begin() const { return tree_.begin(); }
end()112*9356374aSAndroid Build Coastguard Worker   iterator end() { return tree_.end(); }
end() const113*9356374aSAndroid Build Coastguard Worker   const_iterator end() const { return tree_.end(); }
rbegin()114*9356374aSAndroid Build Coastguard Worker   reverse_iterator rbegin() { return tree_.rbegin(); }
rbegin() const115*9356374aSAndroid Build Coastguard Worker   const_reverse_iterator rbegin() const { return tree_.rbegin(); }
rend()116*9356374aSAndroid Build Coastguard Worker   reverse_iterator rend() { return tree_.rend(); }
rend() const117*9356374aSAndroid Build Coastguard Worker   const_reverse_iterator rend() const { return tree_.rend(); }
118*9356374aSAndroid Build Coastguard Worker 
119*9356374aSAndroid Build Coastguard Worker   template <typename IterType, typename CheckerIterType>
iter_check(IterType tree_iter,CheckerIterType checker_iter) const120*9356374aSAndroid Build Coastguard Worker   IterType iter_check(IterType tree_iter, CheckerIterType checker_iter) const {
121*9356374aSAndroid Build Coastguard Worker     if (tree_iter == tree_.end()) {
122*9356374aSAndroid Build Coastguard Worker       ABSL_INTERNAL_CHECK(checker_iter == checker_.end(),
123*9356374aSAndroid Build Coastguard Worker                           "Checker iterator not at end.");
124*9356374aSAndroid Build Coastguard Worker     } else {
125*9356374aSAndroid Build Coastguard Worker       CheckPairEquals(*tree_iter, *checker_iter);
126*9356374aSAndroid Build Coastguard Worker     }
127*9356374aSAndroid Build Coastguard Worker     return tree_iter;
128*9356374aSAndroid Build Coastguard Worker   }
129*9356374aSAndroid Build Coastguard Worker   template <typename IterType, typename CheckerIterType>
riter_check(IterType tree_iter,CheckerIterType checker_iter) const130*9356374aSAndroid Build Coastguard Worker   IterType riter_check(IterType tree_iter, CheckerIterType checker_iter) const {
131*9356374aSAndroid Build Coastguard Worker     if (tree_iter == tree_.rend()) {
132*9356374aSAndroid Build Coastguard Worker       ABSL_INTERNAL_CHECK(checker_iter == checker_.rend(),
133*9356374aSAndroid Build Coastguard Worker                           "Checker iterator not at rend.");
134*9356374aSAndroid Build Coastguard Worker     } else {
135*9356374aSAndroid Build Coastguard Worker       CheckPairEquals(*tree_iter, *checker_iter);
136*9356374aSAndroid Build Coastguard Worker     }
137*9356374aSAndroid Build Coastguard Worker     return tree_iter;
138*9356374aSAndroid Build Coastguard Worker   }
value_check(const value_type & v)139*9356374aSAndroid Build Coastguard Worker   void value_check(const value_type &v) {
140*9356374aSAndroid Build Coastguard Worker     typename KeyOfValue<typename TreeType::key_type,
141*9356374aSAndroid Build Coastguard Worker                         typename TreeType::value_type>::type key_of_value;
142*9356374aSAndroid Build Coastguard Worker     const key_type &key = key_of_value(v);
143*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*find(key), v);
144*9356374aSAndroid Build Coastguard Worker     lower_bound(key);
145*9356374aSAndroid Build Coastguard Worker     upper_bound(key);
146*9356374aSAndroid Build Coastguard Worker     equal_range(key);
147*9356374aSAndroid Build Coastguard Worker     contains(key);
148*9356374aSAndroid Build Coastguard Worker     count(key);
149*9356374aSAndroid Build Coastguard Worker   }
erase_check(const key_type & key)150*9356374aSAndroid Build Coastguard Worker   void erase_check(const key_type &key) {
151*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(tree_.contains(key));
152*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.find(key), const_tree_.end());
153*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(const_tree_.contains(key));
154*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(const_tree_.find(key), tree_.end());
155*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.equal_range(key).first,
156*9356374aSAndroid Build Coastguard Worker               const_tree_.equal_range(key).second);
157*9356374aSAndroid Build Coastguard Worker   }
158*9356374aSAndroid Build Coastguard Worker 
lower_bound(const key_type & key)159*9356374aSAndroid Build Coastguard Worker   iterator lower_bound(const key_type &key) {
160*9356374aSAndroid Build Coastguard Worker     return iter_check(tree_.lower_bound(key), checker_.lower_bound(key));
161*9356374aSAndroid Build Coastguard Worker   }
lower_bound(const key_type & key) const162*9356374aSAndroid Build Coastguard Worker   const_iterator lower_bound(const key_type &key) const {
163*9356374aSAndroid Build Coastguard Worker     return iter_check(tree_.lower_bound(key), checker_.lower_bound(key));
164*9356374aSAndroid Build Coastguard Worker   }
upper_bound(const key_type & key)165*9356374aSAndroid Build Coastguard Worker   iterator upper_bound(const key_type &key) {
166*9356374aSAndroid Build Coastguard Worker     return iter_check(tree_.upper_bound(key), checker_.upper_bound(key));
167*9356374aSAndroid Build Coastguard Worker   }
upper_bound(const key_type & key) const168*9356374aSAndroid Build Coastguard Worker   const_iterator upper_bound(const key_type &key) const {
169*9356374aSAndroid Build Coastguard Worker     return iter_check(tree_.upper_bound(key), checker_.upper_bound(key));
170*9356374aSAndroid Build Coastguard Worker   }
equal_range(const key_type & key)171*9356374aSAndroid Build Coastguard Worker   std::pair<iterator, iterator> equal_range(const key_type &key) {
172*9356374aSAndroid Build Coastguard Worker     std::pair<typename CheckerType::iterator, typename CheckerType::iterator>
173*9356374aSAndroid Build Coastguard Worker         checker_res = checker_.equal_range(key);
174*9356374aSAndroid Build Coastguard Worker     std::pair<iterator, iterator> tree_res = tree_.equal_range(key);
175*9356374aSAndroid Build Coastguard Worker     iter_check(tree_res.first, checker_res.first);
176*9356374aSAndroid Build Coastguard Worker     iter_check(tree_res.second, checker_res.second);
177*9356374aSAndroid Build Coastguard Worker     return tree_res;
178*9356374aSAndroid Build Coastguard Worker   }
equal_range(const key_type & key) const179*9356374aSAndroid Build Coastguard Worker   std::pair<const_iterator, const_iterator> equal_range(
180*9356374aSAndroid Build Coastguard Worker       const key_type &key) const {
181*9356374aSAndroid Build Coastguard Worker     std::pair<typename CheckerType::const_iterator,
182*9356374aSAndroid Build Coastguard Worker               typename CheckerType::const_iterator>
183*9356374aSAndroid Build Coastguard Worker         checker_res = checker_.equal_range(key);
184*9356374aSAndroid Build Coastguard Worker     std::pair<const_iterator, const_iterator> tree_res = tree_.equal_range(key);
185*9356374aSAndroid Build Coastguard Worker     iter_check(tree_res.first, checker_res.first);
186*9356374aSAndroid Build Coastguard Worker     iter_check(tree_res.second, checker_res.second);
187*9356374aSAndroid Build Coastguard Worker     return tree_res;
188*9356374aSAndroid Build Coastguard Worker   }
find(const key_type & key)189*9356374aSAndroid Build Coastguard Worker   iterator find(const key_type &key) {
190*9356374aSAndroid Build Coastguard Worker     return iter_check(tree_.find(key), checker_.find(key));
191*9356374aSAndroid Build Coastguard Worker   }
find(const key_type & key) const192*9356374aSAndroid Build Coastguard Worker   const_iterator find(const key_type &key) const {
193*9356374aSAndroid Build Coastguard Worker     return iter_check(tree_.find(key), checker_.find(key));
194*9356374aSAndroid Build Coastguard Worker   }
contains(const key_type & key) const195*9356374aSAndroid Build Coastguard Worker   bool contains(const key_type &key) const { return find(key) != end(); }
count(const key_type & key) const196*9356374aSAndroid Build Coastguard Worker   size_type count(const key_type &key) const {
197*9356374aSAndroid Build Coastguard Worker     size_type res = checker_.count(key);
198*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(res, tree_.count(key));
199*9356374aSAndroid Build Coastguard Worker     return res;
200*9356374aSAndroid Build Coastguard Worker   }
201*9356374aSAndroid Build Coastguard Worker 
operator =(const base_checker & other)202*9356374aSAndroid Build Coastguard Worker   base_checker &operator=(const base_checker &other) {
203*9356374aSAndroid Build Coastguard Worker     tree_ = other.tree_;
204*9356374aSAndroid Build Coastguard Worker     checker_ = other.checker_;
205*9356374aSAndroid Build Coastguard Worker     return *this;
206*9356374aSAndroid Build Coastguard Worker   }
207*9356374aSAndroid Build Coastguard Worker 
erase(const key_type & key)208*9356374aSAndroid Build Coastguard Worker   int erase(const key_type &key) {
209*9356374aSAndroid Build Coastguard Worker     int size = tree_.size();
210*9356374aSAndroid Build Coastguard Worker     int res = checker_.erase(key);
211*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(res, tree_.count(key));
212*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(res, tree_.erase(key));
213*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.count(key), 0);
214*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.size(), size - res);
215*9356374aSAndroid Build Coastguard Worker     erase_check(key);
216*9356374aSAndroid Build Coastguard Worker     return res;
217*9356374aSAndroid Build Coastguard Worker   }
erase(iterator iter)218*9356374aSAndroid Build Coastguard Worker   iterator erase(iterator iter) {
219*9356374aSAndroid Build Coastguard Worker     key_type key = iter.key();
220*9356374aSAndroid Build Coastguard Worker     int size = tree_.size();
221*9356374aSAndroid Build Coastguard Worker     int count = tree_.count(key);
222*9356374aSAndroid Build Coastguard Worker     auto checker_iter = checker_.lower_bound(key);
223*9356374aSAndroid Build Coastguard Worker     for (iterator tmp(tree_.lower_bound(key)); tmp != iter; ++tmp) {
224*9356374aSAndroid Build Coastguard Worker       ++checker_iter;
225*9356374aSAndroid Build Coastguard Worker     }
226*9356374aSAndroid Build Coastguard Worker     auto checker_next = checker_iter;
227*9356374aSAndroid Build Coastguard Worker     ++checker_next;
228*9356374aSAndroid Build Coastguard Worker     checker_.erase(checker_iter);
229*9356374aSAndroid Build Coastguard Worker     iter = tree_.erase(iter);
230*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.size(), checker_.size());
231*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.size(), size - 1);
232*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.count(key), count - 1);
233*9356374aSAndroid Build Coastguard Worker     if (count == 1) {
234*9356374aSAndroid Build Coastguard Worker       erase_check(key);
235*9356374aSAndroid Build Coastguard Worker     }
236*9356374aSAndroid Build Coastguard Worker     return iter_check(iter, checker_next);
237*9356374aSAndroid Build Coastguard Worker   }
238*9356374aSAndroid Build Coastguard Worker 
erase(iterator begin,iterator end)239*9356374aSAndroid Build Coastguard Worker   void erase(iterator begin, iterator end) {
240*9356374aSAndroid Build Coastguard Worker     int size = tree_.size();
241*9356374aSAndroid Build Coastguard Worker     int count = std::distance(begin, end);
242*9356374aSAndroid Build Coastguard Worker     auto checker_begin = checker_.lower_bound(begin.key());
243*9356374aSAndroid Build Coastguard Worker     for (iterator tmp(tree_.lower_bound(begin.key())); tmp != begin; ++tmp) {
244*9356374aSAndroid Build Coastguard Worker       ++checker_begin;
245*9356374aSAndroid Build Coastguard Worker     }
246*9356374aSAndroid Build Coastguard Worker     auto checker_end =
247*9356374aSAndroid Build Coastguard Worker         end == tree_.end() ? checker_.end() : checker_.lower_bound(end.key());
248*9356374aSAndroid Build Coastguard Worker     if (end != tree_.end()) {
249*9356374aSAndroid Build Coastguard Worker       for (iterator tmp(tree_.lower_bound(end.key())); tmp != end; ++tmp) {
250*9356374aSAndroid Build Coastguard Worker         ++checker_end;
251*9356374aSAndroid Build Coastguard Worker       }
252*9356374aSAndroid Build Coastguard Worker     }
253*9356374aSAndroid Build Coastguard Worker     const auto checker_ret = checker_.erase(checker_begin, checker_end);
254*9356374aSAndroid Build Coastguard Worker     const auto tree_ret = tree_.erase(begin, end);
255*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(std::distance(checker_.begin(), checker_ret),
256*9356374aSAndroid Build Coastguard Worker               std::distance(tree_.begin(), tree_ret));
257*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.size(), checker_.size());
258*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.size(), size - count);
259*9356374aSAndroid Build Coastguard Worker   }
260*9356374aSAndroid Build Coastguard Worker 
clear()261*9356374aSAndroid Build Coastguard Worker   void clear() {
262*9356374aSAndroid Build Coastguard Worker     tree_.clear();
263*9356374aSAndroid Build Coastguard Worker     checker_.clear();
264*9356374aSAndroid Build Coastguard Worker   }
swap(base_checker & other)265*9356374aSAndroid Build Coastguard Worker   void swap(base_checker &other) {
266*9356374aSAndroid Build Coastguard Worker     tree_.swap(other.tree_);
267*9356374aSAndroid Build Coastguard Worker     checker_.swap(other.checker_);
268*9356374aSAndroid Build Coastguard Worker   }
269*9356374aSAndroid Build Coastguard Worker 
verify() const270*9356374aSAndroid Build Coastguard Worker   void verify() const {
271*9356374aSAndroid Build Coastguard Worker     tree_.verify();
272*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.size(), checker_.size());
273*9356374aSAndroid Build Coastguard Worker 
274*9356374aSAndroid Build Coastguard Worker     // Move through the forward iterators using increment.
275*9356374aSAndroid Build Coastguard Worker     auto checker_iter = checker_.begin();
276*9356374aSAndroid Build Coastguard Worker     const_iterator tree_iter(tree_.begin());
277*9356374aSAndroid Build Coastguard Worker     for (; tree_iter != tree_.end(); ++tree_iter, ++checker_iter) {
278*9356374aSAndroid Build Coastguard Worker       CheckPairEquals(*tree_iter, *checker_iter);
279*9356374aSAndroid Build Coastguard Worker     }
280*9356374aSAndroid Build Coastguard Worker 
281*9356374aSAndroid Build Coastguard Worker     // Move through the forward iterators using decrement.
282*9356374aSAndroid Build Coastguard Worker     for (int n = tree_.size() - 1; n >= 0; --n) {
283*9356374aSAndroid Build Coastguard Worker       iter_check(tree_iter, checker_iter);
284*9356374aSAndroid Build Coastguard Worker       --tree_iter;
285*9356374aSAndroid Build Coastguard Worker       --checker_iter;
286*9356374aSAndroid Build Coastguard Worker     }
287*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_iter, tree_.begin());
288*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(checker_iter, checker_.begin());
289*9356374aSAndroid Build Coastguard Worker 
290*9356374aSAndroid Build Coastguard Worker     // Move through the reverse iterators using increment.
291*9356374aSAndroid Build Coastguard Worker     auto checker_riter = checker_.rbegin();
292*9356374aSAndroid Build Coastguard Worker     const_reverse_iterator tree_riter(tree_.rbegin());
293*9356374aSAndroid Build Coastguard Worker     for (; tree_riter != tree_.rend(); ++tree_riter, ++checker_riter) {
294*9356374aSAndroid Build Coastguard Worker       CheckPairEquals(*tree_riter, *checker_riter);
295*9356374aSAndroid Build Coastguard Worker     }
296*9356374aSAndroid Build Coastguard Worker 
297*9356374aSAndroid Build Coastguard Worker     // Move through the reverse iterators using decrement.
298*9356374aSAndroid Build Coastguard Worker     for (int n = tree_.size() - 1; n >= 0; --n) {
299*9356374aSAndroid Build Coastguard Worker       riter_check(tree_riter, checker_riter);
300*9356374aSAndroid Build Coastguard Worker       --tree_riter;
301*9356374aSAndroid Build Coastguard Worker       --checker_riter;
302*9356374aSAndroid Build Coastguard Worker     }
303*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_riter, tree_.rbegin());
304*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(checker_riter, checker_.rbegin());
305*9356374aSAndroid Build Coastguard Worker   }
306*9356374aSAndroid Build Coastguard Worker 
tree() const307*9356374aSAndroid Build Coastguard Worker   const TreeType &tree() const { return tree_; }
308*9356374aSAndroid Build Coastguard Worker 
size() const309*9356374aSAndroid Build Coastguard Worker   size_type size() const {
310*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.size(), checker_.size());
311*9356374aSAndroid Build Coastguard Worker     return tree_.size();
312*9356374aSAndroid Build Coastguard Worker   }
max_size() const313*9356374aSAndroid Build Coastguard Worker   size_type max_size() const { return tree_.max_size(); }
empty() const314*9356374aSAndroid Build Coastguard Worker   bool empty() const {
315*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_.empty(), checker_.empty());
316*9356374aSAndroid Build Coastguard Worker     return tree_.empty();
317*9356374aSAndroid Build Coastguard Worker   }
318*9356374aSAndroid Build Coastguard Worker 
319*9356374aSAndroid Build Coastguard Worker  protected:
320*9356374aSAndroid Build Coastguard Worker   TreeType tree_;
321*9356374aSAndroid Build Coastguard Worker   const TreeType &const_tree_;
322*9356374aSAndroid Build Coastguard Worker   CheckerType checker_;
323*9356374aSAndroid Build Coastguard Worker };
324*9356374aSAndroid Build Coastguard Worker 
325*9356374aSAndroid Build Coastguard Worker namespace {
326*9356374aSAndroid Build Coastguard Worker // A checker for unique sorted associative containers. TreeType is expected to
327*9356374aSAndroid Build Coastguard Worker // be btree_{set,map} and CheckerType is expected to be {set,map}.
328*9356374aSAndroid Build Coastguard Worker template <typename TreeType, typename CheckerType>
329*9356374aSAndroid Build Coastguard Worker class unique_checker : public base_checker<TreeType, CheckerType> {
330*9356374aSAndroid Build Coastguard Worker   using super_type = base_checker<TreeType, CheckerType>;
331*9356374aSAndroid Build Coastguard Worker 
332*9356374aSAndroid Build Coastguard Worker  public:
333*9356374aSAndroid Build Coastguard Worker   using iterator = typename super_type::iterator;
334*9356374aSAndroid Build Coastguard Worker   using value_type = typename super_type::value_type;
335*9356374aSAndroid Build Coastguard Worker 
336*9356374aSAndroid Build Coastguard Worker  public:
unique_checker()337*9356374aSAndroid Build Coastguard Worker   unique_checker() : super_type() {}
unique_checker(const unique_checker & other)338*9356374aSAndroid Build Coastguard Worker   unique_checker(const unique_checker &other) : super_type(other) {}
339*9356374aSAndroid Build Coastguard Worker   template <class InputIterator>
unique_checker(InputIterator b,InputIterator e)340*9356374aSAndroid Build Coastguard Worker   unique_checker(InputIterator b, InputIterator e) : super_type(b, e) {}
341*9356374aSAndroid Build Coastguard Worker   unique_checker &operator=(const unique_checker &) = default;
342*9356374aSAndroid Build Coastguard Worker 
343*9356374aSAndroid Build Coastguard Worker   // Insertion routines.
insert(const value_type & v)344*9356374aSAndroid Build Coastguard Worker   std::pair<iterator, bool> insert(const value_type &v) {
345*9356374aSAndroid Build Coastguard Worker     int size = this->tree_.size();
346*9356374aSAndroid Build Coastguard Worker     std::pair<typename CheckerType::iterator, bool> checker_res =
347*9356374aSAndroid Build Coastguard Worker         this->checker_.insert(v);
348*9356374aSAndroid Build Coastguard Worker     std::pair<iterator, bool> tree_res = this->tree_.insert(v);
349*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*tree_res.first, *checker_res.first);
350*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tree_res.second, checker_res.second);
351*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(this->tree_.size(), this->checker_.size());
352*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(this->tree_.size(), size + tree_res.second);
353*9356374aSAndroid Build Coastguard Worker     return tree_res;
354*9356374aSAndroid Build Coastguard Worker   }
insert(iterator position,const value_type & v)355*9356374aSAndroid Build Coastguard Worker   iterator insert(iterator position, const value_type &v) {
356*9356374aSAndroid Build Coastguard Worker     int size = this->tree_.size();
357*9356374aSAndroid Build Coastguard Worker     std::pair<typename CheckerType::iterator, bool> checker_res =
358*9356374aSAndroid Build Coastguard Worker         this->checker_.insert(v);
359*9356374aSAndroid Build Coastguard Worker     iterator tree_res = this->tree_.insert(position, v);
360*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*tree_res, *checker_res.first);
361*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(this->tree_.size(), this->checker_.size());
362*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(this->tree_.size(), size + checker_res.second);
363*9356374aSAndroid Build Coastguard Worker     return tree_res;
364*9356374aSAndroid Build Coastguard Worker   }
365*9356374aSAndroid Build Coastguard Worker   template <typename InputIterator>
insert(InputIterator b,InputIterator e)366*9356374aSAndroid Build Coastguard Worker   void insert(InputIterator b, InputIterator e) {
367*9356374aSAndroid Build Coastguard Worker     for (; b != e; ++b) {
368*9356374aSAndroid Build Coastguard Worker       insert(*b);
369*9356374aSAndroid Build Coastguard Worker     }
370*9356374aSAndroid Build Coastguard Worker   }
371*9356374aSAndroid Build Coastguard Worker };
372*9356374aSAndroid Build Coastguard Worker 
373*9356374aSAndroid Build Coastguard Worker // A checker for multiple sorted associative containers. TreeType is expected
374*9356374aSAndroid Build Coastguard Worker // to be btree_{multiset,multimap} and CheckerType is expected to be
375*9356374aSAndroid Build Coastguard Worker // {multiset,multimap}.
376*9356374aSAndroid Build Coastguard Worker template <typename TreeType, typename CheckerType>
377*9356374aSAndroid Build Coastguard Worker class multi_checker : public base_checker<TreeType, CheckerType> {
378*9356374aSAndroid Build Coastguard Worker   using super_type = base_checker<TreeType, CheckerType>;
379*9356374aSAndroid Build Coastguard Worker 
380*9356374aSAndroid Build Coastguard Worker  public:
381*9356374aSAndroid Build Coastguard Worker   using iterator = typename super_type::iterator;
382*9356374aSAndroid Build Coastguard Worker   using value_type = typename super_type::value_type;
383*9356374aSAndroid Build Coastguard Worker 
384*9356374aSAndroid Build Coastguard Worker  public:
multi_checker()385*9356374aSAndroid Build Coastguard Worker   multi_checker() : super_type() {}
multi_checker(const multi_checker & other)386*9356374aSAndroid Build Coastguard Worker   multi_checker(const multi_checker &other) : super_type(other) {}
387*9356374aSAndroid Build Coastguard Worker   template <class InputIterator>
multi_checker(InputIterator b,InputIterator e)388*9356374aSAndroid Build Coastguard Worker   multi_checker(InputIterator b, InputIterator e) : super_type(b, e) {}
389*9356374aSAndroid Build Coastguard Worker   multi_checker &operator=(const multi_checker &) = default;
390*9356374aSAndroid Build Coastguard Worker 
391*9356374aSAndroid Build Coastguard Worker   // Insertion routines.
insert(const value_type & v)392*9356374aSAndroid Build Coastguard Worker   iterator insert(const value_type &v) {
393*9356374aSAndroid Build Coastguard Worker     int size = this->tree_.size();
394*9356374aSAndroid Build Coastguard Worker     auto checker_res = this->checker_.insert(v);
395*9356374aSAndroid Build Coastguard Worker     iterator tree_res = this->tree_.insert(v);
396*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*tree_res, *checker_res);
397*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(this->tree_.size(), this->checker_.size());
398*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(this->tree_.size(), size + 1);
399*9356374aSAndroid Build Coastguard Worker     return tree_res;
400*9356374aSAndroid Build Coastguard Worker   }
insert(iterator position,const value_type & v)401*9356374aSAndroid Build Coastguard Worker   iterator insert(iterator position, const value_type &v) {
402*9356374aSAndroid Build Coastguard Worker     int size = this->tree_.size();
403*9356374aSAndroid Build Coastguard Worker     auto checker_res = this->checker_.insert(v);
404*9356374aSAndroid Build Coastguard Worker     iterator tree_res = this->tree_.insert(position, v);
405*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*tree_res, *checker_res);
406*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(this->tree_.size(), this->checker_.size());
407*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(this->tree_.size(), size + 1);
408*9356374aSAndroid Build Coastguard Worker     return tree_res;
409*9356374aSAndroid Build Coastguard Worker   }
410*9356374aSAndroid Build Coastguard Worker   template <typename InputIterator>
insert(InputIterator b,InputIterator e)411*9356374aSAndroid Build Coastguard Worker   void insert(InputIterator b, InputIterator e) {
412*9356374aSAndroid Build Coastguard Worker     for (; b != e; ++b) {
413*9356374aSAndroid Build Coastguard Worker       insert(*b);
414*9356374aSAndroid Build Coastguard Worker     }
415*9356374aSAndroid Build Coastguard Worker   }
416*9356374aSAndroid Build Coastguard Worker };
417*9356374aSAndroid Build Coastguard Worker 
418*9356374aSAndroid Build Coastguard Worker template <typename T, typename V>
DoTest(const char * name,T * b,const std::vector<V> & values)419*9356374aSAndroid Build Coastguard Worker void DoTest(const char *name, T *b, const std::vector<V> &values) {
420*9356374aSAndroid Build Coastguard Worker   typename KeyOfValue<typename T::key_type, V>::type key_of_value;
421*9356374aSAndroid Build Coastguard Worker 
422*9356374aSAndroid Build Coastguard Worker   T &mutable_b = *b;
423*9356374aSAndroid Build Coastguard Worker   const T &const_b = *b;
424*9356374aSAndroid Build Coastguard Worker 
425*9356374aSAndroid Build Coastguard Worker   // Test insert.
426*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); ++i) {
427*9356374aSAndroid Build Coastguard Worker     mutable_b.insert(values[i]);
428*9356374aSAndroid Build Coastguard Worker     mutable_b.value_check(values[i]);
429*9356374aSAndroid Build Coastguard Worker   }
430*9356374aSAndroid Build Coastguard Worker   ASSERT_EQ(mutable_b.size(), values.size());
431*9356374aSAndroid Build Coastguard Worker 
432*9356374aSAndroid Build Coastguard Worker   const_b.verify();
433*9356374aSAndroid Build Coastguard Worker 
434*9356374aSAndroid Build Coastguard Worker   // Test copy constructor.
435*9356374aSAndroid Build Coastguard Worker   T b_copy(const_b);
436*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_copy.size(), const_b.size());
437*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); ++i) {
438*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*b_copy.find(key_of_value(values[i])), values[i]);
439*9356374aSAndroid Build Coastguard Worker   }
440*9356374aSAndroid Build Coastguard Worker 
441*9356374aSAndroid Build Coastguard Worker   // Test range constructor.
442*9356374aSAndroid Build Coastguard Worker   T b_range(const_b.begin(), const_b.end());
443*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_range.size(), const_b.size());
444*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); ++i) {
445*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*b_range.find(key_of_value(values[i])), values[i]);
446*9356374aSAndroid Build Coastguard Worker   }
447*9356374aSAndroid Build Coastguard Worker 
448*9356374aSAndroid Build Coastguard Worker   // Test range insertion for values that already exist.
449*9356374aSAndroid Build Coastguard Worker   b_range.insert(b_copy.begin(), b_copy.end());
450*9356374aSAndroid Build Coastguard Worker   b_range.verify();
451*9356374aSAndroid Build Coastguard Worker 
452*9356374aSAndroid Build Coastguard Worker   // Test range insertion for new values.
453*9356374aSAndroid Build Coastguard Worker   b_range.clear();
454*9356374aSAndroid Build Coastguard Worker   b_range.insert(b_copy.begin(), b_copy.end());
455*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_range.size(), b_copy.size());
456*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); ++i) {
457*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*b_range.find(key_of_value(values[i])), values[i]);
458*9356374aSAndroid Build Coastguard Worker   }
459*9356374aSAndroid Build Coastguard Worker 
460*9356374aSAndroid Build Coastguard Worker   // Test assignment to self. Nothing should change.
461*9356374aSAndroid Build Coastguard Worker   b_range.operator=(b_range);
462*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_range.size(), b_copy.size());
463*9356374aSAndroid Build Coastguard Worker 
464*9356374aSAndroid Build Coastguard Worker   // Test assignment of new values.
465*9356374aSAndroid Build Coastguard Worker   b_range.clear();
466*9356374aSAndroid Build Coastguard Worker   b_range = b_copy;
467*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_range.size(), b_copy.size());
468*9356374aSAndroid Build Coastguard Worker 
469*9356374aSAndroid Build Coastguard Worker   // Test swap.
470*9356374aSAndroid Build Coastguard Worker   b_range.clear();
471*9356374aSAndroid Build Coastguard Worker   b_range.swap(b_copy);
472*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_copy.size(), 0);
473*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_range.size(), const_b.size());
474*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); ++i) {
475*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*b_range.find(key_of_value(values[i])), values[i]);
476*9356374aSAndroid Build Coastguard Worker   }
477*9356374aSAndroid Build Coastguard Worker   b_range.swap(b_copy);
478*9356374aSAndroid Build Coastguard Worker 
479*9356374aSAndroid Build Coastguard Worker   // Test non-member function swap.
480*9356374aSAndroid Build Coastguard Worker   swap(b_range, b_copy);
481*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_copy.size(), 0);
482*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b_range.size(), const_b.size());
483*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); ++i) {
484*9356374aSAndroid Build Coastguard Worker     CheckPairEquals(*b_range.find(key_of_value(values[i])), values[i]);
485*9356374aSAndroid Build Coastguard Worker   }
486*9356374aSAndroid Build Coastguard Worker   swap(b_range, b_copy);
487*9356374aSAndroid Build Coastguard Worker 
488*9356374aSAndroid Build Coastguard Worker   // Test erase via values.
489*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); ++i) {
490*9356374aSAndroid Build Coastguard Worker     mutable_b.erase(key_of_value(values[i]));
491*9356374aSAndroid Build Coastguard Worker     // Erasing a non-existent key should have no effect.
492*9356374aSAndroid Build Coastguard Worker     ASSERT_EQ(mutable_b.erase(key_of_value(values[i])), 0);
493*9356374aSAndroid Build Coastguard Worker   }
494*9356374aSAndroid Build Coastguard Worker 
495*9356374aSAndroid Build Coastguard Worker   const_b.verify();
496*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_b.size(), 0);
497*9356374aSAndroid Build Coastguard Worker 
498*9356374aSAndroid Build Coastguard Worker   // Test erase via iterators.
499*9356374aSAndroid Build Coastguard Worker   mutable_b = b_copy;
500*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); ++i) {
501*9356374aSAndroid Build Coastguard Worker     mutable_b.erase(mutable_b.find(key_of_value(values[i])));
502*9356374aSAndroid Build Coastguard Worker   }
503*9356374aSAndroid Build Coastguard Worker 
504*9356374aSAndroid Build Coastguard Worker   const_b.verify();
505*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_b.size(), 0);
506*9356374aSAndroid Build Coastguard Worker 
507*9356374aSAndroid Build Coastguard Worker   // Test insert with hint.
508*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size(); i++) {
509*9356374aSAndroid Build Coastguard Worker     mutable_b.insert(mutable_b.upper_bound(key_of_value(values[i])), values[i]);
510*9356374aSAndroid Build Coastguard Worker   }
511*9356374aSAndroid Build Coastguard Worker 
512*9356374aSAndroid Build Coastguard Worker   const_b.verify();
513*9356374aSAndroid Build Coastguard Worker 
514*9356374aSAndroid Build Coastguard Worker   // Test range erase.
515*9356374aSAndroid Build Coastguard Worker   mutable_b.erase(mutable_b.begin(), mutable_b.end());
516*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mutable_b.size(), 0);
517*9356374aSAndroid Build Coastguard Worker   const_b.verify();
518*9356374aSAndroid Build Coastguard Worker 
519*9356374aSAndroid Build Coastguard Worker   // First half.
520*9356374aSAndroid Build Coastguard Worker   mutable_b = b_copy;
521*9356374aSAndroid Build Coastguard Worker   typename T::iterator mutable_iter_end = mutable_b.begin();
522*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size() / 2; ++i) ++mutable_iter_end;
523*9356374aSAndroid Build Coastguard Worker   mutable_b.erase(mutable_b.begin(), mutable_iter_end);
524*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mutable_b.size(), values.size() - values.size() / 2);
525*9356374aSAndroid Build Coastguard Worker   const_b.verify();
526*9356374aSAndroid Build Coastguard Worker 
527*9356374aSAndroid Build Coastguard Worker   // Second half.
528*9356374aSAndroid Build Coastguard Worker   mutable_b = b_copy;
529*9356374aSAndroid Build Coastguard Worker   typename T::iterator mutable_iter_begin = mutable_b.begin();
530*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size() / 2; ++i) ++mutable_iter_begin;
531*9356374aSAndroid Build Coastguard Worker   mutable_b.erase(mutable_iter_begin, mutable_b.end());
532*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mutable_b.size(), values.size() / 2);
533*9356374aSAndroid Build Coastguard Worker   const_b.verify();
534*9356374aSAndroid Build Coastguard Worker 
535*9356374aSAndroid Build Coastguard Worker   // Second quarter.
536*9356374aSAndroid Build Coastguard Worker   mutable_b = b_copy;
537*9356374aSAndroid Build Coastguard Worker   mutable_iter_begin = mutable_b.begin();
538*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size() / 4; ++i) ++mutable_iter_begin;
539*9356374aSAndroid Build Coastguard Worker   mutable_iter_end = mutable_iter_begin;
540*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < values.size() / 4; ++i) ++mutable_iter_end;
541*9356374aSAndroid Build Coastguard Worker   mutable_b.erase(mutable_iter_begin, mutable_iter_end);
542*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mutable_b.size(), values.size() - values.size() / 4);
543*9356374aSAndroid Build Coastguard Worker   const_b.verify();
544*9356374aSAndroid Build Coastguard Worker 
545*9356374aSAndroid Build Coastguard Worker   mutable_b.clear();
546*9356374aSAndroid Build Coastguard Worker }
547*9356374aSAndroid Build Coastguard Worker 
548*9356374aSAndroid Build Coastguard Worker template <typename T>
ConstTest()549*9356374aSAndroid Build Coastguard Worker void ConstTest() {
550*9356374aSAndroid Build Coastguard Worker   using value_type = typename T::value_type;
551*9356374aSAndroid Build Coastguard Worker   typename KeyOfValue<typename T::key_type, value_type>::type key_of_value;
552*9356374aSAndroid Build Coastguard Worker 
553*9356374aSAndroid Build Coastguard Worker   T mutable_b;
554*9356374aSAndroid Build Coastguard Worker   const T &const_b = mutable_b;
555*9356374aSAndroid Build Coastguard Worker 
556*9356374aSAndroid Build Coastguard Worker   // Insert a single value into the container and test looking it up.
557*9356374aSAndroid Build Coastguard Worker   value_type value = Generator<value_type>(2)(2);
558*9356374aSAndroid Build Coastguard Worker   mutable_b.insert(value);
559*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(mutable_b.contains(key_of_value(value)));
560*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(mutable_b.find(key_of_value(value)), const_b.end());
561*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(const_b.contains(key_of_value(value)));
562*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(const_b.find(key_of_value(value)), mutable_b.end());
563*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*const_b.lower_bound(key_of_value(value)), value);
564*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_b.upper_bound(key_of_value(value)), const_b.end());
565*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*const_b.equal_range(key_of_value(value)).first, value);
566*9356374aSAndroid Build Coastguard Worker 
567*9356374aSAndroid Build Coastguard Worker   // We can only create a non-const iterator from a non-const container.
568*9356374aSAndroid Build Coastguard Worker   typename T::iterator mutable_iter(mutable_b.begin());
569*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mutable_iter, const_b.begin());
570*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(mutable_iter, const_b.end());
571*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_b.begin(), mutable_iter);
572*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(const_b.end(), mutable_iter);
573*9356374aSAndroid Build Coastguard Worker   typename T::reverse_iterator mutable_riter(mutable_b.rbegin());
574*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mutable_riter, const_b.rbegin());
575*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(mutable_riter, const_b.rend());
576*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_b.rbegin(), mutable_riter);
577*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(const_b.rend(), mutable_riter);
578*9356374aSAndroid Build Coastguard Worker 
579*9356374aSAndroid Build Coastguard Worker   // We can create a const iterator from a non-const iterator.
580*9356374aSAndroid Build Coastguard Worker   typename T::const_iterator const_iter(mutable_iter);
581*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_iter, mutable_b.begin());
582*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(const_iter, mutable_b.end());
583*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mutable_b.begin(), const_iter);
584*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(mutable_b.end(), const_iter);
585*9356374aSAndroid Build Coastguard Worker   typename T::const_reverse_iterator const_riter(mutable_riter);
586*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_riter, mutable_b.rbegin());
587*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(const_riter, mutable_b.rend());
588*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mutable_b.rbegin(), const_riter);
589*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(mutable_b.rend(), const_riter);
590*9356374aSAndroid Build Coastguard Worker 
591*9356374aSAndroid Build Coastguard Worker   // Make sure various methods can be invoked on a const container.
592*9356374aSAndroid Build Coastguard Worker   const_b.verify();
593*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(!const_b.empty());
594*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_b.size(), 1);
595*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(const_b.max_size(), 0);
596*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(const_b.contains(key_of_value(value)));
597*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_b.count(key_of_value(value)), 1);
598*9356374aSAndroid Build Coastguard Worker }
599*9356374aSAndroid Build Coastguard Worker 
600*9356374aSAndroid Build Coastguard Worker template <typename T, typename C>
BtreeTest()601*9356374aSAndroid Build Coastguard Worker void BtreeTest() {
602*9356374aSAndroid Build Coastguard Worker   ConstTest<T>();
603*9356374aSAndroid Build Coastguard Worker 
604*9356374aSAndroid Build Coastguard Worker   using V = typename remove_pair_const<typename T::value_type>::type;
605*9356374aSAndroid Build Coastguard Worker   const std::vector<V> random_values = GenerateValuesWithSeed<V>(
606*9356374aSAndroid Build Coastguard Worker       absl::GetFlag(FLAGS_test_values), 4 * absl::GetFlag(FLAGS_test_values),
607*9356374aSAndroid Build Coastguard Worker       GTEST_FLAG_GET(random_seed));
608*9356374aSAndroid Build Coastguard Worker 
609*9356374aSAndroid Build Coastguard Worker   unique_checker<T, C> container;
610*9356374aSAndroid Build Coastguard Worker 
611*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in sorted order.
612*9356374aSAndroid Build Coastguard Worker   std::vector<V> sorted_values(random_values);
613*9356374aSAndroid Build Coastguard Worker   std::sort(sorted_values.begin(), sorted_values.end());
614*9356374aSAndroid Build Coastguard Worker   DoTest("sorted:    ", &container, sorted_values);
615*9356374aSAndroid Build Coastguard Worker 
616*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in reverse sorted order.
617*9356374aSAndroid Build Coastguard Worker   std::reverse(sorted_values.begin(), sorted_values.end());
618*9356374aSAndroid Build Coastguard Worker   DoTest("rsorted:   ", &container, sorted_values);
619*9356374aSAndroid Build Coastguard Worker 
620*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in random order.
621*9356374aSAndroid Build Coastguard Worker   DoTest("random:    ", &container, random_values);
622*9356374aSAndroid Build Coastguard Worker }
623*9356374aSAndroid Build Coastguard Worker 
624*9356374aSAndroid Build Coastguard Worker template <typename T, typename C>
BtreeMultiTest()625*9356374aSAndroid Build Coastguard Worker void BtreeMultiTest() {
626*9356374aSAndroid Build Coastguard Worker   ConstTest<T>();
627*9356374aSAndroid Build Coastguard Worker 
628*9356374aSAndroid Build Coastguard Worker   using V = typename remove_pair_const<typename T::value_type>::type;
629*9356374aSAndroid Build Coastguard Worker   const std::vector<V> random_values = GenerateValuesWithSeed<V>(
630*9356374aSAndroid Build Coastguard Worker       absl::GetFlag(FLAGS_test_values), 4 * absl::GetFlag(FLAGS_test_values),
631*9356374aSAndroid Build Coastguard Worker       GTEST_FLAG_GET(random_seed));
632*9356374aSAndroid Build Coastguard Worker 
633*9356374aSAndroid Build Coastguard Worker   multi_checker<T, C> container;
634*9356374aSAndroid Build Coastguard Worker 
635*9356374aSAndroid Build Coastguard Worker   // Test keys in sorted order.
636*9356374aSAndroid Build Coastguard Worker   std::vector<V> sorted_values(random_values);
637*9356374aSAndroid Build Coastguard Worker   std::sort(sorted_values.begin(), sorted_values.end());
638*9356374aSAndroid Build Coastguard Worker   DoTest("sorted:    ", &container, sorted_values);
639*9356374aSAndroid Build Coastguard Worker 
640*9356374aSAndroid Build Coastguard Worker   // Test keys in reverse sorted order.
641*9356374aSAndroid Build Coastguard Worker   std::reverse(sorted_values.begin(), sorted_values.end());
642*9356374aSAndroid Build Coastguard Worker   DoTest("rsorted:   ", &container, sorted_values);
643*9356374aSAndroid Build Coastguard Worker 
644*9356374aSAndroid Build Coastguard Worker   // Test keys in random order.
645*9356374aSAndroid Build Coastguard Worker   DoTest("random:    ", &container, random_values);
646*9356374aSAndroid Build Coastguard Worker 
647*9356374aSAndroid Build Coastguard Worker   // Test keys in random order w/ duplicates.
648*9356374aSAndroid Build Coastguard Worker   std::vector<V> duplicate_values(random_values);
649*9356374aSAndroid Build Coastguard Worker   duplicate_values.insert(duplicate_values.end(), random_values.begin(),
650*9356374aSAndroid Build Coastguard Worker                           random_values.end());
651*9356374aSAndroid Build Coastguard Worker   DoTest("duplicates:", &container, duplicate_values);
652*9356374aSAndroid Build Coastguard Worker 
653*9356374aSAndroid Build Coastguard Worker   // Test all identical keys.
654*9356374aSAndroid Build Coastguard Worker   std::vector<V> identical_values(100);
655*9356374aSAndroid Build Coastguard Worker   std::fill(identical_values.begin(), identical_values.end(),
656*9356374aSAndroid Build Coastguard Worker             Generator<V>(2)(2));
657*9356374aSAndroid Build Coastguard Worker   DoTest("identical: ", &container, identical_values);
658*9356374aSAndroid Build Coastguard Worker }
659*9356374aSAndroid Build Coastguard Worker 
660*9356374aSAndroid Build Coastguard Worker template <typename T>
BtreeMapTest()661*9356374aSAndroid Build Coastguard Worker void BtreeMapTest() {
662*9356374aSAndroid Build Coastguard Worker   using value_type = typename T::value_type;
663*9356374aSAndroid Build Coastguard Worker   using mapped_type = typename T::mapped_type;
664*9356374aSAndroid Build Coastguard Worker 
665*9356374aSAndroid Build Coastguard Worker   mapped_type m = Generator<mapped_type>(0)(0);
666*9356374aSAndroid Build Coastguard Worker   (void)m;
667*9356374aSAndroid Build Coastguard Worker 
668*9356374aSAndroid Build Coastguard Worker   T b;
669*9356374aSAndroid Build Coastguard Worker 
670*9356374aSAndroid Build Coastguard Worker   // Verify we can insert using operator[].
671*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 1000; i++) {
672*9356374aSAndroid Build Coastguard Worker     value_type v = Generator<value_type>(1000)(i);
673*9356374aSAndroid Build Coastguard Worker     b[v.first] = v.second;
674*9356374aSAndroid Build Coastguard Worker   }
675*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b.size(), 1000);
676*9356374aSAndroid Build Coastguard Worker 
677*9356374aSAndroid Build Coastguard Worker   // Test whether we can use the "->" operator on iterators and
678*9356374aSAndroid Build Coastguard Worker   // reverse_iterators. This stresses the btree_map_params::pair_pointer
679*9356374aSAndroid Build Coastguard Worker   // mechanism.
680*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b.begin()->first, Generator<value_type>(1000)(0).first);
681*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b.begin()->second, Generator<value_type>(1000)(0).second);
682*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b.rbegin()->first, Generator<value_type>(1000)(999).first);
683*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(b.rbegin()->second, Generator<value_type>(1000)(999).second);
684*9356374aSAndroid Build Coastguard Worker }
685*9356374aSAndroid Build Coastguard Worker 
686*9356374aSAndroid Build Coastguard Worker template <typename T>
BtreeMultiMapTest()687*9356374aSAndroid Build Coastguard Worker void BtreeMultiMapTest() {
688*9356374aSAndroid Build Coastguard Worker   using mapped_type = typename T::mapped_type;
689*9356374aSAndroid Build Coastguard Worker   mapped_type m = Generator<mapped_type>(0)(0);
690*9356374aSAndroid Build Coastguard Worker   (void)m;
691*9356374aSAndroid Build Coastguard Worker }
692*9356374aSAndroid Build Coastguard Worker 
693*9356374aSAndroid Build Coastguard Worker template <typename K, int N = 256>
SetTest()694*9356374aSAndroid Build Coastguard Worker void SetTest() {
695*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(
696*9356374aSAndroid Build Coastguard Worker       sizeof(absl::btree_set<K>),
697*9356374aSAndroid Build Coastguard Worker       2 * sizeof(void *) + sizeof(typename absl::btree_set<K>::size_type));
698*9356374aSAndroid Build Coastguard Worker   using BtreeSet = absl::btree_set<K>;
699*9356374aSAndroid Build Coastguard Worker   BtreeTest<BtreeSet, std::set<K>>();
700*9356374aSAndroid Build Coastguard Worker }
701*9356374aSAndroid Build Coastguard Worker 
702*9356374aSAndroid Build Coastguard Worker template <typename K, int N = 256>
MapTest()703*9356374aSAndroid Build Coastguard Worker void MapTest() {
704*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(
705*9356374aSAndroid Build Coastguard Worker       sizeof(absl::btree_map<K, K>),
706*9356374aSAndroid Build Coastguard Worker       2 * sizeof(void *) + sizeof(typename absl::btree_map<K, K>::size_type));
707*9356374aSAndroid Build Coastguard Worker   using BtreeMap = absl::btree_map<K, K>;
708*9356374aSAndroid Build Coastguard Worker   BtreeTest<BtreeMap, std::map<K, K>>();
709*9356374aSAndroid Build Coastguard Worker   BtreeMapTest<BtreeMap>();
710*9356374aSAndroid Build Coastguard Worker }
711*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,set_int32)712*9356374aSAndroid Build Coastguard Worker TEST(Btree, set_int32) { SetTest<int32_t>(); }
TEST(Btree,set_string)713*9356374aSAndroid Build Coastguard Worker TEST(Btree, set_string) { SetTest<std::string>(); }
TEST(Btree,set_cord)714*9356374aSAndroid Build Coastguard Worker TEST(Btree, set_cord) { SetTest<absl::Cord>(); }
TEST(Btree,map_int32)715*9356374aSAndroid Build Coastguard Worker TEST(Btree, map_int32) { MapTest<int32_t>(); }
TEST(Btree,map_string)716*9356374aSAndroid Build Coastguard Worker TEST(Btree, map_string) { MapTest<std::string>(); }
TEST(Btree,map_cord)717*9356374aSAndroid Build Coastguard Worker TEST(Btree, map_cord) { MapTest<absl::Cord>(); }
718*9356374aSAndroid Build Coastguard Worker 
719*9356374aSAndroid Build Coastguard Worker template <typename K, int N = 256>
MultiSetTest()720*9356374aSAndroid Build Coastguard Worker void MultiSetTest() {
721*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(
722*9356374aSAndroid Build Coastguard Worker       sizeof(absl::btree_multiset<K>),
723*9356374aSAndroid Build Coastguard Worker       2 * sizeof(void *) + sizeof(typename absl::btree_multiset<K>::size_type));
724*9356374aSAndroid Build Coastguard Worker   using BtreeMSet = absl::btree_multiset<K>;
725*9356374aSAndroid Build Coastguard Worker   BtreeMultiTest<BtreeMSet, std::multiset<K>>();
726*9356374aSAndroid Build Coastguard Worker }
727*9356374aSAndroid Build Coastguard Worker 
728*9356374aSAndroid Build Coastguard Worker template <typename K, int N = 256>
MultiMapTest()729*9356374aSAndroid Build Coastguard Worker void MultiMapTest() {
730*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(sizeof(absl::btree_multimap<K, K>),
731*9356374aSAndroid Build Coastguard Worker             2 * sizeof(void *) +
732*9356374aSAndroid Build Coastguard Worker                 sizeof(typename absl::btree_multimap<K, K>::size_type));
733*9356374aSAndroid Build Coastguard Worker   using BtreeMMap = absl::btree_multimap<K, K>;
734*9356374aSAndroid Build Coastguard Worker   BtreeMultiTest<BtreeMMap, std::multimap<K, K>>();
735*9356374aSAndroid Build Coastguard Worker   BtreeMultiMapTest<BtreeMMap>();
736*9356374aSAndroid Build Coastguard Worker }
737*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,multiset_int32)738*9356374aSAndroid Build Coastguard Worker TEST(Btree, multiset_int32) { MultiSetTest<int32_t>(); }
TEST(Btree,multiset_string)739*9356374aSAndroid Build Coastguard Worker TEST(Btree, multiset_string) { MultiSetTest<std::string>(); }
TEST(Btree,multiset_cord)740*9356374aSAndroid Build Coastguard Worker TEST(Btree, multiset_cord) { MultiSetTest<absl::Cord>(); }
TEST(Btree,multimap_int32)741*9356374aSAndroid Build Coastguard Worker TEST(Btree, multimap_int32) { MultiMapTest<int32_t>(); }
TEST(Btree,multimap_string)742*9356374aSAndroid Build Coastguard Worker TEST(Btree, multimap_string) { MultiMapTest<std::string>(); }
TEST(Btree,multimap_cord)743*9356374aSAndroid Build Coastguard Worker TEST(Btree, multimap_cord) { MultiMapTest<absl::Cord>(); }
744*9356374aSAndroid Build Coastguard Worker 
745*9356374aSAndroid Build Coastguard Worker struct CompareIntToString {
operator ()absl::container_internal::__anon7e8713fe0211::CompareIntToString746*9356374aSAndroid Build Coastguard Worker   bool operator()(const std::string &a, const std::string &b) const {
747*9356374aSAndroid Build Coastguard Worker     return a < b;
748*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0211::CompareIntToString749*9356374aSAndroid Build Coastguard Worker   bool operator()(const std::string &a, int b) const {
750*9356374aSAndroid Build Coastguard Worker     return a < absl::StrCat(b);
751*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0211::CompareIntToString752*9356374aSAndroid Build Coastguard Worker   bool operator()(int a, const std::string &b) const {
753*9356374aSAndroid Build Coastguard Worker     return absl::StrCat(a) < b;
754*9356374aSAndroid Build Coastguard Worker   }
755*9356374aSAndroid Build Coastguard Worker   using is_transparent = void;
756*9356374aSAndroid Build Coastguard Worker };
757*9356374aSAndroid Build Coastguard Worker 
758*9356374aSAndroid Build Coastguard Worker struct NonTransparentCompare {
759*9356374aSAndroid Build Coastguard Worker   template <typename T, typename U>
operator ()absl::container_internal::__anon7e8713fe0211::NonTransparentCompare760*9356374aSAndroid Build Coastguard Worker   bool operator()(const T &t, const U &u) const {
761*9356374aSAndroid Build Coastguard Worker     // Treating all comparators as transparent can cause inefficiencies (see
762*9356374aSAndroid Build Coastguard Worker     // N3657 C++ proposal). Test that for comparators without 'is_transparent'
763*9356374aSAndroid Build Coastguard Worker     // alias (like this one), we do not attempt heterogeneous lookup.
764*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE((std::is_same<T, U>()));
765*9356374aSAndroid Build Coastguard Worker     return t < u;
766*9356374aSAndroid Build Coastguard Worker   }
767*9356374aSAndroid Build Coastguard Worker };
768*9356374aSAndroid Build Coastguard Worker 
769*9356374aSAndroid Build Coastguard Worker template <typename T>
770*9356374aSAndroid Build Coastguard Worker bool CanEraseWithEmptyBrace(T t, decltype(t.erase({})) *) {
771*9356374aSAndroid Build Coastguard Worker   return true;
772*9356374aSAndroid Build Coastguard Worker }
773*9356374aSAndroid Build Coastguard Worker 
774*9356374aSAndroid Build Coastguard Worker template <typename T>
CanEraseWithEmptyBrace(T,...)775*9356374aSAndroid Build Coastguard Worker bool CanEraseWithEmptyBrace(T, ...) {
776*9356374aSAndroid Build Coastguard Worker   return false;
777*9356374aSAndroid Build Coastguard Worker }
778*9356374aSAndroid Build Coastguard Worker 
779*9356374aSAndroid Build Coastguard Worker template <typename T>
TestHeterogeneous(T table)780*9356374aSAndroid Build Coastguard Worker void TestHeterogeneous(T table) {
781*9356374aSAndroid Build Coastguard Worker   auto lb = table.lower_bound("3");
782*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(lb, table.lower_bound(3));
783*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(lb, table.lower_bound(4));
784*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(lb, table.lower_bound({"3"}));
785*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(lb, table.lower_bound({}));
786*9356374aSAndroid Build Coastguard Worker 
787*9356374aSAndroid Build Coastguard Worker   auto ub = table.upper_bound("3");
788*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ub, table.upper_bound(3));
789*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(ub, table.upper_bound(5));
790*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ub, table.upper_bound({"3"}));
791*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(ub, table.upper_bound({}));
792*9356374aSAndroid Build Coastguard Worker 
793*9356374aSAndroid Build Coastguard Worker   auto er = table.equal_range("3");
794*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(er, table.equal_range(3));
795*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(er, table.equal_range(4));
796*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(er, table.equal_range({"3"}));
797*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(er, table.equal_range({}));
798*9356374aSAndroid Build Coastguard Worker 
799*9356374aSAndroid Build Coastguard Worker   auto it = table.find("3");
800*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, table.find(3));
801*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(it, table.find(4));
802*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, table.find({"3"}));
803*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(it, table.find({}));
804*9356374aSAndroid Build Coastguard Worker 
805*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(table.contains(3));
806*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(table.contains(4));
807*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(table.count({"3"}));
808*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(table.contains({}));
809*9356374aSAndroid Build Coastguard Worker 
810*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, table.count(3));
811*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(0, table.count(4));
812*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, table.count({"3"}));
813*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(0, table.count({}));
814*9356374aSAndroid Build Coastguard Worker 
815*9356374aSAndroid Build Coastguard Worker   auto copy = table;
816*9356374aSAndroid Build Coastguard Worker   copy.erase(3);
817*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(table.size() - 1, copy.size());
818*9356374aSAndroid Build Coastguard Worker   copy.erase(4);
819*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(table.size() - 1, copy.size());
820*9356374aSAndroid Build Coastguard Worker   copy.erase({"5"});
821*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(table.size() - 2, copy.size());
822*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(CanEraseWithEmptyBrace(table, nullptr));
823*9356374aSAndroid Build Coastguard Worker 
824*9356374aSAndroid Build Coastguard Worker   // Also run it with const T&.
825*9356374aSAndroid Build Coastguard Worker   if (std::is_class<T>()) TestHeterogeneous<const T &>(table);
826*9356374aSAndroid Build Coastguard Worker }
827*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,HeterogeneousLookup)828*9356374aSAndroid Build Coastguard Worker TEST(Btree, HeterogeneousLookup) {
829*9356374aSAndroid Build Coastguard Worker   TestHeterogeneous(btree_set<std::string, CompareIntToString>{"1", "3", "5"});
830*9356374aSAndroid Build Coastguard Worker   TestHeterogeneous(btree_map<std::string, int, CompareIntToString>{
831*9356374aSAndroid Build Coastguard Worker       {"1", 1}, {"3", 3}, {"5", 5}});
832*9356374aSAndroid Build Coastguard Worker   TestHeterogeneous(
833*9356374aSAndroid Build Coastguard Worker       btree_multiset<std::string, CompareIntToString>{"1", "3", "5"});
834*9356374aSAndroid Build Coastguard Worker   TestHeterogeneous(btree_multimap<std::string, int, CompareIntToString>{
835*9356374aSAndroid Build Coastguard Worker       {"1", 1}, {"3", 3}, {"5", 5}});
836*9356374aSAndroid Build Coastguard Worker 
837*9356374aSAndroid Build Coastguard Worker   // Only maps have .at()
838*9356374aSAndroid Build Coastguard Worker   btree_map<std::string, int, CompareIntToString> map{
839*9356374aSAndroid Build Coastguard Worker       {"", -1}, {"1", 1}, {"3", 3}, {"5", 5}};
840*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, map.at(1));
841*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(3, map.at({"3"}));
842*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(-1, map.at({}));
843*9356374aSAndroid Build Coastguard Worker   const auto &cmap = map;
844*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, cmap.at(1));
845*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(3, cmap.at({"3"}));
846*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(-1, cmap.at({}));
847*9356374aSAndroid Build Coastguard Worker }
848*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,NoHeterogeneousLookupWithoutAlias)849*9356374aSAndroid Build Coastguard Worker TEST(Btree, NoHeterogeneousLookupWithoutAlias) {
850*9356374aSAndroid Build Coastguard Worker   using StringSet = absl::btree_set<std::string, NonTransparentCompare>;
851*9356374aSAndroid Build Coastguard Worker   StringSet s;
852*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(s.insert("hello").second);
853*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(s.insert("world").second);
854*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(s.end() == s.find("blah"));
855*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(s.begin() == s.lower_bound("hello"));
856*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, s.count("world"));
857*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(s.contains("hello"));
858*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(s.contains("world"));
859*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(s.contains("blah"));
860*9356374aSAndroid Build Coastguard Worker 
861*9356374aSAndroid Build Coastguard Worker   using StringMultiSet =
862*9356374aSAndroid Build Coastguard Worker       absl::btree_multiset<std::string, NonTransparentCompare>;
863*9356374aSAndroid Build Coastguard Worker   StringMultiSet ms;
864*9356374aSAndroid Build Coastguard Worker   ms.insert("hello");
865*9356374aSAndroid Build Coastguard Worker   ms.insert("world");
866*9356374aSAndroid Build Coastguard Worker   ms.insert("world");
867*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(ms.end() == ms.find("blah"));
868*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(ms.begin() == ms.lower_bound("hello"));
869*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(2, ms.count("world"));
870*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(ms.contains("hello"));
871*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(ms.contains("world"));
872*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(ms.contains("blah"));
873*9356374aSAndroid Build Coastguard Worker }
874*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,DefaultTransparent)875*9356374aSAndroid Build Coastguard Worker TEST(Btree, DefaultTransparent) {
876*9356374aSAndroid Build Coastguard Worker   {
877*9356374aSAndroid Build Coastguard Worker     // `int` does not have a default transparent comparator.
878*9356374aSAndroid Build Coastguard Worker     // The input value is converted to key_type.
879*9356374aSAndroid Build Coastguard Worker     btree_set<int> s = {1};
880*9356374aSAndroid Build Coastguard Worker     double d = 1.1;
881*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(s.begin(), s.find(d));
882*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(s.contains(d));
883*9356374aSAndroid Build Coastguard Worker   }
884*9356374aSAndroid Build Coastguard Worker 
885*9356374aSAndroid Build Coastguard Worker   {
886*9356374aSAndroid Build Coastguard Worker     // `std::string` has heterogeneous support.
887*9356374aSAndroid Build Coastguard Worker     btree_set<std::string> s = {"A"};
888*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(s.begin(), s.find(absl::string_view("A")));
889*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(s.contains(absl::string_view("A")));
890*9356374aSAndroid Build Coastguard Worker   }
891*9356374aSAndroid Build Coastguard Worker }
892*9356374aSAndroid Build Coastguard Worker 
893*9356374aSAndroid Build Coastguard Worker class StringLike {
894*9356374aSAndroid Build Coastguard Worker  public:
895*9356374aSAndroid Build Coastguard Worker   StringLike() = default;
896*9356374aSAndroid Build Coastguard Worker 
StringLike(const char * s)897*9356374aSAndroid Build Coastguard Worker   StringLike(const char *s) : s_(s) {  // NOLINT
898*9356374aSAndroid Build Coastguard Worker     ++constructor_calls_;
899*9356374aSAndroid Build Coastguard Worker   }
900*9356374aSAndroid Build Coastguard Worker 
operator <(const StringLike & a) const901*9356374aSAndroid Build Coastguard Worker   bool operator<(const StringLike &a) const { return s_ < a.s_; }
902*9356374aSAndroid Build Coastguard Worker 
clear_constructor_call_count()903*9356374aSAndroid Build Coastguard Worker   static void clear_constructor_call_count() { constructor_calls_ = 0; }
904*9356374aSAndroid Build Coastguard Worker 
constructor_calls()905*9356374aSAndroid Build Coastguard Worker   static int constructor_calls() { return constructor_calls_; }
906*9356374aSAndroid Build Coastguard Worker 
907*9356374aSAndroid Build Coastguard Worker  private:
908*9356374aSAndroid Build Coastguard Worker   static int constructor_calls_;
909*9356374aSAndroid Build Coastguard Worker   std::string s_;
910*9356374aSAndroid Build Coastguard Worker };
911*9356374aSAndroid Build Coastguard Worker 
912*9356374aSAndroid Build Coastguard Worker int StringLike::constructor_calls_ = 0;
913*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,HeterogeneousLookupDoesntDegradePerformance)914*9356374aSAndroid Build Coastguard Worker TEST(Btree, HeterogeneousLookupDoesntDegradePerformance) {
915*9356374aSAndroid Build Coastguard Worker   using StringSet = absl::btree_set<StringLike>;
916*9356374aSAndroid Build Coastguard Worker   StringSet s;
917*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
918*9356374aSAndroid Build Coastguard Worker     ASSERT_TRUE(s.insert(absl::StrCat(i).c_str()).second);
919*9356374aSAndroid Build Coastguard Worker   }
920*9356374aSAndroid Build Coastguard Worker   StringLike::clear_constructor_call_count();
921*9356374aSAndroid Build Coastguard Worker   s.find("50");
922*9356374aSAndroid Build Coastguard Worker   ASSERT_EQ(1, StringLike::constructor_calls());
923*9356374aSAndroid Build Coastguard Worker 
924*9356374aSAndroid Build Coastguard Worker   StringLike::clear_constructor_call_count();
925*9356374aSAndroid Build Coastguard Worker   s.contains("50");
926*9356374aSAndroid Build Coastguard Worker   ASSERT_EQ(1, StringLike::constructor_calls());
927*9356374aSAndroid Build Coastguard Worker 
928*9356374aSAndroid Build Coastguard Worker   StringLike::clear_constructor_call_count();
929*9356374aSAndroid Build Coastguard Worker   s.count("50");
930*9356374aSAndroid Build Coastguard Worker   ASSERT_EQ(1, StringLike::constructor_calls());
931*9356374aSAndroid Build Coastguard Worker 
932*9356374aSAndroid Build Coastguard Worker   StringLike::clear_constructor_call_count();
933*9356374aSAndroid Build Coastguard Worker   s.lower_bound("50");
934*9356374aSAndroid Build Coastguard Worker   ASSERT_EQ(1, StringLike::constructor_calls());
935*9356374aSAndroid Build Coastguard Worker 
936*9356374aSAndroid Build Coastguard Worker   StringLike::clear_constructor_call_count();
937*9356374aSAndroid Build Coastguard Worker   s.upper_bound("50");
938*9356374aSAndroid Build Coastguard Worker   ASSERT_EQ(1, StringLike::constructor_calls());
939*9356374aSAndroid Build Coastguard Worker 
940*9356374aSAndroid Build Coastguard Worker   StringLike::clear_constructor_call_count();
941*9356374aSAndroid Build Coastguard Worker   s.equal_range("50");
942*9356374aSAndroid Build Coastguard Worker   ASSERT_EQ(1, StringLike::constructor_calls());
943*9356374aSAndroid Build Coastguard Worker 
944*9356374aSAndroid Build Coastguard Worker   StringLike::clear_constructor_call_count();
945*9356374aSAndroid Build Coastguard Worker   s.erase("50");
946*9356374aSAndroid Build Coastguard Worker   ASSERT_EQ(1, StringLike::constructor_calls());
947*9356374aSAndroid Build Coastguard Worker }
948*9356374aSAndroid Build Coastguard Worker 
949*9356374aSAndroid Build Coastguard Worker // Verify that swapping btrees swaps the key comparison functors and that we can
950*9356374aSAndroid Build Coastguard Worker // use non-default constructible comparators.
951*9356374aSAndroid Build Coastguard Worker struct SubstringLess {
952*9356374aSAndroid Build Coastguard Worker   SubstringLess() = delete;
SubstringLessabsl::container_internal::__anon7e8713fe0211::SubstringLess953*9356374aSAndroid Build Coastguard Worker   explicit SubstringLess(int length) : n(length) {}
operator ()absl::container_internal::__anon7e8713fe0211::SubstringLess954*9356374aSAndroid Build Coastguard Worker   bool operator()(const std::string &a, const std::string &b) const {
955*9356374aSAndroid Build Coastguard Worker     return absl::string_view(a).substr(0, n) <
956*9356374aSAndroid Build Coastguard Worker            absl::string_view(b).substr(0, n);
957*9356374aSAndroid Build Coastguard Worker   }
958*9356374aSAndroid Build Coastguard Worker   int n;
959*9356374aSAndroid Build Coastguard Worker };
960*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,SwapKeyCompare)961*9356374aSAndroid Build Coastguard Worker TEST(Btree, SwapKeyCompare) {
962*9356374aSAndroid Build Coastguard Worker   using SubstringSet = absl::btree_set<std::string, SubstringLess>;
963*9356374aSAndroid Build Coastguard Worker   SubstringSet s1(SubstringLess(1), SubstringSet::allocator_type());
964*9356374aSAndroid Build Coastguard Worker   SubstringSet s2(SubstringLess(2), SubstringSet::allocator_type());
965*9356374aSAndroid Build Coastguard Worker 
966*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(s1.insert("a").second);
967*9356374aSAndroid Build Coastguard Worker   ASSERT_FALSE(s1.insert("aa").second);
968*9356374aSAndroid Build Coastguard Worker 
969*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(s2.insert("a").second);
970*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(s2.insert("aa").second);
971*9356374aSAndroid Build Coastguard Worker   ASSERT_FALSE(s2.insert("aaa").second);
972*9356374aSAndroid Build Coastguard Worker 
973*9356374aSAndroid Build Coastguard Worker   swap(s1, s2);
974*9356374aSAndroid Build Coastguard Worker 
975*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(s1.insert("b").second);
976*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(s1.insert("bb").second);
977*9356374aSAndroid Build Coastguard Worker   ASSERT_FALSE(s1.insert("bbb").second);
978*9356374aSAndroid Build Coastguard Worker 
979*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(s2.insert("b").second);
980*9356374aSAndroid Build Coastguard Worker   ASSERT_FALSE(s2.insert("bb").second);
981*9356374aSAndroid Build Coastguard Worker }
982*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,UpperBoundRegression)983*9356374aSAndroid Build Coastguard Worker TEST(Btree, UpperBoundRegression) {
984*9356374aSAndroid Build Coastguard Worker   // Regress a bug where upper_bound would default-construct a new key_compare
985*9356374aSAndroid Build Coastguard Worker   // instead of copying the existing one.
986*9356374aSAndroid Build Coastguard Worker   using SubstringSet = absl::btree_set<std::string, SubstringLess>;
987*9356374aSAndroid Build Coastguard Worker   SubstringSet my_set(SubstringLess(3));
988*9356374aSAndroid Build Coastguard Worker   my_set.insert("aab");
989*9356374aSAndroid Build Coastguard Worker   my_set.insert("abb");
990*9356374aSAndroid Build Coastguard Worker   // We call upper_bound("aaa").  If this correctly uses the length 3
991*9356374aSAndroid Build Coastguard Worker   // comparator, aaa < aab < abb, so we should get aab as the result.
992*9356374aSAndroid Build Coastguard Worker   // If it instead uses the default-constructed length 2 comparator,
993*9356374aSAndroid Build Coastguard Worker   // aa == aa < ab, so we'll get abb as our result.
994*9356374aSAndroid Build Coastguard Worker   SubstringSet::iterator it = my_set.upper_bound("aaa");
995*9356374aSAndroid Build Coastguard Worker   ASSERT_TRUE(it != my_set.end());
996*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("aab", *it);
997*9356374aSAndroid Build Coastguard Worker }
998*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,Comparison)999*9356374aSAndroid Build Coastguard Worker TEST(Btree, Comparison) {
1000*9356374aSAndroid Build Coastguard Worker   const int kSetSize = 1201;
1001*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int64_t> my_set;
1002*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < kSetSize; ++i) {
1003*9356374aSAndroid Build Coastguard Worker     my_set.insert(i);
1004*9356374aSAndroid Build Coastguard Worker   }
1005*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int64_t> my_set_copy(my_set);
1006*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_set_copy == my_set);
1007*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_set == my_set_copy);
1008*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_set_copy != my_set);
1009*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_set != my_set_copy);
1010*9356374aSAndroid Build Coastguard Worker 
1011*9356374aSAndroid Build Coastguard Worker   my_set.insert(kSetSize);
1012*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_set_copy == my_set);
1013*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_set == my_set_copy);
1014*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_set_copy != my_set);
1015*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_set != my_set_copy);
1016*9356374aSAndroid Build Coastguard Worker 
1017*9356374aSAndroid Build Coastguard Worker   my_set.erase(kSetSize - 1);
1018*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_set_copy == my_set);
1019*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_set == my_set_copy);
1020*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_set_copy != my_set);
1021*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_set != my_set_copy);
1022*9356374aSAndroid Build Coastguard Worker 
1023*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int64_t> my_map;
1024*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < kSetSize; ++i) {
1025*9356374aSAndroid Build Coastguard Worker     my_map[std::string(i, 'a')] = i;
1026*9356374aSAndroid Build Coastguard Worker   }
1027*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int64_t> my_map_copy(my_map);
1028*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_map_copy == my_map);
1029*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_map == my_map_copy);
1030*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_map_copy != my_map);
1031*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_map != my_map_copy);
1032*9356374aSAndroid Build Coastguard Worker 
1033*9356374aSAndroid Build Coastguard Worker   ++my_map_copy[std::string(7, 'a')];
1034*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_map_copy == my_map);
1035*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_map == my_map_copy);
1036*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_map_copy != my_map);
1037*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_map != my_map_copy);
1038*9356374aSAndroid Build Coastguard Worker 
1039*9356374aSAndroid Build Coastguard Worker   my_map_copy = my_map;
1040*9356374aSAndroid Build Coastguard Worker   my_map["hello"] = kSetSize;
1041*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_map_copy == my_map);
1042*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_map == my_map_copy);
1043*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_map_copy != my_map);
1044*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_map != my_map_copy);
1045*9356374aSAndroid Build Coastguard Worker 
1046*9356374aSAndroid Build Coastguard Worker   my_map.erase(std::string(kSetSize - 1, 'a'));
1047*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_map_copy == my_map);
1048*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(my_map == my_map_copy);
1049*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_map_copy != my_map);
1050*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(my_map != my_map_copy);
1051*9356374aSAndroid Build Coastguard Worker }
1052*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,RangeCtorSanity)1053*9356374aSAndroid Build Coastguard Worker TEST(Btree, RangeCtorSanity) {
1054*9356374aSAndroid Build Coastguard Worker   std::vector<int> ivec;
1055*9356374aSAndroid Build Coastguard Worker   ivec.push_back(1);
1056*9356374aSAndroid Build Coastguard Worker   std::map<int, int> imap;
1057*9356374aSAndroid Build Coastguard Worker   imap.insert(std::make_pair(1, 2));
1058*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> tmset(ivec.begin(), ivec.end());
1059*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> tmmap(imap.begin(), imap.end());
1060*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> tset(ivec.begin(), ivec.end());
1061*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> tmap(imap.begin(), imap.end());
1062*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, tmset.size());
1063*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, tmmap.size());
1064*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, tset.size());
1065*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, tmap.size());
1066*9356374aSAndroid Build Coastguard Worker }
1067*9356374aSAndroid Build Coastguard Worker 
1068*9356374aSAndroid Build Coastguard Worker }  // namespace
1069*9356374aSAndroid Build Coastguard Worker 
1070*9356374aSAndroid Build Coastguard Worker class BtreeNodePeer {
1071*9356374aSAndroid Build Coastguard Worker  public:
1072*9356374aSAndroid Build Coastguard Worker   // Yields the size of a leaf node with a specific number of values.
1073*9356374aSAndroid Build Coastguard Worker   template <typename ValueType>
GetTargetNodeSize(size_t target_values_per_node)1074*9356374aSAndroid Build Coastguard Worker   constexpr static size_t GetTargetNodeSize(size_t target_values_per_node) {
1075*9356374aSAndroid Build Coastguard Worker     return btree_node<
1076*9356374aSAndroid Build Coastguard Worker         set_params<ValueType, std::less<ValueType>, std::allocator<ValueType>,
1077*9356374aSAndroid Build Coastguard Worker                    /*TargetNodeSize=*/256,  // This parameter isn't used here.
1078*9356374aSAndroid Build Coastguard Worker                    /*Multi=*/false>>::SizeWithNSlots(target_values_per_node);
1079*9356374aSAndroid Build Coastguard Worker   }
1080*9356374aSAndroid Build Coastguard Worker 
1081*9356374aSAndroid Build Coastguard Worker   // Yields the number of slots in a (non-root) leaf node for this btree.
1082*9356374aSAndroid Build Coastguard Worker   template <typename Btree>
GetNumSlotsPerNode()1083*9356374aSAndroid Build Coastguard Worker   constexpr static size_t GetNumSlotsPerNode() {
1084*9356374aSAndroid Build Coastguard Worker     return btree_node<typename Btree::params_type>::kNodeSlots;
1085*9356374aSAndroid Build Coastguard Worker   }
1086*9356374aSAndroid Build Coastguard Worker 
1087*9356374aSAndroid Build Coastguard Worker   template <typename Btree>
GetMaxFieldType()1088*9356374aSAndroid Build Coastguard Worker   constexpr static size_t GetMaxFieldType() {
1089*9356374aSAndroid Build Coastguard Worker     return std::numeric_limits<
1090*9356374aSAndroid Build Coastguard Worker         typename btree_node<typename Btree::params_type>::field_type>::max();
1091*9356374aSAndroid Build Coastguard Worker   }
1092*9356374aSAndroid Build Coastguard Worker 
1093*9356374aSAndroid Build Coastguard Worker   template <typename Btree>
UsesLinearNodeSearch()1094*9356374aSAndroid Build Coastguard Worker   constexpr static bool UsesLinearNodeSearch() {
1095*9356374aSAndroid Build Coastguard Worker     return btree_node<typename Btree::params_type>::use_linear_search::value;
1096*9356374aSAndroid Build Coastguard Worker   }
1097*9356374aSAndroid Build Coastguard Worker 
1098*9356374aSAndroid Build Coastguard Worker   template <typename Btree>
FieldTypeEqualsSlotType()1099*9356374aSAndroid Build Coastguard Worker   constexpr static bool FieldTypeEqualsSlotType() {
1100*9356374aSAndroid Build Coastguard Worker     return std::is_same<
1101*9356374aSAndroid Build Coastguard Worker         typename btree_node<typename Btree::params_type>::field_type,
1102*9356374aSAndroid Build Coastguard Worker         typename btree_node<typename Btree::params_type>::slot_type>::value;
1103*9356374aSAndroid Build Coastguard Worker   }
1104*9356374aSAndroid Build Coastguard Worker };
1105*9356374aSAndroid Build Coastguard Worker 
1106*9356374aSAndroid Build Coastguard Worker namespace {
1107*9356374aSAndroid Build Coastguard Worker 
1108*9356374aSAndroid Build Coastguard Worker class BtreeMapTest : public ::testing::Test {
1109*9356374aSAndroid Build Coastguard Worker  public:
1110*9356374aSAndroid Build Coastguard Worker   struct Key {};
1111*9356374aSAndroid Build Coastguard Worker   struct Cmp {
1112*9356374aSAndroid Build Coastguard Worker     template <typename T>
operator ()absl::container_internal::__anon7e8713fe0311::BtreeMapTest::Cmp1113*9356374aSAndroid Build Coastguard Worker     bool operator()(T, T) const {
1114*9356374aSAndroid Build Coastguard Worker       return false;
1115*9356374aSAndroid Build Coastguard Worker     }
1116*9356374aSAndroid Build Coastguard Worker   };
1117*9356374aSAndroid Build Coastguard Worker 
1118*9356374aSAndroid Build Coastguard Worker   struct KeyLin {
1119*9356374aSAndroid Build Coastguard Worker     using absl_btree_prefer_linear_node_search = std::true_type;
1120*9356374aSAndroid Build Coastguard Worker   };
1121*9356374aSAndroid Build Coastguard Worker   struct CmpLin : Cmp {
1122*9356374aSAndroid Build Coastguard Worker     using absl_btree_prefer_linear_node_search = std::true_type;
1123*9356374aSAndroid Build Coastguard Worker   };
1124*9356374aSAndroid Build Coastguard Worker 
1125*9356374aSAndroid Build Coastguard Worker   struct KeyBin {
1126*9356374aSAndroid Build Coastguard Worker     using absl_btree_prefer_linear_node_search = std::false_type;
1127*9356374aSAndroid Build Coastguard Worker   };
1128*9356374aSAndroid Build Coastguard Worker   struct CmpBin : Cmp {
1129*9356374aSAndroid Build Coastguard Worker     using absl_btree_prefer_linear_node_search = std::false_type;
1130*9356374aSAndroid Build Coastguard Worker   };
1131*9356374aSAndroid Build Coastguard Worker 
1132*9356374aSAndroid Build Coastguard Worker   template <typename K, typename C>
IsLinear()1133*9356374aSAndroid Build Coastguard Worker   static bool IsLinear() {
1134*9356374aSAndroid Build Coastguard Worker     return BtreeNodePeer::UsesLinearNodeSearch<absl::btree_map<K, int, C>>();
1135*9356374aSAndroid Build Coastguard Worker   }
1136*9356374aSAndroid Build Coastguard Worker };
1137*9356374aSAndroid Build Coastguard Worker 
TEST_F(BtreeMapTest,TestLinearSearchPreferredForKeyLinearViaAlias)1138*9356374aSAndroid Build Coastguard Worker TEST_F(BtreeMapTest, TestLinearSearchPreferredForKeyLinearViaAlias) {
1139*9356374aSAndroid Build Coastguard Worker   // Test requesting linear search by directly exporting an alias.
1140*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<Key, Cmp>()));
1141*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<KeyLin, Cmp>()));
1142*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<Key, CmpLin>()));
1143*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<KeyLin, CmpLin>()));
1144*9356374aSAndroid Build Coastguard Worker }
1145*9356374aSAndroid Build Coastguard Worker 
TEST_F(BtreeMapTest,LinearChoiceTree)1146*9356374aSAndroid Build Coastguard Worker TEST_F(BtreeMapTest, LinearChoiceTree) {
1147*9356374aSAndroid Build Coastguard Worker   // Cmp has precedence, and is forcing binary
1148*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<Key, CmpBin>()));
1149*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<KeyLin, CmpBin>()));
1150*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<KeyBin, CmpBin>()));
1151*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<int, CmpBin>()));
1152*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<std::string, CmpBin>()));
1153*9356374aSAndroid Build Coastguard Worker   // Cmp has precedence, and is forcing linear
1154*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<Key, CmpLin>()));
1155*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<KeyLin, CmpLin>()));
1156*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<KeyBin, CmpLin>()));
1157*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<int, CmpLin>()));
1158*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<std::string, CmpLin>()));
1159*9356374aSAndroid Build Coastguard Worker   // Cmp has no preference, Key determines linear vs binary.
1160*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<Key, Cmp>()));
1161*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<KeyLin, Cmp>()));
1162*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<KeyBin, Cmp>()));
1163*9356374aSAndroid Build Coastguard Worker   // arithmetic key w/ std::less or std::greater: linear
1164*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<int, std::less<int>>()));
1165*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((IsLinear<double, std::greater<double>>()));
1166*9356374aSAndroid Build Coastguard Worker   // arithmetic key w/ custom compare: binary
1167*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<int, Cmp>()));
1168*9356374aSAndroid Build Coastguard Worker   // non-arithmetic key: binary
1169*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((IsLinear<std::string, std::less<std::string>>()));
1170*9356374aSAndroid Build Coastguard Worker }
1171*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,BtreeMapCanHoldMoveOnlyTypes)1172*9356374aSAndroid Build Coastguard Worker TEST(Btree, BtreeMapCanHoldMoveOnlyTypes) {
1173*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, std::unique_ptr<std::string>> m;
1174*9356374aSAndroid Build Coastguard Worker 
1175*9356374aSAndroid Build Coastguard Worker   std::unique_ptr<std::string> &v = m["A"];
1176*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(v == nullptr);
1177*9356374aSAndroid Build Coastguard Worker   v = absl::make_unique<std::string>("X");
1178*9356374aSAndroid Build Coastguard Worker 
1179*9356374aSAndroid Build Coastguard Worker   auto iter = m.find("A");
1180*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("X", *iter->second);
1181*9356374aSAndroid Build Coastguard Worker }
1182*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,InitializerListConstructor)1183*9356374aSAndroid Build Coastguard Worker TEST(Btree, InitializerListConstructor) {
1184*9356374aSAndroid Build Coastguard Worker   absl::btree_set<std::string> set({"a", "b"});
1185*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(set.count("a"), 1);
1186*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(set.count("b"), 1);
1187*9356374aSAndroid Build Coastguard Worker 
1188*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> mset({1, 1, 4});
1189*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mset.count(1), 2);
1190*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mset.count(4), 1);
1191*9356374aSAndroid Build Coastguard Worker 
1192*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> map({{1, 5}, {2, 10}});
1193*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(map[1], 5);
1194*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(map[2], 10);
1195*9356374aSAndroid Build Coastguard Worker 
1196*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> mmap({{1, 5}, {1, 10}});
1197*9356374aSAndroid Build Coastguard Worker   auto range = mmap.equal_range(1);
1198*9356374aSAndroid Build Coastguard Worker   auto it = range.first;
1199*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(it, range.second);
1200*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it->second, 5);
1201*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(++it, range.second);
1202*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it->second, 10);
1203*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(++it, range.second);
1204*9356374aSAndroid Build Coastguard Worker }
1205*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,InitializerListInsert)1206*9356374aSAndroid Build Coastguard Worker TEST(Btree, InitializerListInsert) {
1207*9356374aSAndroid Build Coastguard Worker   absl::btree_set<std::string> set;
1208*9356374aSAndroid Build Coastguard Worker   set.insert({"a", "b"});
1209*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(set.count("a"), 1);
1210*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(set.count("b"), 1);
1211*9356374aSAndroid Build Coastguard Worker 
1212*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> mset;
1213*9356374aSAndroid Build Coastguard Worker   mset.insert({1, 1, 4});
1214*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mset.count(1), 2);
1215*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mset.count(4), 1);
1216*9356374aSAndroid Build Coastguard Worker 
1217*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> map;
1218*9356374aSAndroid Build Coastguard Worker   map.insert({{1, 5}, {2, 10}});
1219*9356374aSAndroid Build Coastguard Worker   // Test that inserting one element using an initializer list also works.
1220*9356374aSAndroid Build Coastguard Worker   map.insert({3, 15});
1221*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(map[1], 5);
1222*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(map[2], 10);
1223*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(map[3], 15);
1224*9356374aSAndroid Build Coastguard Worker 
1225*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> mmap;
1226*9356374aSAndroid Build Coastguard Worker   mmap.insert({{1, 5}, {1, 10}});
1227*9356374aSAndroid Build Coastguard Worker   auto range = mmap.equal_range(1);
1228*9356374aSAndroid Build Coastguard Worker   auto it = range.first;
1229*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(it, range.second);
1230*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it->second, 5);
1231*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(++it, range.second);
1232*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it->second, 10);
1233*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(++it, range.second);
1234*9356374aSAndroid Build Coastguard Worker }
1235*9356374aSAndroid Build Coastguard Worker 
1236*9356374aSAndroid Build Coastguard Worker template <typename Compare, typename Key>
AssertKeyCompareStringAdapted()1237*9356374aSAndroid Build Coastguard Worker void AssertKeyCompareStringAdapted() {
1238*9356374aSAndroid Build Coastguard Worker   using Adapted = typename key_compare_adapter<Compare, Key>::type;
1239*9356374aSAndroid Build Coastguard Worker   static_assert(
1240*9356374aSAndroid Build Coastguard Worker       std::is_same<Adapted, StringBtreeDefaultLess>::value ||
1241*9356374aSAndroid Build Coastguard Worker           std::is_same<Adapted, StringBtreeDefaultGreater>::value,
1242*9356374aSAndroid Build Coastguard Worker       "key_compare_adapter should have string-adapted this comparator.");
1243*9356374aSAndroid Build Coastguard Worker }
1244*9356374aSAndroid Build Coastguard Worker template <typename Compare, typename Key>
AssertKeyCompareNotStringAdapted()1245*9356374aSAndroid Build Coastguard Worker void AssertKeyCompareNotStringAdapted() {
1246*9356374aSAndroid Build Coastguard Worker   using Adapted = typename key_compare_adapter<Compare, Key>::type;
1247*9356374aSAndroid Build Coastguard Worker   static_assert(
1248*9356374aSAndroid Build Coastguard Worker       !std::is_same<Adapted, StringBtreeDefaultLess>::value &&
1249*9356374aSAndroid Build Coastguard Worker           !std::is_same<Adapted, StringBtreeDefaultGreater>::value,
1250*9356374aSAndroid Build Coastguard Worker       "key_compare_adapter shouldn't have string-adapted this comparator.");
1251*9356374aSAndroid Build Coastguard Worker }
1252*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,KeyCompareAdapter)1253*9356374aSAndroid Build Coastguard Worker TEST(Btree, KeyCompareAdapter) {
1254*9356374aSAndroid Build Coastguard Worker   AssertKeyCompareStringAdapted<std::less<std::string>, std::string>();
1255*9356374aSAndroid Build Coastguard Worker   AssertKeyCompareStringAdapted<std::greater<std::string>, std::string>();
1256*9356374aSAndroid Build Coastguard Worker   AssertKeyCompareStringAdapted<std::less<absl::string_view>,
1257*9356374aSAndroid Build Coastguard Worker                                 absl::string_view>();
1258*9356374aSAndroid Build Coastguard Worker   AssertKeyCompareStringAdapted<std::greater<absl::string_view>,
1259*9356374aSAndroid Build Coastguard Worker                                 absl::string_view>();
1260*9356374aSAndroid Build Coastguard Worker   AssertKeyCompareStringAdapted<std::less<absl::Cord>, absl::Cord>();
1261*9356374aSAndroid Build Coastguard Worker   AssertKeyCompareStringAdapted<std::greater<absl::Cord>, absl::Cord>();
1262*9356374aSAndroid Build Coastguard Worker   AssertKeyCompareNotStringAdapted<std::less<int>, int>();
1263*9356374aSAndroid Build Coastguard Worker   AssertKeyCompareNotStringAdapted<std::greater<int>, int>();
1264*9356374aSAndroid Build Coastguard Worker }
1265*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,RValueInsert)1266*9356374aSAndroid Build Coastguard Worker TEST(Btree, RValueInsert) {
1267*9356374aSAndroid Build Coastguard Worker   InstanceTracker tracker;
1268*9356374aSAndroid Build Coastguard Worker 
1269*9356374aSAndroid Build Coastguard Worker   absl::btree_set<MovableOnlyInstance> set;
1270*9356374aSAndroid Build Coastguard Worker   set.insert(MovableOnlyInstance(1));
1271*9356374aSAndroid Build Coastguard Worker   set.insert(MovableOnlyInstance(3));
1272*9356374aSAndroid Build Coastguard Worker   MovableOnlyInstance two(2);
1273*9356374aSAndroid Build Coastguard Worker   set.insert(set.find(MovableOnlyInstance(3)), std::move(two));
1274*9356374aSAndroid Build Coastguard Worker   auto it = set.find(MovableOnlyInstance(2));
1275*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(it, set.end());
1276*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(++it, set.end());
1277*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it->value(), 3);
1278*9356374aSAndroid Build Coastguard Worker 
1279*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<MovableOnlyInstance> mset;
1280*9356374aSAndroid Build Coastguard Worker   MovableOnlyInstance zero(0);
1281*9356374aSAndroid Build Coastguard Worker   MovableOnlyInstance zero2(0);
1282*9356374aSAndroid Build Coastguard Worker   mset.insert(std::move(zero));
1283*9356374aSAndroid Build Coastguard Worker   mset.insert(mset.find(MovableOnlyInstance(0)), std::move(zero2));
1284*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(mset.count(MovableOnlyInstance(0)), 2);
1285*9356374aSAndroid Build Coastguard Worker 
1286*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, MovableOnlyInstance> map;
1287*9356374aSAndroid Build Coastguard Worker   std::pair<const int, MovableOnlyInstance> p1 = {1, MovableOnlyInstance(5)};
1288*9356374aSAndroid Build Coastguard Worker   std::pair<const int, MovableOnlyInstance> p2 = {2, MovableOnlyInstance(10)};
1289*9356374aSAndroid Build Coastguard Worker   std::pair<const int, MovableOnlyInstance> p3 = {3, MovableOnlyInstance(15)};
1290*9356374aSAndroid Build Coastguard Worker   map.insert(std::move(p1));
1291*9356374aSAndroid Build Coastguard Worker   map.insert(std::move(p3));
1292*9356374aSAndroid Build Coastguard Worker   map.insert(map.find(3), std::move(p2));
1293*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(map.find(2), map.end());
1294*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(map.find(2)->second.value(), 10);
1295*9356374aSAndroid Build Coastguard Worker 
1296*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, MovableOnlyInstance> mmap;
1297*9356374aSAndroid Build Coastguard Worker   std::pair<const int, MovableOnlyInstance> p4 = {1, MovableOnlyInstance(5)};
1298*9356374aSAndroid Build Coastguard Worker   std::pair<const int, MovableOnlyInstance> p5 = {1, MovableOnlyInstance(10)};
1299*9356374aSAndroid Build Coastguard Worker   mmap.insert(std::move(p4));
1300*9356374aSAndroid Build Coastguard Worker   mmap.insert(mmap.find(1), std::move(p5));
1301*9356374aSAndroid Build Coastguard Worker   auto range = mmap.equal_range(1);
1302*9356374aSAndroid Build Coastguard Worker   auto it1 = range.first;
1303*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(it1, range.second);
1304*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it1->second.value(), 10);
1305*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(++it1, range.second);
1306*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it1->second.value(), 5);
1307*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(++it1, range.second);
1308*9356374aSAndroid Build Coastguard Worker 
1309*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(tracker.copies(), 0);
1310*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(tracker.swaps(), 0);
1311*9356374aSAndroid Build Coastguard Worker }
1312*9356374aSAndroid Build Coastguard Worker 
1313*9356374aSAndroid Build Coastguard Worker template <typename Cmp>
1314*9356374aSAndroid Build Coastguard Worker struct CheckedCompareOptedOutCmp : Cmp, BtreeTestOnlyCheckedCompareOptOutBase {
1315*9356374aSAndroid Build Coastguard Worker   using Cmp::Cmp;
CheckedCompareOptedOutCmpabsl::container_internal::__anon7e8713fe0311::CheckedCompareOptedOutCmp1316*9356374aSAndroid Build Coastguard Worker   CheckedCompareOptedOutCmp() {}
CheckedCompareOptedOutCmpabsl::container_internal::__anon7e8713fe0311::CheckedCompareOptedOutCmp1317*9356374aSAndroid Build Coastguard Worker   CheckedCompareOptedOutCmp(Cmp cmp) : Cmp(std::move(cmp)) {}  // NOLINT
1318*9356374aSAndroid Build Coastguard Worker };
1319*9356374aSAndroid Build Coastguard Worker 
1320*9356374aSAndroid Build Coastguard Worker // A btree set with a specific number of values per node. Opt out of
1321*9356374aSAndroid Build Coastguard Worker // checked_compare so that we can expect exact numbers of comparisons.
1322*9356374aSAndroid Build Coastguard Worker template <typename Key, int TargetValuesPerNode, typename Cmp = std::less<Key>>
1323*9356374aSAndroid Build Coastguard Worker class SizedBtreeSet
1324*9356374aSAndroid Build Coastguard Worker     : public btree_set_container<btree<
1325*9356374aSAndroid Build Coastguard Worker           set_params<Key, CheckedCompareOptedOutCmp<Cmp>, std::allocator<Key>,
1326*9356374aSAndroid Build Coastguard Worker                      BtreeNodePeer::GetTargetNodeSize<Key>(TargetValuesPerNode),
1327*9356374aSAndroid Build Coastguard Worker                      /*Multi=*/false>>> {
1328*9356374aSAndroid Build Coastguard Worker   using Base = typename SizedBtreeSet::btree_set_container;
1329*9356374aSAndroid Build Coastguard Worker 
1330*9356374aSAndroid Build Coastguard Worker  public:
1331*9356374aSAndroid Build Coastguard Worker   SizedBtreeSet() = default;
1332*9356374aSAndroid Build Coastguard Worker   using Base::Base;
1333*9356374aSAndroid Build Coastguard Worker };
1334*9356374aSAndroid Build Coastguard Worker 
1335*9356374aSAndroid Build Coastguard Worker template <typename Set>
ExpectOperationCounts(const int expected_moves,const int expected_comparisons,const std::vector<int> & values,InstanceTracker * tracker,Set * set)1336*9356374aSAndroid Build Coastguard Worker void ExpectOperationCounts(const int expected_moves,
1337*9356374aSAndroid Build Coastguard Worker                            const int expected_comparisons,
1338*9356374aSAndroid Build Coastguard Worker                            const std::vector<int> &values,
1339*9356374aSAndroid Build Coastguard Worker                            InstanceTracker *tracker, Set *set) {
1340*9356374aSAndroid Build Coastguard Worker   for (const int v : values) set->insert(MovableOnlyInstance(v));
1341*9356374aSAndroid Build Coastguard Worker   set->clear();
1342*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(tracker->moves(), expected_moves);
1343*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(tracker->comparisons(), expected_comparisons);
1344*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(tracker->copies(), 0);
1345*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(tracker->swaps(), 0);
1346*9356374aSAndroid Build Coastguard Worker   tracker->ResetCopiesMovesSwaps();
1347*9356374aSAndroid Build Coastguard Worker }
1348*9356374aSAndroid Build Coastguard Worker 
1349*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
1350*9356374aSAndroid Build Coastguard Worker     defined(ABSL_HAVE_HWADDRESS_SANITIZER)
1351*9356374aSAndroid Build Coastguard Worker constexpr bool kAsan = true;
1352*9356374aSAndroid Build Coastguard Worker #else
1353*9356374aSAndroid Build Coastguard Worker constexpr bool kAsan = false;
1354*9356374aSAndroid Build Coastguard Worker #endif
1355*9356374aSAndroid Build Coastguard Worker 
1356*9356374aSAndroid Build Coastguard Worker // Note: when the values in this test change, it is expected to have an impact
1357*9356374aSAndroid Build Coastguard Worker // on performance.
TEST(Btree,MovesComparisonsCopiesSwapsTracking)1358*9356374aSAndroid Build Coastguard Worker TEST(Btree, MovesComparisonsCopiesSwapsTracking) {
1359*9356374aSAndroid Build Coastguard Worker   if (kAsan) GTEST_SKIP() << "We do extra operations in ASan mode.";
1360*9356374aSAndroid Build Coastguard Worker 
1361*9356374aSAndroid Build Coastguard Worker   InstanceTracker tracker;
1362*9356374aSAndroid Build Coastguard Worker   // Note: this is minimum number of values per node.
1363*9356374aSAndroid Build Coastguard Worker   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/4> set4;
1364*9356374aSAndroid Build Coastguard Worker   // Note: this is the default number of values per node for a set of int32s
1365*9356374aSAndroid Build Coastguard Worker   // (with 64-bit pointers).
1366*9356374aSAndroid Build Coastguard Worker   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/61> set61;
1367*9356374aSAndroid Build Coastguard Worker   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/100> set100;
1368*9356374aSAndroid Build Coastguard Worker 
1369*9356374aSAndroid Build Coastguard Worker   // Don't depend on flags for random values because then the expectations will
1370*9356374aSAndroid Build Coastguard Worker   // fail if the flags change.
1371*9356374aSAndroid Build Coastguard Worker   std::vector<int> values =
1372*9356374aSAndroid Build Coastguard Worker       GenerateValuesWithSeed<int>(10000, 1 << 22, /*seed=*/23);
1373*9356374aSAndroid Build Coastguard Worker 
1374*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set4)>(), 4);
1375*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>(), 61);
1376*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set100)>(), 100);
1377*9356374aSAndroid Build Coastguard Worker   if (sizeof(void *) == 8) {
1378*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t>>(),
1379*9356374aSAndroid Build Coastguard Worker               // When we have generations, there is one fewer slot.
1380*9356374aSAndroid Build Coastguard Worker               BtreeGenerationsEnabled() ? 60 : 61);
1381*9356374aSAndroid Build Coastguard Worker   }
1382*9356374aSAndroid Build Coastguard Worker 
1383*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in random order.
1384*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(56540, 134212, values, &tracker, &set4);
1385*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(386718, 129807, values, &tracker, &set61);
1386*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(586761, 130310, values, &tracker, &set100);
1387*9356374aSAndroid Build Coastguard Worker 
1388*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in sorted order.
1389*9356374aSAndroid Build Coastguard Worker   std::sort(values.begin(), values.end());
1390*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(24972, 85563, values, &tracker, &set4);
1391*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(20208, 87757, values, &tracker, &set61);
1392*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(20124, 96583, values, &tracker, &set100);
1393*9356374aSAndroid Build Coastguard Worker 
1394*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in reverse sorted order.
1395*9356374aSAndroid Build Coastguard Worker   std::reverse(values.begin(), values.end());
1396*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(54949, 127531, values, &tracker, &set4);
1397*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(338813, 118266, values, &tracker, &set61);
1398*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(534529, 125279, values, &tracker, &set100);
1399*9356374aSAndroid Build Coastguard Worker }
1400*9356374aSAndroid Build Coastguard Worker 
1401*9356374aSAndroid Build Coastguard Worker struct MovableOnlyInstanceThreeWayCompare {
operator ()absl::container_internal::__anon7e8713fe0311::MovableOnlyInstanceThreeWayCompare1402*9356374aSAndroid Build Coastguard Worker   absl::weak_ordering operator()(const MovableOnlyInstance &a,
1403*9356374aSAndroid Build Coastguard Worker                                  const MovableOnlyInstance &b) const {
1404*9356374aSAndroid Build Coastguard Worker     return a.compare(b);
1405*9356374aSAndroid Build Coastguard Worker   }
1406*9356374aSAndroid Build Coastguard Worker };
1407*9356374aSAndroid Build Coastguard Worker 
1408*9356374aSAndroid Build Coastguard Worker // Note: when the values in this test change, it is expected to have an impact
1409*9356374aSAndroid Build Coastguard Worker // on performance.
TEST(Btree,MovesComparisonsCopiesSwapsTrackingThreeWayCompare)1410*9356374aSAndroid Build Coastguard Worker TEST(Btree, MovesComparisonsCopiesSwapsTrackingThreeWayCompare) {
1411*9356374aSAndroid Build Coastguard Worker   if (kAsan) GTEST_SKIP() << "We do extra operations in ASan mode.";
1412*9356374aSAndroid Build Coastguard Worker 
1413*9356374aSAndroid Build Coastguard Worker   InstanceTracker tracker;
1414*9356374aSAndroid Build Coastguard Worker   // Note: this is minimum number of values per node.
1415*9356374aSAndroid Build Coastguard Worker   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/4,
1416*9356374aSAndroid Build Coastguard Worker                 MovableOnlyInstanceThreeWayCompare>
1417*9356374aSAndroid Build Coastguard Worker       set4;
1418*9356374aSAndroid Build Coastguard Worker   // Note: this is the default number of values per node for a set of int32s
1419*9356374aSAndroid Build Coastguard Worker   // (with 64-bit pointers).
1420*9356374aSAndroid Build Coastguard Worker   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/61,
1421*9356374aSAndroid Build Coastguard Worker                 MovableOnlyInstanceThreeWayCompare>
1422*9356374aSAndroid Build Coastguard Worker       set61;
1423*9356374aSAndroid Build Coastguard Worker   SizedBtreeSet<MovableOnlyInstance, /*TargetValuesPerNode=*/100,
1424*9356374aSAndroid Build Coastguard Worker                 MovableOnlyInstanceThreeWayCompare>
1425*9356374aSAndroid Build Coastguard Worker       set100;
1426*9356374aSAndroid Build Coastguard Worker 
1427*9356374aSAndroid Build Coastguard Worker   // Don't depend on flags for random values because then the expectations will
1428*9356374aSAndroid Build Coastguard Worker   // fail if the flags change.
1429*9356374aSAndroid Build Coastguard Worker   std::vector<int> values =
1430*9356374aSAndroid Build Coastguard Worker       GenerateValuesWithSeed<int>(10000, 1 << 22, /*seed=*/23);
1431*9356374aSAndroid Build Coastguard Worker 
1432*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set4)>(), 4);
1433*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set61)>(), 61);
1434*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<decltype(set100)>(), 100);
1435*9356374aSAndroid Build Coastguard Worker   if (sizeof(void *) == 8) {
1436*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(BtreeNodePeer::GetNumSlotsPerNode<absl::btree_set<int32_t>>(),
1437*9356374aSAndroid Build Coastguard Worker               // When we have generations, there is one fewer slot.
1438*9356374aSAndroid Build Coastguard Worker               BtreeGenerationsEnabled() ? 60 : 61);
1439*9356374aSAndroid Build Coastguard Worker   }
1440*9356374aSAndroid Build Coastguard Worker 
1441*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in random order.
1442*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(56540, 124221, values, &tracker, &set4);
1443*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(386718, 119816, values, &tracker, &set61);
1444*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(586761, 120319, values, &tracker, &set100);
1445*9356374aSAndroid Build Coastguard Worker 
1446*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in sorted order.
1447*9356374aSAndroid Build Coastguard Worker   std::sort(values.begin(), values.end());
1448*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(24972, 85563, values, &tracker, &set4);
1449*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(20208, 87757, values, &tracker, &set61);
1450*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(20124, 96583, values, &tracker, &set100);
1451*9356374aSAndroid Build Coastguard Worker 
1452*9356374aSAndroid Build Coastguard Worker   // Test key insertion/deletion in reverse sorted order.
1453*9356374aSAndroid Build Coastguard Worker   std::reverse(values.begin(), values.end());
1454*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(54949, 117532, values, &tracker, &set4);
1455*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(338813, 108267, values, &tracker, &set61);
1456*9356374aSAndroid Build Coastguard Worker   ExpectOperationCounts(534529, 115280, values, &tracker, &set100);
1457*9356374aSAndroid Build Coastguard Worker }
1458*9356374aSAndroid Build Coastguard Worker 
1459*9356374aSAndroid Build Coastguard Worker struct NoDefaultCtor {
1460*9356374aSAndroid Build Coastguard Worker   int num;
NoDefaultCtorabsl::container_internal::__anon7e8713fe0311::NoDefaultCtor1461*9356374aSAndroid Build Coastguard Worker   explicit NoDefaultCtor(int i) : num(i) {}
1462*9356374aSAndroid Build Coastguard Worker 
operator <(const NoDefaultCtor & a,const NoDefaultCtor & b)1463*9356374aSAndroid Build Coastguard Worker   friend bool operator<(const NoDefaultCtor &a, const NoDefaultCtor &b) {
1464*9356374aSAndroid Build Coastguard Worker     return a.num < b.num;
1465*9356374aSAndroid Build Coastguard Worker   }
1466*9356374aSAndroid Build Coastguard Worker };
1467*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,BtreeMapCanHoldNoDefaultCtorTypes)1468*9356374aSAndroid Build Coastguard Worker TEST(Btree, BtreeMapCanHoldNoDefaultCtorTypes) {
1469*9356374aSAndroid Build Coastguard Worker   absl::btree_map<NoDefaultCtor, NoDefaultCtor> m;
1470*9356374aSAndroid Build Coastguard Worker 
1471*9356374aSAndroid Build Coastguard Worker   for (int i = 1; i <= 99; ++i) {
1472*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(i);
1473*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(m.emplace(NoDefaultCtor(i), NoDefaultCtor(100 - i)).second);
1474*9356374aSAndroid Build Coastguard Worker   }
1475*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m.emplace(NoDefaultCtor(78), NoDefaultCtor(0)).second);
1476*9356374aSAndroid Build Coastguard Worker 
1477*9356374aSAndroid Build Coastguard Worker   auto iter99 = m.find(NoDefaultCtor(99));
1478*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter99, m.end());
1479*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter99->second.num, 1);
1480*9356374aSAndroid Build Coastguard Worker 
1481*9356374aSAndroid Build Coastguard Worker   auto iter1 = m.find(NoDefaultCtor(1));
1482*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter1, m.end());
1483*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter1->second.num, 99);
1484*9356374aSAndroid Build Coastguard Worker 
1485*9356374aSAndroid Build Coastguard Worker   auto iter50 = m.find(NoDefaultCtor(50));
1486*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter50, m.end());
1487*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter50->second.num, 50);
1488*9356374aSAndroid Build Coastguard Worker 
1489*9356374aSAndroid Build Coastguard Worker   auto iter25 = m.find(NoDefaultCtor(25));
1490*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter25, m.end());
1491*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter25->second.num, 75);
1492*9356374aSAndroid Build Coastguard Worker }
1493*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,BtreeMultimapCanHoldNoDefaultCtorTypes)1494*9356374aSAndroid Build Coastguard Worker TEST(Btree, BtreeMultimapCanHoldNoDefaultCtorTypes) {
1495*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<NoDefaultCtor, NoDefaultCtor> m;
1496*9356374aSAndroid Build Coastguard Worker 
1497*9356374aSAndroid Build Coastguard Worker   for (int i = 1; i <= 99; ++i) {
1498*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(i);
1499*9356374aSAndroid Build Coastguard Worker     m.emplace(NoDefaultCtor(i), NoDefaultCtor(100 - i));
1500*9356374aSAndroid Build Coastguard Worker   }
1501*9356374aSAndroid Build Coastguard Worker 
1502*9356374aSAndroid Build Coastguard Worker   auto iter99 = m.find(NoDefaultCtor(99));
1503*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter99, m.end());
1504*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter99->second.num, 1);
1505*9356374aSAndroid Build Coastguard Worker 
1506*9356374aSAndroid Build Coastguard Worker   auto iter1 = m.find(NoDefaultCtor(1));
1507*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter1, m.end());
1508*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter1->second.num, 99);
1509*9356374aSAndroid Build Coastguard Worker 
1510*9356374aSAndroid Build Coastguard Worker   auto iter50 = m.find(NoDefaultCtor(50));
1511*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter50, m.end());
1512*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter50->second.num, 50);
1513*9356374aSAndroid Build Coastguard Worker 
1514*9356374aSAndroid Build Coastguard Worker   auto iter25 = m.find(NoDefaultCtor(25));
1515*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter25, m.end());
1516*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter25->second.num, 75);
1517*9356374aSAndroid Build Coastguard Worker }
1518*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MapAt)1519*9356374aSAndroid Build Coastguard Worker TEST(Btree, MapAt) {
1520*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> map = {{1, 2}, {2, 4}};
1521*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(map.at(1), 2);
1522*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(map.at(2), 4);
1523*9356374aSAndroid Build Coastguard Worker   map.at(2) = 8;
1524*9356374aSAndroid Build Coastguard Worker   const absl::btree_map<int, int> &const_map = map;
1525*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_map.at(1), 2);
1526*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(const_map.at(2), 8);
1527*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_EXCEPTIONS
1528*9356374aSAndroid Build Coastguard Worker   EXPECT_THROW(map.at(3), std::out_of_range);
1529*9356374aSAndroid Build Coastguard Worker #else
1530*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH_IF_SUPPORTED(map.at(3), "absl::btree_map::at");
1531*9356374aSAndroid Build Coastguard Worker #endif
1532*9356374aSAndroid Build Coastguard Worker }
1533*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,BtreeMultisetEmplace)1534*9356374aSAndroid Build Coastguard Worker TEST(Btree, BtreeMultisetEmplace) {
1535*9356374aSAndroid Build Coastguard Worker   const int value_to_insert = 123456;
1536*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> s;
1537*9356374aSAndroid Build Coastguard Worker   auto iter = s.emplace(value_to_insert);
1538*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter, s.end());
1539*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*iter, value_to_insert);
1540*9356374aSAndroid Build Coastguard Worker   iter = s.emplace(value_to_insert);
1541*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter, s.end());
1542*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*iter, value_to_insert);
1543*9356374aSAndroid Build Coastguard Worker   auto result = s.equal_range(value_to_insert);
1544*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::distance(result.first, result.second), 2);
1545*9356374aSAndroid Build Coastguard Worker }
1546*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,BtreeMultisetEmplaceHint)1547*9356374aSAndroid Build Coastguard Worker TEST(Btree, BtreeMultisetEmplaceHint) {
1548*9356374aSAndroid Build Coastguard Worker   const int value_to_insert = 123456;
1549*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> s;
1550*9356374aSAndroid Build Coastguard Worker   auto iter = s.emplace(value_to_insert);
1551*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter, s.end());
1552*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*iter, value_to_insert);
1553*9356374aSAndroid Build Coastguard Worker   iter = s.emplace_hint(iter, value_to_insert);
1554*9356374aSAndroid Build Coastguard Worker   // The new element should be before the previously inserted one.
1555*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, s.lower_bound(value_to_insert));
1556*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter, s.end());
1557*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*iter, value_to_insert);
1558*9356374aSAndroid Build Coastguard Worker }
1559*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,BtreeMultimapEmplace)1560*9356374aSAndroid Build Coastguard Worker TEST(Btree, BtreeMultimapEmplace) {
1561*9356374aSAndroid Build Coastguard Worker   const int key_to_insert = 123456;
1562*9356374aSAndroid Build Coastguard Worker   const char value0[] = "a";
1563*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, std::string> m;
1564*9356374aSAndroid Build Coastguard Worker   auto iter = m.emplace(key_to_insert, value0);
1565*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter, m.end());
1566*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->first, key_to_insert);
1567*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->second, value0);
1568*9356374aSAndroid Build Coastguard Worker   const char value1[] = "b";
1569*9356374aSAndroid Build Coastguard Worker   iter = m.emplace(key_to_insert, value1);
1570*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter, m.end());
1571*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->first, key_to_insert);
1572*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->second, value1);
1573*9356374aSAndroid Build Coastguard Worker   auto result = m.equal_range(key_to_insert);
1574*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::distance(result.first, result.second), 2);
1575*9356374aSAndroid Build Coastguard Worker }
1576*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,BtreeMultimapEmplaceHint)1577*9356374aSAndroid Build Coastguard Worker TEST(Btree, BtreeMultimapEmplaceHint) {
1578*9356374aSAndroid Build Coastguard Worker   const int key_to_insert = 123456;
1579*9356374aSAndroid Build Coastguard Worker   const char value0[] = "a";
1580*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, std::string> m;
1581*9356374aSAndroid Build Coastguard Worker   auto iter = m.emplace(key_to_insert, value0);
1582*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter, m.end());
1583*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->first, key_to_insert);
1584*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->second, value0);
1585*9356374aSAndroid Build Coastguard Worker   const char value1[] = "b";
1586*9356374aSAndroid Build Coastguard Worker   iter = m.emplace_hint(iter, key_to_insert, value1);
1587*9356374aSAndroid Build Coastguard Worker   // The new element should be before the previously inserted one.
1588*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, m.lower_bound(key_to_insert));
1589*9356374aSAndroid Build Coastguard Worker   ASSERT_NE(iter, m.end());
1590*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->first, key_to_insert);
1591*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->second, value1);
1592*9356374aSAndroid Build Coastguard Worker }
1593*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ConstIteratorAccessors)1594*9356374aSAndroid Build Coastguard Worker TEST(Btree, ConstIteratorAccessors) {
1595*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> set;
1596*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
1597*9356374aSAndroid Build Coastguard Worker     set.insert(i);
1598*9356374aSAndroid Build Coastguard Worker   }
1599*9356374aSAndroid Build Coastguard Worker 
1600*9356374aSAndroid Build Coastguard Worker   auto it = set.cbegin();
1601*9356374aSAndroid Build Coastguard Worker   auto r_it = set.crbegin();
1602*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i, ++it, ++r_it) {
1603*9356374aSAndroid Build Coastguard Worker     ASSERT_EQ(*it, i);
1604*9356374aSAndroid Build Coastguard Worker     ASSERT_EQ(*r_it, 99 - i);
1605*9356374aSAndroid Build Coastguard Worker   }
1606*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, set.cend());
1607*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(r_it, set.crend());
1608*9356374aSAndroid Build Coastguard Worker }
1609*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,StrSplitCompatible)1610*9356374aSAndroid Build Coastguard Worker TEST(Btree, StrSplitCompatible) {
1611*9356374aSAndroid Build Coastguard Worker   const absl::btree_set<std::string> split_set = absl::StrSplit("a,b,c", ',');
1612*9356374aSAndroid Build Coastguard Worker   const absl::btree_set<std::string> expected_set = {"a", "b", "c"};
1613*9356374aSAndroid Build Coastguard Worker 
1614*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(split_set, expected_set);
1615*9356374aSAndroid Build Coastguard Worker }
1616*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,KeyComp)1617*9356374aSAndroid Build Coastguard Worker TEST(Btree, KeyComp) {
1618*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> s;
1619*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(s.key_comp()(1, 2));
1620*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(s.key_comp()(2, 2));
1621*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(s.key_comp()(2, 1));
1622*9356374aSAndroid Build Coastguard Worker 
1623*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> m1;
1624*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(m1.key_comp()(1, 2));
1625*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m1.key_comp()(2, 2));
1626*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m1.key_comp()(2, 1));
1627*9356374aSAndroid Build Coastguard Worker 
1628*9356374aSAndroid Build Coastguard Worker   // Even though we internally adapt the comparator of `m2` to be three-way and
1629*9356374aSAndroid Build Coastguard Worker   // heterogeneous, the comparator we expose through key_comp() is the original
1630*9356374aSAndroid Build Coastguard Worker   // unadapted comparator.
1631*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int> m2;
1632*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(m2.key_comp()("a", "b"));
1633*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m2.key_comp()("b", "b"));
1634*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m2.key_comp()("b", "a"));
1635*9356374aSAndroid Build Coastguard Worker }
1636*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ValueComp)1637*9356374aSAndroid Build Coastguard Worker TEST(Btree, ValueComp) {
1638*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> s;
1639*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(s.value_comp()(1, 2));
1640*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(s.value_comp()(2, 2));
1641*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(s.value_comp()(2, 1));
1642*9356374aSAndroid Build Coastguard Worker 
1643*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> m1;
1644*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(m1.value_comp()(std::make_pair(1, 0), std::make_pair(2, 0)));
1645*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m1.value_comp()(std::make_pair(2, 0), std::make_pair(2, 0)));
1646*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m1.value_comp()(std::make_pair(2, 0), std::make_pair(1, 0)));
1647*9356374aSAndroid Build Coastguard Worker 
1648*9356374aSAndroid Build Coastguard Worker   // Even though we internally adapt the comparator of `m2` to be three-way and
1649*9356374aSAndroid Build Coastguard Worker   // heterogeneous, the comparator we expose through value_comp() is based on
1650*9356374aSAndroid Build Coastguard Worker   // the original unadapted comparator.
1651*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int> m2;
1652*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(m2.value_comp()(std::make_pair("a", 0), std::make_pair("b", 0)));
1653*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("b", 0)));
1654*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(m2.value_comp()(std::make_pair("b", 0), std::make_pair("a", 0)));
1655*9356374aSAndroid Build Coastguard Worker }
1656*9356374aSAndroid Build Coastguard Worker 
1657*9356374aSAndroid Build Coastguard Worker // Test that we have the protected members from the std::map::value_compare API.
1658*9356374aSAndroid Build Coastguard Worker // See https://en.cppreference.com/w/cpp/container/map/value_compare.
TEST(Btree,MapValueCompProtected)1659*9356374aSAndroid Build Coastguard Worker TEST(Btree, MapValueCompProtected) {
1660*9356374aSAndroid Build Coastguard Worker   struct key_compare {
1661*9356374aSAndroid Build Coastguard Worker     bool operator()(int l, int r) const { return l < r; }
1662*9356374aSAndroid Build Coastguard Worker     int id;
1663*9356374aSAndroid Build Coastguard Worker   };
1664*9356374aSAndroid Build Coastguard Worker   using value_compare = absl::btree_map<int, int, key_compare>::value_compare;
1665*9356374aSAndroid Build Coastguard Worker   struct value_comp_child : public value_compare {
1666*9356374aSAndroid Build Coastguard Worker     explicit value_comp_child(key_compare kc) : value_compare(kc) {}
1667*9356374aSAndroid Build Coastguard Worker     int GetId() const { return comp.id; }
1668*9356374aSAndroid Build Coastguard Worker   };
1669*9356374aSAndroid Build Coastguard Worker   value_comp_child c(key_compare{10});
1670*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(c.GetId(), 10);
1671*9356374aSAndroid Build Coastguard Worker }
1672*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,DefaultConstruction)1673*9356374aSAndroid Build Coastguard Worker TEST(Btree, DefaultConstruction) {
1674*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> s;
1675*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> m;
1676*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> ms;
1677*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> mm;
1678*9356374aSAndroid Build Coastguard Worker 
1679*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(s.empty());
1680*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(m.empty());
1681*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(ms.empty());
1682*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(mm.empty());
1683*9356374aSAndroid Build Coastguard Worker }
1684*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,SwissTableHashable)1685*9356374aSAndroid Build Coastguard Worker TEST(Btree, SwissTableHashable) {
1686*9356374aSAndroid Build Coastguard Worker   static constexpr int kValues = 10000;
1687*9356374aSAndroid Build Coastguard Worker   std::vector<int> values(kValues);
1688*9356374aSAndroid Build Coastguard Worker   std::iota(values.begin(), values.end(), 0);
1689*9356374aSAndroid Build Coastguard Worker   std::vector<std::pair<int, int>> map_values;
1690*9356374aSAndroid Build Coastguard Worker   for (int v : values) map_values.emplace_back(v, -v);
1691*9356374aSAndroid Build Coastguard Worker 
1692*9356374aSAndroid Build Coastguard Worker   using set = absl::btree_set<int>;
1693*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1694*9356374aSAndroid Build Coastguard Worker       set{},
1695*9356374aSAndroid Build Coastguard Worker       set{1},
1696*9356374aSAndroid Build Coastguard Worker       set{2},
1697*9356374aSAndroid Build Coastguard Worker       set{1, 2},
1698*9356374aSAndroid Build Coastguard Worker       set{2, 1},
1699*9356374aSAndroid Build Coastguard Worker       set(values.begin(), values.end()),
1700*9356374aSAndroid Build Coastguard Worker       set(values.rbegin(), values.rend()),
1701*9356374aSAndroid Build Coastguard Worker   }));
1702*9356374aSAndroid Build Coastguard Worker 
1703*9356374aSAndroid Build Coastguard Worker   using mset = absl::btree_multiset<int>;
1704*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1705*9356374aSAndroid Build Coastguard Worker       mset{},
1706*9356374aSAndroid Build Coastguard Worker       mset{1},
1707*9356374aSAndroid Build Coastguard Worker       mset{1, 1},
1708*9356374aSAndroid Build Coastguard Worker       mset{2},
1709*9356374aSAndroid Build Coastguard Worker       mset{2, 2},
1710*9356374aSAndroid Build Coastguard Worker       mset{1, 2},
1711*9356374aSAndroid Build Coastguard Worker       mset{1, 1, 2},
1712*9356374aSAndroid Build Coastguard Worker       mset{1, 2, 2},
1713*9356374aSAndroid Build Coastguard Worker       mset{1, 1, 2, 2},
1714*9356374aSAndroid Build Coastguard Worker       mset(values.begin(), values.end()),
1715*9356374aSAndroid Build Coastguard Worker       mset(values.rbegin(), values.rend()),
1716*9356374aSAndroid Build Coastguard Worker   }));
1717*9356374aSAndroid Build Coastguard Worker 
1718*9356374aSAndroid Build Coastguard Worker   using map = absl::btree_map<int, int>;
1719*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1720*9356374aSAndroid Build Coastguard Worker       map{},
1721*9356374aSAndroid Build Coastguard Worker       map{{1, 0}},
1722*9356374aSAndroid Build Coastguard Worker       map{{1, 1}},
1723*9356374aSAndroid Build Coastguard Worker       map{{2, 0}},
1724*9356374aSAndroid Build Coastguard Worker       map{{2, 2}},
1725*9356374aSAndroid Build Coastguard Worker       map{{1, 0}, {2, 1}},
1726*9356374aSAndroid Build Coastguard Worker       map(map_values.begin(), map_values.end()),
1727*9356374aSAndroid Build Coastguard Worker       map(map_values.rbegin(), map_values.rend()),
1728*9356374aSAndroid Build Coastguard Worker   }));
1729*9356374aSAndroid Build Coastguard Worker 
1730*9356374aSAndroid Build Coastguard Worker   using mmap = absl::btree_multimap<int, int>;
1731*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
1732*9356374aSAndroid Build Coastguard Worker       mmap{},
1733*9356374aSAndroid Build Coastguard Worker       mmap{{1, 0}},
1734*9356374aSAndroid Build Coastguard Worker       mmap{{1, 1}},
1735*9356374aSAndroid Build Coastguard Worker       mmap{{1, 0}, {1, 1}},
1736*9356374aSAndroid Build Coastguard Worker       mmap{{1, 1}, {1, 0}},
1737*9356374aSAndroid Build Coastguard Worker       mmap{{2, 0}},
1738*9356374aSAndroid Build Coastguard Worker       mmap{{2, 2}},
1739*9356374aSAndroid Build Coastguard Worker       mmap{{1, 0}, {2, 1}},
1740*9356374aSAndroid Build Coastguard Worker       mmap(map_values.begin(), map_values.end()),
1741*9356374aSAndroid Build Coastguard Worker       mmap(map_values.rbegin(), map_values.rend()),
1742*9356374aSAndroid Build Coastguard Worker   }));
1743*9356374aSAndroid Build Coastguard Worker }
1744*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ComparableSet)1745*9356374aSAndroid Build Coastguard Worker TEST(Btree, ComparableSet) {
1746*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> s1 = {1, 2};
1747*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> s2 = {2, 3};
1748*9356374aSAndroid Build Coastguard Worker   EXPECT_LT(s1, s2);
1749*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s2);
1750*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s1);
1751*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(s2, s1);
1752*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s2, s1);
1753*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s1, s1);
1754*9356374aSAndroid Build Coastguard Worker }
1755*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ComparableSetsDifferentLength)1756*9356374aSAndroid Build Coastguard Worker TEST(Btree, ComparableSetsDifferentLength) {
1757*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> s1 = {1, 2};
1758*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> s2 = {1, 2, 3};
1759*9356374aSAndroid Build Coastguard Worker   EXPECT_LT(s1, s2);
1760*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s2);
1761*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(s2, s1);
1762*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s2, s1);
1763*9356374aSAndroid Build Coastguard Worker }
1764*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ComparableMultiset)1765*9356374aSAndroid Build Coastguard Worker TEST(Btree, ComparableMultiset) {
1766*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> s1 = {1, 2};
1767*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> s2 = {2, 3};
1768*9356374aSAndroid Build Coastguard Worker   EXPECT_LT(s1, s2);
1769*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s2);
1770*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s1);
1771*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(s2, s1);
1772*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s2, s1);
1773*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s1, s1);
1774*9356374aSAndroid Build Coastguard Worker }
1775*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ComparableMap)1776*9356374aSAndroid Build Coastguard Worker TEST(Btree, ComparableMap) {
1777*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> s1 = {{1, 2}};
1778*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> s2 = {{2, 3}};
1779*9356374aSAndroid Build Coastguard Worker   EXPECT_LT(s1, s2);
1780*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s2);
1781*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s1);
1782*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(s2, s1);
1783*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s2, s1);
1784*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s1, s1);
1785*9356374aSAndroid Build Coastguard Worker }
1786*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ComparableMultimap)1787*9356374aSAndroid Build Coastguard Worker TEST(Btree, ComparableMultimap) {
1788*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> s1 = {{1, 2}};
1789*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> s2 = {{2, 3}};
1790*9356374aSAndroid Build Coastguard Worker   EXPECT_LT(s1, s2);
1791*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s2);
1792*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s1);
1793*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(s2, s1);
1794*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s2, s1);
1795*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s1, s1);
1796*9356374aSAndroid Build Coastguard Worker }
1797*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ComparableSetWithCustomComparator)1798*9356374aSAndroid Build Coastguard Worker TEST(Btree, ComparableSetWithCustomComparator) {
1799*9356374aSAndroid Build Coastguard Worker   // As specified by
1800*9356374aSAndroid Build Coastguard Worker   // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf section
1801*9356374aSAndroid Build Coastguard Worker   // [container.requirements.general].12, ordering associative containers always
1802*9356374aSAndroid Build Coastguard Worker   // uses default '<' operator
1803*9356374aSAndroid Build Coastguard Worker   // - even if otherwise the container uses custom functor.
1804*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, std::greater<int>> s1 = {1, 2};
1805*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, std::greater<int>> s2 = {2, 3};
1806*9356374aSAndroid Build Coastguard Worker   EXPECT_LT(s1, s2);
1807*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s2);
1808*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(s1, s1);
1809*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(s2, s1);
1810*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s2, s1);
1811*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(s1, s1);
1812*9356374aSAndroid Build Coastguard Worker }
1813*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,EraseReturnsIterator)1814*9356374aSAndroid Build Coastguard Worker TEST(Btree, EraseReturnsIterator) {
1815*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> set = {1, 2, 3, 4, 5};
1816*9356374aSAndroid Build Coastguard Worker   auto result_it = set.erase(set.begin(), set.find(3));
1817*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result_it, set.find(3));
1818*9356374aSAndroid Build Coastguard Worker   result_it = set.erase(set.find(5));
1819*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result_it, set.end());
1820*9356374aSAndroid Build Coastguard Worker }
1821*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndInsertNodeHandleSet)1822*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndInsertNodeHandleSet) {
1823*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> src1 = {1, 2, 3, 4, 5};
1824*9356374aSAndroid Build Coastguard Worker   auto nh = src1.extract(src1.find(3));
1825*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src1, ElementsAre(1, 2, 4, 5));
1826*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> other;
1827*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int>::insert_return_type res = other.insert(std::move(nh));
1828*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other, ElementsAre(3));
1829*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res.position, other.find(3));
1830*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(res.inserted);
1831*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(res.node.empty());
1832*9356374aSAndroid Build Coastguard Worker 
1833*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> src2 = {3, 4};
1834*9356374aSAndroid Build Coastguard Worker   nh = src2.extract(src2.find(3));
1835*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src2, ElementsAre(4));
1836*9356374aSAndroid Build Coastguard Worker   res = other.insert(std::move(nh));
1837*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other, ElementsAre(3));
1838*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res.position, other.find(3));
1839*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(res.inserted);
1840*9356374aSAndroid Build Coastguard Worker   ASSERT_FALSE(res.node.empty());
1841*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res.node.value(), 3);
1842*9356374aSAndroid Build Coastguard Worker }
1843*9356374aSAndroid Build Coastguard Worker 
1844*9356374aSAndroid Build Coastguard Worker template <typename Set>
TestExtractWithTrackingForSet()1845*9356374aSAndroid Build Coastguard Worker void TestExtractWithTrackingForSet() {
1846*9356374aSAndroid Build Coastguard Worker   InstanceTracker tracker;
1847*9356374aSAndroid Build Coastguard Worker   {
1848*9356374aSAndroid Build Coastguard Worker     Set s;
1849*9356374aSAndroid Build Coastguard Worker     // Add enough elements to make sure we test internal nodes too.
1850*9356374aSAndroid Build Coastguard Worker     const size_t kSize = 1000;
1851*9356374aSAndroid Build Coastguard Worker     while (s.size() < kSize) {
1852*9356374aSAndroid Build Coastguard Worker       s.insert(MovableOnlyInstance(s.size()));
1853*9356374aSAndroid Build Coastguard Worker     }
1854*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i < kSize; ++i) {
1855*9356374aSAndroid Build Coastguard Worker       // Extract with key
1856*9356374aSAndroid Build Coastguard Worker       auto nh = s.extract(MovableOnlyInstance(i));
1857*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(s.size(), kSize - 1);
1858*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(nh.value().value(), i);
1859*9356374aSAndroid Build Coastguard Worker       // Insert with node
1860*9356374aSAndroid Build Coastguard Worker       s.insert(std::move(nh));
1861*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(s.size(), kSize);
1862*9356374aSAndroid Build Coastguard Worker 
1863*9356374aSAndroid Build Coastguard Worker       // Extract with iterator
1864*9356374aSAndroid Build Coastguard Worker       auto it = s.find(MovableOnlyInstance(i));
1865*9356374aSAndroid Build Coastguard Worker       nh = s.extract(it);
1866*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(s.size(), kSize - 1);
1867*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(nh.value().value(), i);
1868*9356374aSAndroid Build Coastguard Worker       // Insert with node and hint
1869*9356374aSAndroid Build Coastguard Worker       s.insert(s.begin(), std::move(nh));
1870*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(s.size(), kSize);
1871*9356374aSAndroid Build Coastguard Worker     }
1872*9356374aSAndroid Build Coastguard Worker   }
1873*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(0, tracker.instances());
1874*9356374aSAndroid Build Coastguard Worker }
1875*9356374aSAndroid Build Coastguard Worker 
1876*9356374aSAndroid Build Coastguard Worker template <typename Map>
TestExtractWithTrackingForMap()1877*9356374aSAndroid Build Coastguard Worker void TestExtractWithTrackingForMap() {
1878*9356374aSAndroid Build Coastguard Worker   InstanceTracker tracker;
1879*9356374aSAndroid Build Coastguard Worker   {
1880*9356374aSAndroid Build Coastguard Worker     Map m;
1881*9356374aSAndroid Build Coastguard Worker     // Add enough elements to make sure we test internal nodes too.
1882*9356374aSAndroid Build Coastguard Worker     const size_t kSize = 1000;
1883*9356374aSAndroid Build Coastguard Worker     while (m.size() < kSize) {
1884*9356374aSAndroid Build Coastguard Worker       m.insert(
1885*9356374aSAndroid Build Coastguard Worker           {CopyableMovableInstance(m.size()), MovableOnlyInstance(m.size())});
1886*9356374aSAndroid Build Coastguard Worker     }
1887*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i < kSize; ++i) {
1888*9356374aSAndroid Build Coastguard Worker       // Extract with key
1889*9356374aSAndroid Build Coastguard Worker       auto nh = m.extract(CopyableMovableInstance(i));
1890*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(m.size(), kSize - 1);
1891*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(nh.key().value(), i);
1892*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(nh.mapped().value(), i);
1893*9356374aSAndroid Build Coastguard Worker       // Insert with node
1894*9356374aSAndroid Build Coastguard Worker       m.insert(std::move(nh));
1895*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(m.size(), kSize);
1896*9356374aSAndroid Build Coastguard Worker 
1897*9356374aSAndroid Build Coastguard Worker       // Extract with iterator
1898*9356374aSAndroid Build Coastguard Worker       auto it = m.find(CopyableMovableInstance(i));
1899*9356374aSAndroid Build Coastguard Worker       nh = m.extract(it);
1900*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(m.size(), kSize - 1);
1901*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(nh.key().value(), i);
1902*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(nh.mapped().value(), i);
1903*9356374aSAndroid Build Coastguard Worker       // Insert with node and hint
1904*9356374aSAndroid Build Coastguard Worker       m.insert(m.begin(), std::move(nh));
1905*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(m.size(), kSize);
1906*9356374aSAndroid Build Coastguard Worker     }
1907*9356374aSAndroid Build Coastguard Worker   }
1908*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(0, tracker.instances());
1909*9356374aSAndroid Build Coastguard Worker }
1910*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractTracking)1911*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractTracking) {
1912*9356374aSAndroid Build Coastguard Worker   TestExtractWithTrackingForSet<absl::btree_set<MovableOnlyInstance>>();
1913*9356374aSAndroid Build Coastguard Worker   TestExtractWithTrackingForSet<absl::btree_multiset<MovableOnlyInstance>>();
1914*9356374aSAndroid Build Coastguard Worker   TestExtractWithTrackingForMap<
1915*9356374aSAndroid Build Coastguard Worker       absl::btree_map<CopyableMovableInstance, MovableOnlyInstance>>();
1916*9356374aSAndroid Build Coastguard Worker   TestExtractWithTrackingForMap<
1917*9356374aSAndroid Build Coastguard Worker       absl::btree_multimap<CopyableMovableInstance, MovableOnlyInstance>>();
1918*9356374aSAndroid Build Coastguard Worker }
1919*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndInsertNodeHandleMultiSet)1920*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndInsertNodeHandleMultiSet) {
1921*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> src1 = {1, 2, 3, 3, 4, 5};
1922*9356374aSAndroid Build Coastguard Worker   auto nh = src1.extract(src1.find(3));
1923*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src1, ElementsAre(1, 2, 3, 4, 5));
1924*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> other;
1925*9356374aSAndroid Build Coastguard Worker   auto res = other.insert(std::move(nh));
1926*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other, ElementsAre(3));
1927*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res, other.find(3));
1928*9356374aSAndroid Build Coastguard Worker 
1929*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> src2 = {3, 4};
1930*9356374aSAndroid Build Coastguard Worker   nh = src2.extract(src2.find(3));
1931*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src2, ElementsAre(4));
1932*9356374aSAndroid Build Coastguard Worker   res = other.insert(std::move(nh));
1933*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other, ElementsAre(3, 3));
1934*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res, ++other.find(3));
1935*9356374aSAndroid Build Coastguard Worker }
1936*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndInsertNodeHandleMap)1937*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndInsertNodeHandleMap) {
1938*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> src1 = {{1, 2}, {3, 4}, {5, 6}};
1939*9356374aSAndroid Build Coastguard Worker   auto nh = src1.extract(src1.find(3));
1940*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src1, ElementsAre(Pair(1, 2), Pair(5, 6)));
1941*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> other;
1942*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int>::insert_return_type res =
1943*9356374aSAndroid Build Coastguard Worker       other.insert(std::move(nh));
1944*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
1945*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res.position, other.find(3));
1946*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(res.inserted);
1947*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(res.node.empty());
1948*9356374aSAndroid Build Coastguard Worker 
1949*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> src2 = {{3, 6}};
1950*9356374aSAndroid Build Coastguard Worker   nh = src2.extract(src2.find(3));
1951*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src2.empty());
1952*9356374aSAndroid Build Coastguard Worker   res = other.insert(std::move(nh));
1953*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
1954*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res.position, other.find(3));
1955*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(res.inserted);
1956*9356374aSAndroid Build Coastguard Worker   ASSERT_FALSE(res.node.empty());
1957*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res.node.key(), 3);
1958*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res.node.mapped(), 6);
1959*9356374aSAndroid Build Coastguard Worker }
1960*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndInsertNodeHandleMultiMap)1961*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndInsertNodeHandleMultiMap) {
1962*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> src1 = {{1, 2}, {3, 4}, {5, 6}};
1963*9356374aSAndroid Build Coastguard Worker   auto nh = src1.extract(src1.find(3));
1964*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src1, ElementsAre(Pair(1, 2), Pair(5, 6)));
1965*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> other;
1966*9356374aSAndroid Build Coastguard Worker   auto res = other.insert(std::move(nh));
1967*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other, ElementsAre(Pair(3, 4)));
1968*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res, other.find(3));
1969*9356374aSAndroid Build Coastguard Worker 
1970*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> src2 = {{3, 6}};
1971*9356374aSAndroid Build Coastguard Worker   nh = src2.extract(src2.find(3));
1972*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src2.empty());
1973*9356374aSAndroid Build Coastguard Worker   res = other.insert(std::move(nh));
1974*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other, ElementsAre(Pair(3, 4), Pair(3, 6)));
1975*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(res, ++other.begin());
1976*9356374aSAndroid Build Coastguard Worker }
1977*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractMultiMapEquivalentKeys)1978*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractMultiMapEquivalentKeys) {
1979*9356374aSAndroid Build Coastguard Worker   // Note: using string keys means a three-way comparator.
1980*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<std::string, int> map;
1981*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
1982*9356374aSAndroid Build Coastguard Worker     for (int j = 0; j < 100; ++j) {
1983*9356374aSAndroid Build Coastguard Worker       map.insert({absl::StrCat(i), j});
1984*9356374aSAndroid Build Coastguard Worker     }
1985*9356374aSAndroid Build Coastguard Worker   }
1986*9356374aSAndroid Build Coastguard Worker 
1987*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
1988*9356374aSAndroid Build Coastguard Worker     const std::string key = absl::StrCat(i);
1989*9356374aSAndroid Build Coastguard Worker     auto node_handle = map.extract(key);
1990*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(node_handle.key(), key);
1991*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(node_handle.mapped(), 0) << i;
1992*9356374aSAndroid Build Coastguard Worker   }
1993*9356374aSAndroid Build Coastguard Worker 
1994*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
1995*9356374aSAndroid Build Coastguard Worker     const std::string key = absl::StrCat(i);
1996*9356374aSAndroid Build Coastguard Worker     auto node_handle = map.extract(key);
1997*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(node_handle.key(), key);
1998*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(node_handle.mapped(), 1) << i;
1999*9356374aSAndroid Build Coastguard Worker   }
2000*9356374aSAndroid Build Coastguard Worker }
2001*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndGetNextSet)2002*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndGetNextSet) {
2003*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> src = {1, 2, 3, 4, 5};
2004*9356374aSAndroid Build Coastguard Worker   auto it = src.find(3);
2005*9356374aSAndroid Build Coastguard Worker   auto extracted_and_next = src.extract_and_get_next(it);
2006*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2007*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(extracted_and_next.node.value(), 3);
2008*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*extracted_and_next.next, 4);
2009*9356374aSAndroid Build Coastguard Worker }
2010*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndGetNextMultiSet)2011*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndGetNextMultiSet) {
2012*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> src = {1, 2, 3, 4, 5};
2013*9356374aSAndroid Build Coastguard Worker   auto it = src.find(3);
2014*9356374aSAndroid Build Coastguard Worker   auto extracted_and_next = src.extract_and_get_next(it);
2015*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2016*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(extracted_and_next.node.value(), 3);
2017*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*extracted_and_next.next, 4);
2018*9356374aSAndroid Build Coastguard Worker }
2019*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndGetNextMap)2020*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndGetNextMap) {
2021*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> src = {{1, 2}, {3, 4}, {5, 6}};
2022*9356374aSAndroid Build Coastguard Worker   auto it = src.find(3);
2023*9356374aSAndroid Build Coastguard Worker   auto extracted_and_next = src.extract_and_get_next(it);
2024*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src, ElementsAre(Pair(1, 2), Pair(5, 6)));
2025*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(extracted_and_next.node.key(), 3);
2026*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(extracted_and_next.node.mapped(), 4);
2027*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(*extracted_and_next.next, Pair(5, 6));
2028*9356374aSAndroid Build Coastguard Worker }
2029*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndGetNextMultiMap)2030*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndGetNextMultiMap) {
2031*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> src = {{1, 2}, {3, 4}, {5, 6}};
2032*9356374aSAndroid Build Coastguard Worker   auto it = src.find(3);
2033*9356374aSAndroid Build Coastguard Worker   auto extracted_and_next = src.extract_and_get_next(it);
2034*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src, ElementsAre(Pair(1, 2), Pair(5, 6)));
2035*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(extracted_and_next.node.key(), 3);
2036*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(extracted_and_next.node.mapped(), 4);
2037*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(*extracted_and_next.next, Pair(5, 6));
2038*9356374aSAndroid Build Coastguard Worker }
2039*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractAndGetNextEndIter)2040*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractAndGetNextEndIter) {
2041*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> src = {1, 2, 3, 4, 5};
2042*9356374aSAndroid Build Coastguard Worker   auto it = src.find(5);
2043*9356374aSAndroid Build Coastguard Worker   auto extracted_and_next = src.extract_and_get_next(it);
2044*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src, ElementsAre(1, 2, 3, 4));
2045*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(extracted_and_next.node.value(), 5);
2046*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(extracted_and_next.next, src.end());
2047*9356374aSAndroid Build Coastguard Worker }
2048*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ExtractDoesntCauseExtraMoves)2049*9356374aSAndroid Build Coastguard Worker TEST(Btree, ExtractDoesntCauseExtraMoves) {
2050*9356374aSAndroid Build Coastguard Worker #ifdef _MSC_VER
2051*9356374aSAndroid Build Coastguard Worker   GTEST_SKIP() << "This test fails on MSVC.";
2052*9356374aSAndroid Build Coastguard Worker #endif
2053*9356374aSAndroid Build Coastguard Worker 
2054*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<MovableOnlyInstance>;
2055*9356374aSAndroid Build Coastguard Worker   std::array<std::function<void(Set &)>, 3> extracters = {
2056*9356374aSAndroid Build Coastguard Worker       [](Set &s) { auto node = s.extract(s.begin()); },
2057*9356374aSAndroid Build Coastguard Worker       [](Set &s) { auto ret = s.extract_and_get_next(s.begin()); },
2058*9356374aSAndroid Build Coastguard Worker       [](Set &s) { auto node = s.extract(MovableOnlyInstance(0)); }};
2059*9356374aSAndroid Build Coastguard Worker 
2060*9356374aSAndroid Build Coastguard Worker   InstanceTracker tracker;
2061*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 3; ++i) {
2062*9356374aSAndroid Build Coastguard Worker     Set s;
2063*9356374aSAndroid Build Coastguard Worker     s.insert(MovableOnlyInstance(0));
2064*9356374aSAndroid Build Coastguard Worker     tracker.ResetCopiesMovesSwaps();
2065*9356374aSAndroid Build Coastguard Worker 
2066*9356374aSAndroid Build Coastguard Worker     extracters[i](s);
2067*9356374aSAndroid Build Coastguard Worker     // We expect to see exactly 1 move: from the original slot into the
2068*9356374aSAndroid Build Coastguard Worker     // extracted node.
2069*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tracker.copies(), 0) << i;
2070*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tracker.moves(), 1) << i;
2071*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tracker.swaps(), 0) << i;
2072*9356374aSAndroid Build Coastguard Worker   }
2073*9356374aSAndroid Build Coastguard Worker }
2074*9356374aSAndroid Build Coastguard Worker 
2075*9356374aSAndroid Build Coastguard Worker // For multisets, insert with hint also affects correctness because we need to
2076*9356374aSAndroid Build Coastguard Worker // insert immediately before the hint if possible.
2077*9356374aSAndroid Build Coastguard Worker struct InsertMultiHintData {
2078*9356374aSAndroid Build Coastguard Worker   int key;
2079*9356374aSAndroid Build Coastguard Worker   int not_key;
operator ==absl::container_internal::__anon7e8713fe0311::InsertMultiHintData2080*9356374aSAndroid Build Coastguard Worker   bool operator==(const InsertMultiHintData other) const {
2081*9356374aSAndroid Build Coastguard Worker     return key == other.key && not_key == other.not_key;
2082*9356374aSAndroid Build Coastguard Worker   }
2083*9356374aSAndroid Build Coastguard Worker };
2084*9356374aSAndroid Build Coastguard Worker 
2085*9356374aSAndroid Build Coastguard Worker struct InsertMultiHintDataKeyCompare {
2086*9356374aSAndroid Build Coastguard Worker   using is_transparent = void;
operator ()absl::container_internal::__anon7e8713fe0311::InsertMultiHintDataKeyCompare2087*9356374aSAndroid Build Coastguard Worker   bool operator()(const InsertMultiHintData a,
2088*9356374aSAndroid Build Coastguard Worker                   const InsertMultiHintData b) const {
2089*9356374aSAndroid Build Coastguard Worker     return a.key < b.key;
2090*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0311::InsertMultiHintDataKeyCompare2091*9356374aSAndroid Build Coastguard Worker   bool operator()(const int a, const InsertMultiHintData b) const {
2092*9356374aSAndroid Build Coastguard Worker     return a < b.key;
2093*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0311::InsertMultiHintDataKeyCompare2094*9356374aSAndroid Build Coastguard Worker   bool operator()(const InsertMultiHintData a, const int b) const {
2095*9356374aSAndroid Build Coastguard Worker     return a.key < b;
2096*9356374aSAndroid Build Coastguard Worker   }
2097*9356374aSAndroid Build Coastguard Worker };
2098*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,InsertHintNodeHandle)2099*9356374aSAndroid Build Coastguard Worker TEST(Btree, InsertHintNodeHandle) {
2100*9356374aSAndroid Build Coastguard Worker   // For unique sets, insert with hint is just a performance optimization.
2101*9356374aSAndroid Build Coastguard Worker   // Test that insert works correctly when the hint is right or wrong.
2102*9356374aSAndroid Build Coastguard Worker   {
2103*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> src = {1, 2, 3, 4, 5};
2104*9356374aSAndroid Build Coastguard Worker     auto nh = src.extract(src.find(3));
2105*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(src, ElementsAre(1, 2, 4, 5));
2106*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> other = {0, 100};
2107*9356374aSAndroid Build Coastguard Worker     // Test a correct hint.
2108*9356374aSAndroid Build Coastguard Worker     auto it = other.insert(other.lower_bound(3), std::move(nh));
2109*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(other, ElementsAre(0, 3, 100));
2110*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(it, other.find(3));
2111*9356374aSAndroid Build Coastguard Worker 
2112*9356374aSAndroid Build Coastguard Worker     nh = src.extract(src.find(5));
2113*9356374aSAndroid Build Coastguard Worker     // Test an incorrect hint.
2114*9356374aSAndroid Build Coastguard Worker     it = other.insert(other.end(), std::move(nh));
2115*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(other, ElementsAre(0, 3, 5, 100));
2116*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(it, other.find(5));
2117*9356374aSAndroid Build Coastguard Worker   }
2118*9356374aSAndroid Build Coastguard Worker 
2119*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<InsertMultiHintData, InsertMultiHintDataKeyCompare> src =
2120*9356374aSAndroid Build Coastguard Worker       {{1, 2}, {3, 4}, {3, 5}};
2121*9356374aSAndroid Build Coastguard Worker   auto nh = src.extract(src.lower_bound(3));
2122*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(nh.value(), (InsertMultiHintData{3, 4}));
2123*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<InsertMultiHintData, InsertMultiHintDataKeyCompare>
2124*9356374aSAndroid Build Coastguard Worker       other = {{3, 1}, {3, 2}, {3, 3}};
2125*9356374aSAndroid Build Coastguard Worker   auto it = other.insert(--other.end(), std::move(nh));
2126*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(
2127*9356374aSAndroid Build Coastguard Worker       other, ElementsAre(InsertMultiHintData{3, 1}, InsertMultiHintData{3, 2},
2128*9356374aSAndroid Build Coastguard Worker                          InsertMultiHintData{3, 4}, InsertMultiHintData{3, 3}));
2129*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, --(--other.end()));
2130*9356374aSAndroid Build Coastguard Worker 
2131*9356374aSAndroid Build Coastguard Worker   nh = src.extract(src.find(3));
2132*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(nh.value(), (InsertMultiHintData{3, 5}));
2133*9356374aSAndroid Build Coastguard Worker   it = other.insert(other.begin(), std::move(nh));
2134*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(other,
2135*9356374aSAndroid Build Coastguard Worker               ElementsAre(InsertMultiHintData{3, 5}, InsertMultiHintData{3, 1},
2136*9356374aSAndroid Build Coastguard Worker                           InsertMultiHintData{3, 2}, InsertMultiHintData{3, 4},
2137*9356374aSAndroid Build Coastguard Worker                           InsertMultiHintData{3, 3}));
2138*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, other.begin());
2139*9356374aSAndroid Build Coastguard Worker }
2140*9356374aSAndroid Build Coastguard Worker 
2141*9356374aSAndroid Build Coastguard Worker struct IntCompareToCmp {
operator ()absl::container_internal::__anon7e8713fe0311::IntCompareToCmp2142*9356374aSAndroid Build Coastguard Worker   absl::weak_ordering operator()(int a, int b) const {
2143*9356374aSAndroid Build Coastguard Worker     if (a < b) return absl::weak_ordering::less;
2144*9356374aSAndroid Build Coastguard Worker     if (a > b) return absl::weak_ordering::greater;
2145*9356374aSAndroid Build Coastguard Worker     return absl::weak_ordering::equivalent;
2146*9356374aSAndroid Build Coastguard Worker   }
2147*9356374aSAndroid Build Coastguard Worker };
2148*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MergeIntoUniqueContainers)2149*9356374aSAndroid Build Coastguard Worker TEST(Btree, MergeIntoUniqueContainers) {
2150*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2151*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2152*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> dst;
2153*9356374aSAndroid Build Coastguard Worker 
2154*9356374aSAndroid Build Coastguard Worker   dst.merge(src1);
2155*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src1.empty());
2156*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2157*9356374aSAndroid Build Coastguard Worker   dst.merge(src2);
2158*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src2, ElementsAre(3, 4));
2159*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(1, 2, 3, 4, 5));
2160*9356374aSAndroid Build Coastguard Worker }
2161*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MergeIntoUniqueContainersWithCompareTo)2162*9356374aSAndroid Build Coastguard Worker TEST(Btree, MergeIntoUniqueContainersWithCompareTo) {
2163*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2164*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2165*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, IntCompareToCmp> dst;
2166*9356374aSAndroid Build Coastguard Worker 
2167*9356374aSAndroid Build Coastguard Worker   dst.merge(src1);
2168*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src1.empty());
2169*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2170*9356374aSAndroid Build Coastguard Worker   dst.merge(src2);
2171*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(src2, ElementsAre(3, 4));
2172*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(1, 2, 3, 4, 5));
2173*9356374aSAndroid Build Coastguard Worker }
2174*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MergeIntoMultiContainers)2175*9356374aSAndroid Build Coastguard Worker TEST(Btree, MergeIntoMultiContainers) {
2176*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2177*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2178*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> dst;
2179*9356374aSAndroid Build Coastguard Worker 
2180*9356374aSAndroid Build Coastguard Worker   dst.merge(src1);
2181*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src1.empty());
2182*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2183*9356374aSAndroid Build Coastguard Worker   dst.merge(src2);
2184*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src2.empty());
2185*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(1, 2, 3, 3, 4, 4, 5));
2186*9356374aSAndroid Build Coastguard Worker }
2187*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MergeIntoMultiContainersWithCompareTo)2188*9356374aSAndroid Build Coastguard Worker TEST(Btree, MergeIntoMultiContainersWithCompareTo) {
2189*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, IntCompareToCmp> src1 = {1, 2, 3};
2190*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int> src2 = {3, 4, 4, 5};
2191*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<int, IntCompareToCmp> dst;
2192*9356374aSAndroid Build Coastguard Worker 
2193*9356374aSAndroid Build Coastguard Worker   dst.merge(src1);
2194*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src1.empty());
2195*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(1, 2, 3));
2196*9356374aSAndroid Build Coastguard Worker   dst.merge(src2);
2197*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src2.empty());
2198*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(1, 2, 3, 3, 4, 4, 5));
2199*9356374aSAndroid Build Coastguard Worker }
2200*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MergeIntoMultiMapsWithDifferentComparators)2201*9356374aSAndroid Build Coastguard Worker TEST(Btree, MergeIntoMultiMapsWithDifferentComparators) {
2202*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int, IntCompareToCmp> src1 = {{1, 1}, {2, 2}, {3, 3}};
2203*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int, std::greater<int>> src2 = {
2204*9356374aSAndroid Build Coastguard Worker       {5, 5}, {4, 1}, {4, 4}, {3, 2}};
2205*9356374aSAndroid Build Coastguard Worker   absl::btree_multimap<int, int> dst;
2206*9356374aSAndroid Build Coastguard Worker 
2207*9356374aSAndroid Build Coastguard Worker   dst.merge(src1);
2208*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src1.empty());
2209*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3)));
2210*9356374aSAndroid Build Coastguard Worker   dst.merge(src2);
2211*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src2.empty());
2212*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(dst, ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(3, 2),
2213*9356374aSAndroid Build Coastguard Worker                                Pair(4, 1), Pair(4, 4), Pair(5, 5)));
2214*9356374aSAndroid Build Coastguard Worker }
2215*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MergeIntoSetMovableOnly)2216*9356374aSAndroid Build Coastguard Worker TEST(Btree, MergeIntoSetMovableOnly) {
2217*9356374aSAndroid Build Coastguard Worker   absl::btree_set<MovableOnlyInstance> src;
2218*9356374aSAndroid Build Coastguard Worker   src.insert(MovableOnlyInstance(1));
2219*9356374aSAndroid Build Coastguard Worker   absl::btree_multiset<MovableOnlyInstance> dst1;
2220*9356374aSAndroid Build Coastguard Worker   dst1.insert(MovableOnlyInstance(2));
2221*9356374aSAndroid Build Coastguard Worker   absl::btree_set<MovableOnlyInstance> dst2;
2222*9356374aSAndroid Build Coastguard Worker 
2223*9356374aSAndroid Build Coastguard Worker   // Test merge into multiset.
2224*9356374aSAndroid Build Coastguard Worker   dst1.merge(src);
2225*9356374aSAndroid Build Coastguard Worker 
2226*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(src.empty());
2227*9356374aSAndroid Build Coastguard Worker   // ElementsAre/ElementsAreArray don't work with move-only types.
2228*9356374aSAndroid Build Coastguard Worker   ASSERT_THAT(dst1, SizeIs(2));
2229*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*dst1.begin(), MovableOnlyInstance(1));
2230*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*std::next(dst1.begin()), MovableOnlyInstance(2));
2231*9356374aSAndroid Build Coastguard Worker 
2232*9356374aSAndroid Build Coastguard Worker   // Test merge into set.
2233*9356374aSAndroid Build Coastguard Worker   dst2.merge(dst1);
2234*9356374aSAndroid Build Coastguard Worker 
2235*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(dst1.empty());
2236*9356374aSAndroid Build Coastguard Worker   ASSERT_THAT(dst2, SizeIs(2));
2237*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*dst2.begin(), MovableOnlyInstance(1));
2238*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*std::next(dst2.begin()), MovableOnlyInstance(2));
2239*9356374aSAndroid Build Coastguard Worker }
2240*9356374aSAndroid Build Coastguard Worker 
2241*9356374aSAndroid Build Coastguard Worker struct KeyCompareToWeakOrdering {
2242*9356374aSAndroid Build Coastguard Worker   template <typename T>
operator ()absl::container_internal::__anon7e8713fe0311::KeyCompareToWeakOrdering2243*9356374aSAndroid Build Coastguard Worker   absl::weak_ordering operator()(const T &a, const T &b) const {
2244*9356374aSAndroid Build Coastguard Worker     return a < b ? absl::weak_ordering::less
2245*9356374aSAndroid Build Coastguard Worker                  : a == b ? absl::weak_ordering::equivalent
2246*9356374aSAndroid Build Coastguard Worker                           : absl::weak_ordering::greater;
2247*9356374aSAndroid Build Coastguard Worker   }
2248*9356374aSAndroid Build Coastguard Worker };
2249*9356374aSAndroid Build Coastguard Worker 
2250*9356374aSAndroid Build Coastguard Worker struct KeyCompareToStrongOrdering {
2251*9356374aSAndroid Build Coastguard Worker   template <typename T>
operator ()absl::container_internal::__anon7e8713fe0311::KeyCompareToStrongOrdering2252*9356374aSAndroid Build Coastguard Worker   absl::strong_ordering operator()(const T &a, const T &b) const {
2253*9356374aSAndroid Build Coastguard Worker     return a < b ? absl::strong_ordering::less
2254*9356374aSAndroid Build Coastguard Worker                  : a == b ? absl::strong_ordering::equal
2255*9356374aSAndroid Build Coastguard Worker                           : absl::strong_ordering::greater;
2256*9356374aSAndroid Build Coastguard Worker   }
2257*9356374aSAndroid Build Coastguard Worker };
2258*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,UserProvidedKeyCompareToComparators)2259*9356374aSAndroid Build Coastguard Worker TEST(Btree, UserProvidedKeyCompareToComparators) {
2260*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, KeyCompareToWeakOrdering> weak_set = {1, 2, 3};
2261*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(weak_set.contains(2));
2262*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(weak_set.contains(4));
2263*9356374aSAndroid Build Coastguard Worker 
2264*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, KeyCompareToStrongOrdering> strong_set = {1, 2, 3};
2265*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(strong_set.contains(2));
2266*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(strong_set.contains(4));
2267*9356374aSAndroid Build Coastguard Worker }
2268*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,TryEmplaceBasicTest)2269*9356374aSAndroid Build Coastguard Worker TEST(Btree, TryEmplaceBasicTest) {
2270*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, std::string> m;
2271*9356374aSAndroid Build Coastguard Worker 
2272*9356374aSAndroid Build Coastguard Worker   // Should construct a string from the literal.
2273*9356374aSAndroid Build Coastguard Worker   m.try_emplace(1, "one");
2274*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(1, m.size());
2275*9356374aSAndroid Build Coastguard Worker 
2276*9356374aSAndroid Build Coastguard Worker   // Try other string constructors and const lvalue key.
2277*9356374aSAndroid Build Coastguard Worker   const int key(42);
2278*9356374aSAndroid Build Coastguard Worker   m.try_emplace(key, 3, 'a');
2279*9356374aSAndroid Build Coastguard Worker   m.try_emplace(2, std::string("two"));
2280*9356374aSAndroid Build Coastguard Worker 
2281*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2282*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(m, ElementsAreArray(std::vector<std::pair<int, std::string>>{
2283*9356374aSAndroid Build Coastguard Worker                      {1, "one"}, {2, "two"}, {42, "aaa"}}));
2284*9356374aSAndroid Build Coastguard Worker }
2285*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,TryEmplaceWithHintWorks)2286*9356374aSAndroid Build Coastguard Worker TEST(Btree, TryEmplaceWithHintWorks) {
2287*9356374aSAndroid Build Coastguard Worker   // Use a counting comparator here to verify that hint is used.
2288*9356374aSAndroid Build Coastguard Worker   int calls = 0;
2289*9356374aSAndroid Build Coastguard Worker   auto cmp = [&calls](int x, int y) {
2290*9356374aSAndroid Build Coastguard Worker     ++calls;
2291*9356374aSAndroid Build Coastguard Worker     return x < y;
2292*9356374aSAndroid Build Coastguard Worker   };
2293*9356374aSAndroid Build Coastguard Worker   using Cmp = decltype(cmp);
2294*9356374aSAndroid Build Coastguard Worker 
2295*9356374aSAndroid Build Coastguard Worker   // Use a map that is opted out of key_compare being adapted so we can expect
2296*9356374aSAndroid Build Coastguard Worker   // strict comparison call limits.
2297*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int, CheckedCompareOptedOutCmp<Cmp>> m(cmp);
2298*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 128; ++i) {
2299*9356374aSAndroid Build Coastguard Worker     m.emplace(i, i);
2300*9356374aSAndroid Build Coastguard Worker   }
2301*9356374aSAndroid Build Coastguard Worker 
2302*9356374aSAndroid Build Coastguard Worker   // Sanity check for the comparator
2303*9356374aSAndroid Build Coastguard Worker   calls = 0;
2304*9356374aSAndroid Build Coastguard Worker   m.emplace(127, 127);
2305*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(calls, 4);
2306*9356374aSAndroid Build Coastguard Worker 
2307*9356374aSAndroid Build Coastguard Worker   // Try with begin hint:
2308*9356374aSAndroid Build Coastguard Worker   calls = 0;
2309*9356374aSAndroid Build Coastguard Worker   auto it = m.try_emplace(m.begin(), -1, -1);
2310*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(129, m.size());
2311*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, m.begin());
2312*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(calls, 2);
2313*9356374aSAndroid Build Coastguard Worker 
2314*9356374aSAndroid Build Coastguard Worker   // Try with end hint:
2315*9356374aSAndroid Build Coastguard Worker   calls = 0;
2316*9356374aSAndroid Build Coastguard Worker   std::pair<int, int> pair1024 = {1024, 1024};
2317*9356374aSAndroid Build Coastguard Worker   it = m.try_emplace(m.end(), pair1024.first, pair1024.second);
2318*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(130, m.size());
2319*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, --m.end());
2320*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(calls, 2);
2321*9356374aSAndroid Build Coastguard Worker 
2322*9356374aSAndroid Build Coastguard Worker   // Try value already present, bad hint; ensure no duplicate added:
2323*9356374aSAndroid Build Coastguard Worker   calls = 0;
2324*9356374aSAndroid Build Coastguard Worker   it = m.try_emplace(m.end(), 16, 17);
2325*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(130, m.size());
2326*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(calls, 4);
2327*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, m.find(16));
2328*9356374aSAndroid Build Coastguard Worker 
2329*9356374aSAndroid Build Coastguard Worker   // Try value already present, hint points directly to it:
2330*9356374aSAndroid Build Coastguard Worker   calls = 0;
2331*9356374aSAndroid Build Coastguard Worker   it = m.try_emplace(it, 16, 17);
2332*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(130, m.size());
2333*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(calls, 2);
2334*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, m.find(16));
2335*9356374aSAndroid Build Coastguard Worker 
2336*9356374aSAndroid Build Coastguard Worker   m.erase(2);
2337*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(129, m.size());
2338*9356374aSAndroid Build Coastguard Worker   auto hint = m.find(3);
2339*9356374aSAndroid Build Coastguard Worker   // Try emplace in the middle of two other elements.
2340*9356374aSAndroid Build Coastguard Worker   calls = 0;
2341*9356374aSAndroid Build Coastguard Worker   m.try_emplace(hint, 2, 2);
2342*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(130, m.size());
2343*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(calls, 2);
2344*9356374aSAndroid Build Coastguard Worker 
2345*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2346*9356374aSAndroid Build Coastguard Worker }
2347*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,TryEmplaceWithBadHint)2348*9356374aSAndroid Build Coastguard Worker TEST(Btree, TryEmplaceWithBadHint) {
2349*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> m = {{1, 1}, {9, 9}};
2350*9356374aSAndroid Build Coastguard Worker 
2351*9356374aSAndroid Build Coastguard Worker   // Bad hint (too small), should still emplace:
2352*9356374aSAndroid Build Coastguard Worker   auto it = m.try_emplace(m.begin(), 2, 2);
2353*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, ++m.begin());
2354*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(m, ElementsAreArray(
2355*9356374aSAndroid Build Coastguard Worker                      std::vector<std::pair<int, int>>{{1, 1}, {2, 2}, {9, 9}}));
2356*9356374aSAndroid Build Coastguard Worker 
2357*9356374aSAndroid Build Coastguard Worker   // Bad hint, too large this time:
2358*9356374aSAndroid Build Coastguard Worker   it = m.try_emplace(++(++m.begin()), 0, 0);
2359*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(it, m.begin());
2360*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(m, ElementsAreArray(std::vector<std::pair<int, int>>{
2361*9356374aSAndroid Build Coastguard Worker                      {0, 0}, {1, 1}, {2, 2}, {9, 9}}));
2362*9356374aSAndroid Build Coastguard Worker }
2363*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,TryEmplaceMaintainsSortedOrder)2364*9356374aSAndroid Build Coastguard Worker TEST(Btree, TryEmplaceMaintainsSortedOrder) {
2365*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, std::string> m;
2366*9356374aSAndroid Build Coastguard Worker   std::pair<int, std::string> pair5 = {5, "five"};
2367*9356374aSAndroid Build Coastguard Worker 
2368*9356374aSAndroid Build Coastguard Worker   // Test both lvalue & rvalue emplace.
2369*9356374aSAndroid Build Coastguard Worker   m.try_emplace(10, "ten");
2370*9356374aSAndroid Build Coastguard Worker   m.try_emplace(pair5.first, pair5.second);
2371*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(2, m.size());
2372*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2373*9356374aSAndroid Build Coastguard Worker 
2374*9356374aSAndroid Build Coastguard Worker   int int100{100};
2375*9356374aSAndroid Build Coastguard Worker   m.try_emplace(int100, "hundred");
2376*9356374aSAndroid Build Coastguard Worker   m.try_emplace(1, "one");
2377*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(4, m.size());
2378*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(m.begin(), m.end()));
2379*9356374aSAndroid Build Coastguard Worker }
2380*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,TryEmplaceWithHintAndNoValueArgsWorks)2381*9356374aSAndroid Build Coastguard Worker TEST(Btree, TryEmplaceWithHintAndNoValueArgsWorks) {
2382*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> m;
2383*9356374aSAndroid Build Coastguard Worker   m.try_emplace(m.end(), 1);
2384*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(0, m[1]);
2385*9356374aSAndroid Build Coastguard Worker }
2386*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,TryEmplaceWithHintAndMultipleValueArgsWorks)2387*9356374aSAndroid Build Coastguard Worker TEST(Btree, TryEmplaceWithHintAndMultipleValueArgsWorks) {
2388*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, std::string> m;
2389*9356374aSAndroid Build Coastguard Worker   m.try_emplace(m.end(), 1, 10, 'a');
2390*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string(10, 'a'), m[1]);
2391*9356374aSAndroid Build Coastguard Worker }
2392*9356374aSAndroid Build Coastguard Worker 
2393*9356374aSAndroid Build Coastguard Worker template <typename Alloc>
2394*9356374aSAndroid Build Coastguard Worker using BtreeSetAlloc = absl::btree_set<int, std::less<int>, Alloc>;
2395*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,AllocatorPropagation)2396*9356374aSAndroid Build Coastguard Worker TEST(Btree, AllocatorPropagation) {
2397*9356374aSAndroid Build Coastguard Worker   TestAllocPropagation<BtreeSetAlloc>();
2398*9356374aSAndroid Build Coastguard Worker }
2399*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MinimumAlignmentAllocator)2400*9356374aSAndroid Build Coastguard Worker TEST(Btree, MinimumAlignmentAllocator) {
2401*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int8_t, std::less<int8_t>, MinimumAlignmentAlloc<int8_t>> set;
2402*9356374aSAndroid Build Coastguard Worker 
2403*9356374aSAndroid Build Coastguard Worker   // Do some basic operations. Test that everything is fine when allocator uses
2404*9356374aSAndroid Build Coastguard Worker   // minimal alignment.
2405*9356374aSAndroid Build Coastguard Worker   for (int8_t i = 0; i < 100; ++i) set.insert(i);
2406*9356374aSAndroid Build Coastguard Worker   set.erase(set.find(50), set.end());
2407*9356374aSAndroid Build Coastguard Worker   for (int8_t i = 51; i < 101; ++i) set.insert(i);
2408*9356374aSAndroid Build Coastguard Worker 
2409*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(set.size(), 100);
2410*9356374aSAndroid Build Coastguard Worker }
2411*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,EmptyTree)2412*9356374aSAndroid Build Coastguard Worker TEST(Btree, EmptyTree) {
2413*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> s;
2414*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(s.empty());
2415*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(s.size(), 0);
2416*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(s.max_size(), 0);
2417*9356374aSAndroid Build Coastguard Worker }
2418*9356374aSAndroid Build Coastguard Worker 
IsEven(int k)2419*9356374aSAndroid Build Coastguard Worker bool IsEven(int k) { return k % 2 == 0; }
2420*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,EraseIf)2421*9356374aSAndroid Build Coastguard Worker TEST(Btree, EraseIf) {
2422*9356374aSAndroid Build Coastguard Worker   // Test that erase_if works with all the container types and supports lambdas.
2423*9356374aSAndroid Build Coastguard Worker   {
2424*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> s = {1, 3, 5, 6, 100};
2425*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(erase_if(s, [](int k) { return k > 3; }), 3);
2426*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(s, ElementsAre(1, 3));
2427*9356374aSAndroid Build Coastguard Worker   }
2428*9356374aSAndroid Build Coastguard Worker   {
2429*9356374aSAndroid Build Coastguard Worker     absl::btree_multiset<int> s = {1, 3, 3, 5, 6, 6, 100};
2430*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(erase_if(s, [](int k) { return k <= 3; }), 3);
2431*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(s, ElementsAre(5, 6, 6, 100));
2432*9356374aSAndroid Build Coastguard Worker   }
2433*9356374aSAndroid Build Coastguard Worker   {
2434*9356374aSAndroid Build Coastguard Worker     absl::btree_map<int, int> m = {{1, 1}, {3, 3}, {6, 6}, {100, 100}};
2435*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(
2436*9356374aSAndroid Build Coastguard Worker         erase_if(m, [](std::pair<const int, int> kv) { return kv.first > 3; }),
2437*9356374aSAndroid Build Coastguard Worker         2);
2438*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(m, ElementsAre(Pair(1, 1), Pair(3, 3)));
2439*9356374aSAndroid Build Coastguard Worker   }
2440*9356374aSAndroid Build Coastguard Worker   {
2441*9356374aSAndroid Build Coastguard Worker     absl::btree_multimap<int, int> m = {{1, 1}, {3, 3}, {3, 6},
2442*9356374aSAndroid Build Coastguard Worker                                         {6, 6}, {6, 7}, {100, 6}};
2443*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(
2444*9356374aSAndroid Build Coastguard Worker         erase_if(m,
2445*9356374aSAndroid Build Coastguard Worker                  [](std::pair<const int, int> kv) { return kv.second == 6; }),
2446*9356374aSAndroid Build Coastguard Worker         3);
2447*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(m, ElementsAre(Pair(1, 1), Pair(3, 3), Pair(6, 7)));
2448*9356374aSAndroid Build Coastguard Worker   }
2449*9356374aSAndroid Build Coastguard Worker   // Test that erasing all elements from a large set works and test support for
2450*9356374aSAndroid Build Coastguard Worker   // function pointers.
2451*9356374aSAndroid Build Coastguard Worker   {
2452*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> s;
2453*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i < 1000; ++i) s.insert(2 * i);
2454*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(erase_if(s, IsEven), 1000);
2455*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(s, IsEmpty());
2456*9356374aSAndroid Build Coastguard Worker   }
2457*9356374aSAndroid Build Coastguard Worker   // Test that erase_if supports other format of function pointers.
2458*9356374aSAndroid Build Coastguard Worker   {
2459*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> s = {1, 3, 5, 6, 100};
2460*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(erase_if(s, &IsEven), 2);
2461*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(s, ElementsAre(1, 3, 5));
2462*9356374aSAndroid Build Coastguard Worker   }
2463*9356374aSAndroid Build Coastguard Worker   // Test that erase_if invokes the predicate once per element.
2464*9356374aSAndroid Build Coastguard Worker   {
2465*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> s;
2466*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i < 1000; ++i) s.insert(i);
2467*9356374aSAndroid Build Coastguard Worker     int pred_calls = 0;
2468*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(erase_if(s,
2469*9356374aSAndroid Build Coastguard Worker                        [&pred_calls](int k) {
2470*9356374aSAndroid Build Coastguard Worker                          ++pred_calls;
2471*9356374aSAndroid Build Coastguard Worker                          return k % 2;
2472*9356374aSAndroid Build Coastguard Worker                        }),
2473*9356374aSAndroid Build Coastguard Worker               500);
2474*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(s, SizeIs(500));
2475*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(pred_calls, 1000);
2476*9356374aSAndroid Build Coastguard Worker   }
2477*9356374aSAndroid Build Coastguard Worker }
2478*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,InsertOrAssign)2479*9356374aSAndroid Build Coastguard Worker TEST(Btree, InsertOrAssign) {
2480*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> m = {{1, 1}, {3, 3}};
2481*9356374aSAndroid Build Coastguard Worker   using value_type = typename decltype(m)::value_type;
2482*9356374aSAndroid Build Coastguard Worker 
2483*9356374aSAndroid Build Coastguard Worker   auto ret = m.insert_or_assign(4, 4);
2484*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*ret.first, value_type(4, 4));
2485*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(ret.second);
2486*9356374aSAndroid Build Coastguard Worker   ret = m.insert_or_assign(3, 100);
2487*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*ret.first, value_type(3, 100));
2488*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(ret.second);
2489*9356374aSAndroid Build Coastguard Worker 
2490*9356374aSAndroid Build Coastguard Worker   auto hint_ret = m.insert_or_assign(ret.first, 3, 200);
2491*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*hint_ret, value_type(3, 200));
2492*9356374aSAndroid Build Coastguard Worker   hint_ret = m.insert_or_assign(m.find(1), 0, 1);
2493*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*hint_ret, value_type(0, 1));
2494*9356374aSAndroid Build Coastguard Worker   // Test with bad hint.
2495*9356374aSAndroid Build Coastguard Worker   hint_ret = m.insert_or_assign(m.end(), -1, 1);
2496*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*hint_ret, value_type(-1, 1));
2497*9356374aSAndroid Build Coastguard Worker 
2498*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(m, ElementsAre(Pair(-1, 1), Pair(0, 1), Pair(1, 1), Pair(3, 200),
2499*9356374aSAndroid Build Coastguard Worker                              Pair(4, 4)));
2500*9356374aSAndroid Build Coastguard Worker }
2501*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,InsertOrAssignMovableOnly)2502*9356374aSAndroid Build Coastguard Worker TEST(Btree, InsertOrAssignMovableOnly) {
2503*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, MovableOnlyInstance> m;
2504*9356374aSAndroid Build Coastguard Worker   using value_type = typename decltype(m)::value_type;
2505*9356374aSAndroid Build Coastguard Worker 
2506*9356374aSAndroid Build Coastguard Worker   auto ret = m.insert_or_assign(4, MovableOnlyInstance(4));
2507*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(4)));
2508*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(ret.second);
2509*9356374aSAndroid Build Coastguard Worker   ret = m.insert_or_assign(4, MovableOnlyInstance(100));
2510*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(100)));
2511*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(ret.second);
2512*9356374aSAndroid Build Coastguard Worker 
2513*9356374aSAndroid Build Coastguard Worker   auto hint_ret = m.insert_or_assign(ret.first, 3, MovableOnlyInstance(200));
2514*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(*hint_ret, value_type(3, MovableOnlyInstance(200)));
2515*9356374aSAndroid Build Coastguard Worker 
2516*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(m.size(), 2);
2517*9356374aSAndroid Build Coastguard Worker }
2518*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,BitfieldArgument)2519*9356374aSAndroid Build Coastguard Worker TEST(Btree, BitfieldArgument) {
2520*9356374aSAndroid Build Coastguard Worker   union {
2521*9356374aSAndroid Build Coastguard Worker     int n : 1;
2522*9356374aSAndroid Build Coastguard Worker   };
2523*9356374aSAndroid Build Coastguard Worker   n = 0;
2524*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int> m;
2525*9356374aSAndroid Build Coastguard Worker   m.erase(n);
2526*9356374aSAndroid Build Coastguard Worker   m.count(n);
2527*9356374aSAndroid Build Coastguard Worker   m.find(n);
2528*9356374aSAndroid Build Coastguard Worker   m.contains(n);
2529*9356374aSAndroid Build Coastguard Worker   m.equal_range(n);
2530*9356374aSAndroid Build Coastguard Worker   m.insert_or_assign(n, n);
2531*9356374aSAndroid Build Coastguard Worker   m.insert_or_assign(m.end(), n, n);
2532*9356374aSAndroid Build Coastguard Worker   m.try_emplace(n);
2533*9356374aSAndroid Build Coastguard Worker   m.try_emplace(m.end(), n);
2534*9356374aSAndroid Build Coastguard Worker   m.at(n);
2535*9356374aSAndroid Build Coastguard Worker   m[n];
2536*9356374aSAndroid Build Coastguard Worker }
2537*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,SetRangeConstructorAndInsertSupportExplicitConversionComparable)2538*9356374aSAndroid Build Coastguard Worker TEST(Btree, SetRangeConstructorAndInsertSupportExplicitConversionComparable) {
2539*9356374aSAndroid Build Coastguard Worker   const absl::string_view names[] = {"n1", "n2"};
2540*9356374aSAndroid Build Coastguard Worker 
2541*9356374aSAndroid Build Coastguard Worker   absl::btree_set<std::string> name_set1{std::begin(names), std::end(names)};
2542*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(name_set1, ElementsAreArray(names));
2543*9356374aSAndroid Build Coastguard Worker 
2544*9356374aSAndroid Build Coastguard Worker   absl::btree_set<std::string> name_set2;
2545*9356374aSAndroid Build Coastguard Worker   name_set2.insert(std::begin(names), std::end(names));
2546*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(name_set2, ElementsAreArray(names));
2547*9356374aSAndroid Build Coastguard Worker }
2548*9356374aSAndroid Build Coastguard Worker 
2549*9356374aSAndroid Build Coastguard Worker // A type that is explicitly convertible from int and counts constructor calls.
2550*9356374aSAndroid Build Coastguard Worker struct ConstructorCounted {
ConstructorCountedabsl::container_internal::__anon7e8713fe0311::ConstructorCounted2551*9356374aSAndroid Build Coastguard Worker   explicit ConstructorCounted(int i) : i(i) { ++constructor_calls; }
operator ==absl::container_internal::__anon7e8713fe0311::ConstructorCounted2552*9356374aSAndroid Build Coastguard Worker   bool operator==(int other) const { return i == other; }
2553*9356374aSAndroid Build Coastguard Worker 
2554*9356374aSAndroid Build Coastguard Worker   int i;
2555*9356374aSAndroid Build Coastguard Worker   static int constructor_calls;
2556*9356374aSAndroid Build Coastguard Worker };
2557*9356374aSAndroid Build Coastguard Worker int ConstructorCounted::constructor_calls = 0;
2558*9356374aSAndroid Build Coastguard Worker 
2559*9356374aSAndroid Build Coastguard Worker struct ConstructorCountedCompare {
operator ()absl::container_internal::__anon7e8713fe0311::ConstructorCountedCompare2560*9356374aSAndroid Build Coastguard Worker   bool operator()(int a, const ConstructorCounted &b) const { return a < b.i; }
operator ()absl::container_internal::__anon7e8713fe0311::ConstructorCountedCompare2561*9356374aSAndroid Build Coastguard Worker   bool operator()(const ConstructorCounted &a, int b) const { return a.i < b; }
operator ()absl::container_internal::__anon7e8713fe0311::ConstructorCountedCompare2562*9356374aSAndroid Build Coastguard Worker   bool operator()(const ConstructorCounted &a,
2563*9356374aSAndroid Build Coastguard Worker                   const ConstructorCounted &b) const {
2564*9356374aSAndroid Build Coastguard Worker     return a.i < b.i;
2565*9356374aSAndroid Build Coastguard Worker   }
2566*9356374aSAndroid Build Coastguard Worker   using is_transparent = void;
2567*9356374aSAndroid Build Coastguard Worker };
2568*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,SetRangeConstructorAndInsertExplicitConvComparableLimitConstruction)2569*9356374aSAndroid Build Coastguard Worker TEST(Btree,
2570*9356374aSAndroid Build Coastguard Worker      SetRangeConstructorAndInsertExplicitConvComparableLimitConstruction) {
2571*9356374aSAndroid Build Coastguard Worker   const int i[] = {0, 1, 1};
2572*9356374aSAndroid Build Coastguard Worker   ConstructorCounted::constructor_calls = 0;
2573*9356374aSAndroid Build Coastguard Worker 
2574*9356374aSAndroid Build Coastguard Worker   absl::btree_set<ConstructorCounted, ConstructorCountedCompare> set{
2575*9356374aSAndroid Build Coastguard Worker       std::begin(i), std::end(i)};
2576*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set, ElementsAre(0, 1));
2577*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2578*9356374aSAndroid Build Coastguard Worker 
2579*9356374aSAndroid Build Coastguard Worker   set.insert(std::begin(i), std::end(i));
2580*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set, ElementsAre(0, 1));
2581*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2582*9356374aSAndroid Build Coastguard Worker }
2583*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,SetRangeConstructorAndInsertSupportExplicitConversionNonComparable)2584*9356374aSAndroid Build Coastguard Worker TEST(Btree,
2585*9356374aSAndroid Build Coastguard Worker      SetRangeConstructorAndInsertSupportExplicitConversionNonComparable) {
2586*9356374aSAndroid Build Coastguard Worker   const int i[] = {0, 1};
2587*9356374aSAndroid Build Coastguard Worker 
2588*9356374aSAndroid Build Coastguard Worker   absl::btree_set<std::vector<void *>> s1{std::begin(i), std::end(i)};
2589*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(s1, ElementsAre(IsEmpty(), ElementsAre(IsNull())));
2590*9356374aSAndroid Build Coastguard Worker 
2591*9356374aSAndroid Build Coastguard Worker   absl::btree_set<std::vector<void *>> s2;
2592*9356374aSAndroid Build Coastguard Worker   s2.insert(std::begin(i), std::end(i));
2593*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(s2, ElementsAre(IsEmpty(), ElementsAre(IsNull())));
2594*9356374aSAndroid Build Coastguard Worker }
2595*9356374aSAndroid Build Coastguard Worker 
2596*9356374aSAndroid Build Coastguard Worker // libstdc++ included with GCC 4.9 has a bug in the std::pair constructors that
2597*9356374aSAndroid Build Coastguard Worker // prevents explicit conversions between pair types.
2598*9356374aSAndroid Build Coastguard Worker // We only run this test for the libstdc++ from GCC 7 or newer because we can't
2599*9356374aSAndroid Build Coastguard Worker // reliably check the libstdc++ version prior to that release.
2600*9356374aSAndroid Build Coastguard Worker #if !defined(__GLIBCXX__) || \
2601*9356374aSAndroid Build Coastguard Worker     (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7)
TEST(Btree,MapRangeConstructorAndInsertSupportExplicitConversionComparable)2602*9356374aSAndroid Build Coastguard Worker TEST(Btree, MapRangeConstructorAndInsertSupportExplicitConversionComparable) {
2603*9356374aSAndroid Build Coastguard Worker   const std::pair<absl::string_view, int> names[] = {{"n1", 1}, {"n2", 2}};
2604*9356374aSAndroid Build Coastguard Worker 
2605*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int> name_map1{std::begin(names),
2606*9356374aSAndroid Build Coastguard Worker                                               std::end(names)};
2607*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(name_map1, ElementsAre(Pair("n1", 1), Pair("n2", 2)));
2608*9356374aSAndroid Build Coastguard Worker 
2609*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int> name_map2;
2610*9356374aSAndroid Build Coastguard Worker   name_map2.insert(std::begin(names), std::end(names));
2611*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(name_map2, ElementsAre(Pair("n1", 1), Pair("n2", 2)));
2612*9356374aSAndroid Build Coastguard Worker }
2613*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MapRangeConstructorAndInsertExplicitConvComparableLimitConstruction)2614*9356374aSAndroid Build Coastguard Worker TEST(Btree,
2615*9356374aSAndroid Build Coastguard Worker      MapRangeConstructorAndInsertExplicitConvComparableLimitConstruction) {
2616*9356374aSAndroid Build Coastguard Worker   const std::pair<int, int> i[] = {{0, 1}, {1, 2}, {1, 3}};
2617*9356374aSAndroid Build Coastguard Worker   ConstructorCounted::constructor_calls = 0;
2618*9356374aSAndroid Build Coastguard Worker 
2619*9356374aSAndroid Build Coastguard Worker   absl::btree_map<ConstructorCounted, int, ConstructorCountedCompare> map{
2620*9356374aSAndroid Build Coastguard Worker       std::begin(i), std::end(i)};
2621*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(map, ElementsAre(Pair(0, 1), Pair(1, 2)));
2622*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2623*9356374aSAndroid Build Coastguard Worker 
2624*9356374aSAndroid Build Coastguard Worker   map.insert(std::begin(i), std::end(i));
2625*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(map, ElementsAre(Pair(0, 1), Pair(1, 2)));
2626*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ConstructorCounted::constructor_calls, 2);
2627*9356374aSAndroid Build Coastguard Worker }
2628*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MapRangeConstructorAndInsertSupportExplicitConversionNonComparable)2629*9356374aSAndroid Build Coastguard Worker TEST(Btree,
2630*9356374aSAndroid Build Coastguard Worker      MapRangeConstructorAndInsertSupportExplicitConversionNonComparable) {
2631*9356374aSAndroid Build Coastguard Worker   const std::pair<int, int> i[] = {{0, 1}, {1, 2}};
2632*9356374aSAndroid Build Coastguard Worker 
2633*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::vector<void *>, int> m1{std::begin(i), std::end(i)};
2634*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(m1,
2635*9356374aSAndroid Build Coastguard Worker               ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2)));
2636*9356374aSAndroid Build Coastguard Worker 
2637*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::vector<void *>, int> m2;
2638*9356374aSAndroid Build Coastguard Worker   m2.insert(std::begin(i), std::end(i));
2639*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(m2,
2640*9356374aSAndroid Build Coastguard Worker               ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2)));
2641*9356374aSAndroid Build Coastguard Worker }
2642*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,HeterogeneousTryEmplace)2643*9356374aSAndroid Build Coastguard Worker TEST(Btree, HeterogeneousTryEmplace) {
2644*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int> m;
2645*9356374aSAndroid Build Coastguard Worker   std::string s = "key";
2646*9356374aSAndroid Build Coastguard Worker   absl::string_view sv = s;
2647*9356374aSAndroid Build Coastguard Worker   m.try_emplace(sv, 1);
2648*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(m[s], 1);
2649*9356374aSAndroid Build Coastguard Worker 
2650*9356374aSAndroid Build Coastguard Worker   m.try_emplace(m.end(), sv, 2);
2651*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(m[s], 1);
2652*9356374aSAndroid Build Coastguard Worker }
2653*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,HeterogeneousOperatorMapped)2654*9356374aSAndroid Build Coastguard Worker TEST(Btree, HeterogeneousOperatorMapped) {
2655*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int> m;
2656*9356374aSAndroid Build Coastguard Worker   std::string s = "key";
2657*9356374aSAndroid Build Coastguard Worker   absl::string_view sv = s;
2658*9356374aSAndroid Build Coastguard Worker   m[sv] = 1;
2659*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(m[s], 1);
2660*9356374aSAndroid Build Coastguard Worker 
2661*9356374aSAndroid Build Coastguard Worker   m[sv] = 2;
2662*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(m[s], 2);
2663*9356374aSAndroid Build Coastguard Worker }
2664*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,HeterogeneousInsertOrAssign)2665*9356374aSAndroid Build Coastguard Worker TEST(Btree, HeterogeneousInsertOrAssign) {
2666*9356374aSAndroid Build Coastguard Worker   absl::btree_map<std::string, int> m;
2667*9356374aSAndroid Build Coastguard Worker   std::string s = "key";
2668*9356374aSAndroid Build Coastguard Worker   absl::string_view sv = s;
2669*9356374aSAndroid Build Coastguard Worker   m.insert_or_assign(sv, 1);
2670*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(m[s], 1);
2671*9356374aSAndroid Build Coastguard Worker 
2672*9356374aSAndroid Build Coastguard Worker   m.insert_or_assign(m.end(), sv, 2);
2673*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(m[s], 2);
2674*9356374aSAndroid Build Coastguard Worker }
2675*9356374aSAndroid Build Coastguard Worker #endif
2676*9356374aSAndroid Build Coastguard Worker 
2677*9356374aSAndroid Build Coastguard Worker // This test requires std::launder for mutable key access in node handles.
2678*9356374aSAndroid Build Coastguard Worker #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
TEST(Btree,NodeHandleMutableKeyAccess)2679*9356374aSAndroid Build Coastguard Worker TEST(Btree, NodeHandleMutableKeyAccess) {
2680*9356374aSAndroid Build Coastguard Worker   {
2681*9356374aSAndroid Build Coastguard Worker     absl::btree_map<std::string, std::string> map;
2682*9356374aSAndroid Build Coastguard Worker 
2683*9356374aSAndroid Build Coastguard Worker     map["key1"] = "mapped";
2684*9356374aSAndroid Build Coastguard Worker 
2685*9356374aSAndroid Build Coastguard Worker     auto nh = map.extract(map.begin());
2686*9356374aSAndroid Build Coastguard Worker     nh.key().resize(3);
2687*9356374aSAndroid Build Coastguard Worker     map.insert(std::move(nh));
2688*9356374aSAndroid Build Coastguard Worker 
2689*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(map, ElementsAre(Pair("key", "mapped")));
2690*9356374aSAndroid Build Coastguard Worker   }
2691*9356374aSAndroid Build Coastguard Worker   // Also for multimap.
2692*9356374aSAndroid Build Coastguard Worker   {
2693*9356374aSAndroid Build Coastguard Worker     absl::btree_multimap<std::string, std::string> map;
2694*9356374aSAndroid Build Coastguard Worker 
2695*9356374aSAndroid Build Coastguard Worker     map.emplace("key1", "mapped");
2696*9356374aSAndroid Build Coastguard Worker 
2697*9356374aSAndroid Build Coastguard Worker     auto nh = map.extract(map.begin());
2698*9356374aSAndroid Build Coastguard Worker     nh.key().resize(3);
2699*9356374aSAndroid Build Coastguard Worker     map.insert(std::move(nh));
2700*9356374aSAndroid Build Coastguard Worker 
2701*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(map, ElementsAre(Pair("key", "mapped")));
2702*9356374aSAndroid Build Coastguard Worker   }
2703*9356374aSAndroid Build Coastguard Worker }
2704*9356374aSAndroid Build Coastguard Worker #endif
2705*9356374aSAndroid Build Coastguard Worker 
2706*9356374aSAndroid Build Coastguard Worker struct MultiKey {
2707*9356374aSAndroid Build Coastguard Worker   int i1;
2708*9356374aSAndroid Build Coastguard Worker   int i2;
2709*9356374aSAndroid Build Coastguard Worker };
2710*9356374aSAndroid Build Coastguard Worker 
operator ==(const MultiKey a,const MultiKey b)2711*9356374aSAndroid Build Coastguard Worker bool operator==(const MultiKey a, const MultiKey b) {
2712*9356374aSAndroid Build Coastguard Worker   return a.i1 == b.i1 && a.i2 == b.i2;
2713*9356374aSAndroid Build Coastguard Worker }
2714*9356374aSAndroid Build Coastguard Worker 
2715*9356374aSAndroid Build Coastguard Worker // A heterogeneous comparator that has different equivalence classes for
2716*9356374aSAndroid Build Coastguard Worker // different lookup types.
2717*9356374aSAndroid Build Coastguard Worker struct MultiKeyComp {
2718*9356374aSAndroid Build Coastguard Worker   using is_transparent = void;
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyComp2719*9356374aSAndroid Build Coastguard Worker   bool operator()(const MultiKey a, const MultiKey b) const {
2720*9356374aSAndroid Build Coastguard Worker     if (a.i1 != b.i1) return a.i1 < b.i1;
2721*9356374aSAndroid Build Coastguard Worker     return a.i2 < b.i2;
2722*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyComp2723*9356374aSAndroid Build Coastguard Worker   bool operator()(const int a, const MultiKey b) const { return a < b.i1; }
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyComp2724*9356374aSAndroid Build Coastguard Worker   bool operator()(const MultiKey a, const int b) const { return a.i1 < b; }
2725*9356374aSAndroid Build Coastguard Worker };
2726*9356374aSAndroid Build Coastguard Worker 
2727*9356374aSAndroid Build Coastguard Worker // A heterogeneous, three-way comparator that has different equivalence classes
2728*9356374aSAndroid Build Coastguard Worker // for different lookup types.
2729*9356374aSAndroid Build Coastguard Worker struct MultiKeyThreeWayComp {
2730*9356374aSAndroid Build Coastguard Worker   using is_transparent = void;
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyThreeWayComp2731*9356374aSAndroid Build Coastguard Worker   absl::weak_ordering operator()(const MultiKey a, const MultiKey b) const {
2732*9356374aSAndroid Build Coastguard Worker     if (a.i1 < b.i1) return absl::weak_ordering::less;
2733*9356374aSAndroid Build Coastguard Worker     if (a.i1 > b.i1) return absl::weak_ordering::greater;
2734*9356374aSAndroid Build Coastguard Worker     if (a.i2 < b.i2) return absl::weak_ordering::less;
2735*9356374aSAndroid Build Coastguard Worker     if (a.i2 > b.i2) return absl::weak_ordering::greater;
2736*9356374aSAndroid Build Coastguard Worker     return absl::weak_ordering::equivalent;
2737*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyThreeWayComp2738*9356374aSAndroid Build Coastguard Worker   absl::weak_ordering operator()(const int a, const MultiKey b) const {
2739*9356374aSAndroid Build Coastguard Worker     if (a < b.i1) return absl::weak_ordering::less;
2740*9356374aSAndroid Build Coastguard Worker     if (a > b.i1) return absl::weak_ordering::greater;
2741*9356374aSAndroid Build Coastguard Worker     return absl::weak_ordering::equivalent;
2742*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0311::MultiKeyThreeWayComp2743*9356374aSAndroid Build Coastguard Worker   absl::weak_ordering operator()(const MultiKey a, const int b) const {
2744*9356374aSAndroid Build Coastguard Worker     if (a.i1 < b) return absl::weak_ordering::less;
2745*9356374aSAndroid Build Coastguard Worker     if (a.i1 > b) return absl::weak_ordering::greater;
2746*9356374aSAndroid Build Coastguard Worker     return absl::weak_ordering::equivalent;
2747*9356374aSAndroid Build Coastguard Worker   }
2748*9356374aSAndroid Build Coastguard Worker };
2749*9356374aSAndroid Build Coastguard Worker 
2750*9356374aSAndroid Build Coastguard Worker template <typename Compare>
2751*9356374aSAndroid Build Coastguard Worker class BtreeMultiKeyTest : public ::testing::Test {};
2752*9356374aSAndroid Build Coastguard Worker using MultiKeyComps = ::testing::Types<MultiKeyComp, MultiKeyThreeWayComp>;
2753*9356374aSAndroid Build Coastguard Worker TYPED_TEST_SUITE(BtreeMultiKeyTest, MultiKeyComps);
2754*9356374aSAndroid Build Coastguard Worker 
TYPED_TEST(BtreeMultiKeyTest,EqualRange)2755*9356374aSAndroid Build Coastguard Worker TYPED_TEST(BtreeMultiKeyTest, EqualRange) {
2756*9356374aSAndroid Build Coastguard Worker   absl::btree_set<MultiKey, TypeParam> set;
2757*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
2758*9356374aSAndroid Build Coastguard Worker     for (int j = 0; j < 100; ++j) {
2759*9356374aSAndroid Build Coastguard Worker       set.insert({i, j});
2760*9356374aSAndroid Build Coastguard Worker     }
2761*9356374aSAndroid Build Coastguard Worker   }
2762*9356374aSAndroid Build Coastguard Worker 
2763*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
2764*9356374aSAndroid Build Coastguard Worker     auto equal_range = set.equal_range(i);
2765*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(equal_range.first->i1, i);
2766*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(equal_range.first->i2, 0) << i;
2767*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(std::distance(equal_range.first, equal_range.second), 100) << i;
2768*9356374aSAndroid Build Coastguard Worker   }
2769*9356374aSAndroid Build Coastguard Worker }
2770*9356374aSAndroid Build Coastguard Worker 
TYPED_TEST(BtreeMultiKeyTest,Extract)2771*9356374aSAndroid Build Coastguard Worker TYPED_TEST(BtreeMultiKeyTest, Extract) {
2772*9356374aSAndroid Build Coastguard Worker   absl::btree_set<MultiKey, TypeParam> set;
2773*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
2774*9356374aSAndroid Build Coastguard Worker     for (int j = 0; j < 100; ++j) {
2775*9356374aSAndroid Build Coastguard Worker       set.insert({i, j});
2776*9356374aSAndroid Build Coastguard Worker     }
2777*9356374aSAndroid Build Coastguard Worker   }
2778*9356374aSAndroid Build Coastguard Worker 
2779*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
2780*9356374aSAndroid Build Coastguard Worker     auto node_handle = set.extract(i);
2781*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(node_handle.value().i1, i);
2782*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(node_handle.value().i2, 0) << i;
2783*9356374aSAndroid Build Coastguard Worker   }
2784*9356374aSAndroid Build Coastguard Worker 
2785*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) {
2786*9356374aSAndroid Build Coastguard Worker     auto node_handle = set.extract(i);
2787*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(node_handle.value().i1, i);
2788*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(node_handle.value().i2, 1) << i;
2789*9356374aSAndroid Build Coastguard Worker   }
2790*9356374aSAndroid Build Coastguard Worker }
2791*9356374aSAndroid Build Coastguard Worker 
TYPED_TEST(BtreeMultiKeyTest,Erase)2792*9356374aSAndroid Build Coastguard Worker TYPED_TEST(BtreeMultiKeyTest, Erase) {
2793*9356374aSAndroid Build Coastguard Worker   absl::btree_set<MultiKey, TypeParam> set = {
2794*9356374aSAndroid Build Coastguard Worker       {1, 1}, {2, 1}, {2, 2}, {3, 1}};
2795*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(set.erase(2), 2);
2796*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set, ElementsAre(MultiKey{1, 1}, MultiKey{3, 1}));
2797*9356374aSAndroid Build Coastguard Worker }
2798*9356374aSAndroid Build Coastguard Worker 
TYPED_TEST(BtreeMultiKeyTest,Count)2799*9356374aSAndroid Build Coastguard Worker TYPED_TEST(BtreeMultiKeyTest, Count) {
2800*9356374aSAndroid Build Coastguard Worker   const absl::btree_set<MultiKey, TypeParam> set = {
2801*9356374aSAndroid Build Coastguard Worker       {1, 1}, {2, 1}, {2, 2}, {3, 1}};
2802*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(set.count(2), 2);
2803*9356374aSAndroid Build Coastguard Worker }
2804*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,SetIteratorsAreConst)2805*9356374aSAndroid Build Coastguard Worker TEST(Btree, SetIteratorsAreConst) {
2806*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<int>;
2807*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
2808*9356374aSAndroid Build Coastguard Worker       (std::is_same<typename Set::iterator::reference, const int &>::value));
2809*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
2810*9356374aSAndroid Build Coastguard Worker       (std::is_same<typename Set::iterator::pointer, const int *>::value));
2811*9356374aSAndroid Build Coastguard Worker 
2812*9356374aSAndroid Build Coastguard Worker   using MSet = absl::btree_multiset<int>;
2813*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
2814*9356374aSAndroid Build Coastguard Worker       (std::is_same<typename MSet::iterator::reference, const int &>::value));
2815*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
2816*9356374aSAndroid Build Coastguard Worker       (std::is_same<typename MSet::iterator::pointer, const int *>::value));
2817*9356374aSAndroid Build Coastguard Worker }
2818*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,AllocConstructor)2819*9356374aSAndroid Build Coastguard Worker TEST(Btree, AllocConstructor) {
2820*9356374aSAndroid Build Coastguard Worker   using Alloc = CountingAllocator<int>;
2821*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2822*9356374aSAndroid Build Coastguard Worker   int64_t bytes_used = 0;
2823*9356374aSAndroid Build Coastguard Worker   Alloc alloc(&bytes_used);
2824*9356374aSAndroid Build Coastguard Worker   Set set(alloc);
2825*9356374aSAndroid Build Coastguard Worker 
2826*9356374aSAndroid Build Coastguard Worker   set.insert({1, 2, 3});
2827*9356374aSAndroid Build Coastguard Worker 
2828*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set, ElementsAre(1, 2, 3));
2829*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(bytes_used, set.size() * sizeof(int));
2830*9356374aSAndroid Build Coastguard Worker }
2831*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,AllocInitializerListConstructor)2832*9356374aSAndroid Build Coastguard Worker TEST(Btree, AllocInitializerListConstructor) {
2833*9356374aSAndroid Build Coastguard Worker   using Alloc = CountingAllocator<int>;
2834*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2835*9356374aSAndroid Build Coastguard Worker   int64_t bytes_used = 0;
2836*9356374aSAndroid Build Coastguard Worker   Alloc alloc(&bytes_used);
2837*9356374aSAndroid Build Coastguard Worker   Set set({1, 2, 3}, alloc);
2838*9356374aSAndroid Build Coastguard Worker 
2839*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set, ElementsAre(1, 2, 3));
2840*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(bytes_used, set.size() * sizeof(int));
2841*9356374aSAndroid Build Coastguard Worker }
2842*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,AllocRangeConstructor)2843*9356374aSAndroid Build Coastguard Worker TEST(Btree, AllocRangeConstructor) {
2844*9356374aSAndroid Build Coastguard Worker   using Alloc = CountingAllocator<int>;
2845*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2846*9356374aSAndroid Build Coastguard Worker   int64_t bytes_used = 0;
2847*9356374aSAndroid Build Coastguard Worker   Alloc alloc(&bytes_used);
2848*9356374aSAndroid Build Coastguard Worker   std::vector<int> v = {1, 2, 3};
2849*9356374aSAndroid Build Coastguard Worker   Set set(v.begin(), v.end(), alloc);
2850*9356374aSAndroid Build Coastguard Worker 
2851*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set, ElementsAre(1, 2, 3));
2852*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(bytes_used, set.size() * sizeof(int));
2853*9356374aSAndroid Build Coastguard Worker }
2854*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,AllocCopyConstructor)2855*9356374aSAndroid Build Coastguard Worker TEST(Btree, AllocCopyConstructor) {
2856*9356374aSAndroid Build Coastguard Worker   using Alloc = CountingAllocator<int>;
2857*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2858*9356374aSAndroid Build Coastguard Worker   int64_t bytes_used1 = 0;
2859*9356374aSAndroid Build Coastguard Worker   Alloc alloc1(&bytes_used1);
2860*9356374aSAndroid Build Coastguard Worker   Set set1(alloc1);
2861*9356374aSAndroid Build Coastguard Worker 
2862*9356374aSAndroid Build Coastguard Worker   set1.insert({1, 2, 3});
2863*9356374aSAndroid Build Coastguard Worker 
2864*9356374aSAndroid Build Coastguard Worker   int64_t bytes_used2 = 0;
2865*9356374aSAndroid Build Coastguard Worker   Alloc alloc2(&bytes_used2);
2866*9356374aSAndroid Build Coastguard Worker   Set set2(set1, alloc2);
2867*9356374aSAndroid Build Coastguard Worker 
2868*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set1, ElementsAre(1, 2, 3));
2869*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set2, ElementsAre(1, 2, 3));
2870*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(bytes_used1, set1.size() * sizeof(int));
2871*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes_used1, bytes_used2);
2872*9356374aSAndroid Build Coastguard Worker }
2873*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,AllocMoveConstructor_SameAlloc)2874*9356374aSAndroid Build Coastguard Worker TEST(Btree, AllocMoveConstructor_SameAlloc) {
2875*9356374aSAndroid Build Coastguard Worker   using Alloc = CountingAllocator<int>;
2876*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2877*9356374aSAndroid Build Coastguard Worker   int64_t bytes_used = 0;
2878*9356374aSAndroid Build Coastguard Worker   Alloc alloc(&bytes_used);
2879*9356374aSAndroid Build Coastguard Worker   Set set1(alloc);
2880*9356374aSAndroid Build Coastguard Worker 
2881*9356374aSAndroid Build Coastguard Worker   set1.insert({1, 2, 3});
2882*9356374aSAndroid Build Coastguard Worker 
2883*9356374aSAndroid Build Coastguard Worker   const int64_t original_bytes_used = bytes_used;
2884*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(original_bytes_used, set1.size() * sizeof(int));
2885*9356374aSAndroid Build Coastguard Worker 
2886*9356374aSAndroid Build Coastguard Worker   Set set2(std::move(set1), alloc);
2887*9356374aSAndroid Build Coastguard Worker 
2888*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set2, ElementsAre(1, 2, 3));
2889*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes_used, original_bytes_used);
2890*9356374aSAndroid Build Coastguard Worker }
2891*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,AllocMoveConstructor_DifferentAlloc)2892*9356374aSAndroid Build Coastguard Worker TEST(Btree, AllocMoveConstructor_DifferentAlloc) {
2893*9356374aSAndroid Build Coastguard Worker   using Alloc = CountingAllocator<int>;
2894*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<int, std::less<int>, Alloc>;
2895*9356374aSAndroid Build Coastguard Worker   int64_t bytes_used1 = 0;
2896*9356374aSAndroid Build Coastguard Worker   Alloc alloc1(&bytes_used1);
2897*9356374aSAndroid Build Coastguard Worker   Set set1(alloc1);
2898*9356374aSAndroid Build Coastguard Worker 
2899*9356374aSAndroid Build Coastguard Worker   set1.insert({1, 2, 3});
2900*9356374aSAndroid Build Coastguard Worker 
2901*9356374aSAndroid Build Coastguard Worker   const int64_t original_bytes_used = bytes_used1;
2902*9356374aSAndroid Build Coastguard Worker   EXPECT_GT(original_bytes_used, set1.size() * sizeof(int));
2903*9356374aSAndroid Build Coastguard Worker 
2904*9356374aSAndroid Build Coastguard Worker   int64_t bytes_used2 = 0;
2905*9356374aSAndroid Build Coastguard Worker   Alloc alloc2(&bytes_used2);
2906*9356374aSAndroid Build Coastguard Worker   Set set2(std::move(set1), alloc2);
2907*9356374aSAndroid Build Coastguard Worker 
2908*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set2, ElementsAre(1, 2, 3));
2909*9356374aSAndroid Build Coastguard Worker   // We didn't free these bytes allocated by `set1` yet.
2910*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes_used1, original_bytes_used);
2911*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes_used2, original_bytes_used);
2912*9356374aSAndroid Build Coastguard Worker }
2913*9356374aSAndroid Build Coastguard Worker 
IntCmp(const int a,const int b)2914*9356374aSAndroid Build Coastguard Worker bool IntCmp(const int a, const int b) { return a < b; }
2915*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,SupportsFunctionPtrComparator)2916*9356374aSAndroid Build Coastguard Worker TEST(Btree, SupportsFunctionPtrComparator) {
2917*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int, decltype(IntCmp) *> set(IntCmp);
2918*9356374aSAndroid Build Coastguard Worker   set.insert({1, 2, 3});
2919*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(set, ElementsAre(1, 2, 3));
2920*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(set.key_comp()(1, 2));
2921*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(set.value_comp()(1, 2));
2922*9356374aSAndroid Build Coastguard Worker 
2923*9356374aSAndroid Build Coastguard Worker   absl::btree_map<int, int, decltype(IntCmp) *> map(&IntCmp);
2924*9356374aSAndroid Build Coastguard Worker   map[1] = 1;
2925*9356374aSAndroid Build Coastguard Worker   EXPECT_THAT(map, ElementsAre(Pair(1, 1)));
2926*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(map.key_comp()(1, 2));
2927*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(map.value_comp()(std::make_pair(1, 1), std::make_pair(2, 2)));
2928*9356374aSAndroid Build Coastguard Worker }
2929*9356374aSAndroid Build Coastguard Worker 
2930*9356374aSAndroid Build Coastguard Worker template <typename Compare>
2931*9356374aSAndroid Build Coastguard Worker struct TransparentPassThroughComp {
2932*9356374aSAndroid Build Coastguard Worker   using is_transparent = void;
2933*9356374aSAndroid Build Coastguard Worker 
2934*9356374aSAndroid Build Coastguard Worker   // This will fail compilation if we attempt a comparison that Compare does not
2935*9356374aSAndroid Build Coastguard Worker   // support, and the failure will happen inside the function implementation so
2936*9356374aSAndroid Build Coastguard Worker   // it can't be avoided by using SFINAE on this comparator.
2937*9356374aSAndroid Build Coastguard Worker   template <typename T, typename U>
operator ()absl::container_internal::__anon7e8713fe0311::TransparentPassThroughComp2938*9356374aSAndroid Build Coastguard Worker   bool operator()(const T &lhs, const U &rhs) const {
2939*9356374aSAndroid Build Coastguard Worker     return Compare()(lhs, rhs);
2940*9356374aSAndroid Build Coastguard Worker   }
2941*9356374aSAndroid Build Coastguard Worker };
2942*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,SupportsTransparentComparatorThatDoesNotImplementAllVisibleOperators)2943*9356374aSAndroid Build Coastguard Worker TEST(Btree,
2944*9356374aSAndroid Build Coastguard Worker      SupportsTransparentComparatorThatDoesNotImplementAllVisibleOperators) {
2945*9356374aSAndroid Build Coastguard Worker   absl::btree_set<MultiKey, TransparentPassThroughComp<MultiKeyComp>> set;
2946*9356374aSAndroid Build Coastguard Worker   set.insert(MultiKey{1, 2});
2947*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(set.contains(1));
2948*9356374aSAndroid Build Coastguard Worker }
2949*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,ConstructImplicitlyWithUnadaptedComparator)2950*9356374aSAndroid Build Coastguard Worker TEST(Btree, ConstructImplicitlyWithUnadaptedComparator) {
2951*9356374aSAndroid Build Coastguard Worker   absl::btree_set<MultiKey, MultiKeyComp> set = {{}, MultiKeyComp{}};
2952*9356374aSAndroid Build Coastguard Worker }
2953*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,InvalidComparatorsCaught)2954*9356374aSAndroid Build Coastguard Worker TEST(Btree, InvalidComparatorsCaught) {
2955*9356374aSAndroid Build Coastguard Worker   if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
2956*9356374aSAndroid Build Coastguard Worker 
2957*9356374aSAndroid Build Coastguard Worker   {
2958*9356374aSAndroid Build Coastguard Worker     struct ZeroAlwaysLessCmp {
2959*9356374aSAndroid Build Coastguard Worker       bool operator()(int lhs, int rhs) const {
2960*9356374aSAndroid Build Coastguard Worker         if (lhs == 0) return true;
2961*9356374aSAndroid Build Coastguard Worker         return lhs < rhs;
2962*9356374aSAndroid Build Coastguard Worker       }
2963*9356374aSAndroid Build Coastguard Worker     };
2964*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int, ZeroAlwaysLessCmp> set;
2965*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.insert({0, 1, 2}), "is_self_equivalent");
2966*9356374aSAndroid Build Coastguard Worker   }
2967*9356374aSAndroid Build Coastguard Worker   {
2968*9356374aSAndroid Build Coastguard Worker     struct ThreeWayAlwaysLessCmp {
2969*9356374aSAndroid Build Coastguard Worker       absl::weak_ordering operator()(int, int) const {
2970*9356374aSAndroid Build Coastguard Worker         return absl::weak_ordering::less;
2971*9356374aSAndroid Build Coastguard Worker       }
2972*9356374aSAndroid Build Coastguard Worker     };
2973*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int, ThreeWayAlwaysLessCmp> set;
2974*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.insert({0, 1, 2}), "is_self_equivalent");
2975*9356374aSAndroid Build Coastguard Worker   }
2976*9356374aSAndroid Build Coastguard Worker   {
2977*9356374aSAndroid Build Coastguard Worker     struct SumGreaterZeroCmp {
2978*9356374aSAndroid Build Coastguard Worker       bool operator()(int lhs, int rhs) const {
2979*9356374aSAndroid Build Coastguard Worker         // First, do equivalence correctly - so we can test later condition.
2980*9356374aSAndroid Build Coastguard Worker         if (lhs == rhs) return false;
2981*9356374aSAndroid Build Coastguard Worker         return lhs + rhs > 0;
2982*9356374aSAndroid Build Coastguard Worker       }
2983*9356374aSAndroid Build Coastguard Worker     };
2984*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int, SumGreaterZeroCmp> set;
2985*9356374aSAndroid Build Coastguard Worker     // Note: '!' only needs to be escaped when it's the first character.
2986*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.insert({0, 1, 2}),
2987*9356374aSAndroid Build Coastguard Worker                  R"regex(\!lhs_comp_rhs \|\| !comp\(\)\(rhs, lhs\))regex");
2988*9356374aSAndroid Build Coastguard Worker   }
2989*9356374aSAndroid Build Coastguard Worker   {
2990*9356374aSAndroid Build Coastguard Worker     struct ThreeWaySumGreaterZeroCmp {
2991*9356374aSAndroid Build Coastguard Worker       absl::weak_ordering operator()(int lhs, int rhs) const {
2992*9356374aSAndroid Build Coastguard Worker         // First, do equivalence correctly - so we can test later condition.
2993*9356374aSAndroid Build Coastguard Worker         if (lhs == rhs) return absl::weak_ordering::equivalent;
2994*9356374aSAndroid Build Coastguard Worker 
2995*9356374aSAndroid Build Coastguard Worker         if (lhs + rhs > 0) return absl::weak_ordering::less;
2996*9356374aSAndroid Build Coastguard Worker         if (lhs + rhs == 0) return absl::weak_ordering::equivalent;
2997*9356374aSAndroid Build Coastguard Worker         return absl::weak_ordering::greater;
2998*9356374aSAndroid Build Coastguard Worker       }
2999*9356374aSAndroid Build Coastguard Worker     };
3000*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int, ThreeWaySumGreaterZeroCmp> set;
3001*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.insert({0, 1, 2}), "lhs_comp_rhs < 0 -> rhs_comp_lhs > 0");
3002*9356374aSAndroid Build Coastguard Worker   }
3003*9356374aSAndroid Build Coastguard Worker   // Verify that we detect cases of comparators that violate transitivity.
3004*9356374aSAndroid Build Coastguard Worker   // When the comparators below check for the presence of an optional field,
3005*9356374aSAndroid Build Coastguard Worker   // they violate transitivity because instances that have the optional field
3006*9356374aSAndroid Build Coastguard Worker   // compare differently with each other from how they compare with instances
3007*9356374aSAndroid Build Coastguard Worker   // that don't have the optional field.
3008*9356374aSAndroid Build Coastguard Worker   struct ClockTime {
3009*9356374aSAndroid Build Coastguard Worker     absl::optional<int> hour;
3010*9356374aSAndroid Build Coastguard Worker     int minute;
3011*9356374aSAndroid Build Coastguard Worker   };
3012*9356374aSAndroid Build Coastguard Worker   // `comp(a,b) && comp(b,c) && !comp(a,c)` violates transitivity.
3013*9356374aSAndroid Build Coastguard Worker   ClockTime a = {absl::nullopt, 1};
3014*9356374aSAndroid Build Coastguard Worker   ClockTime b = {2, 5};
3015*9356374aSAndroid Build Coastguard Worker   ClockTime c = {6, 0};
3016*9356374aSAndroid Build Coastguard Worker   {
3017*9356374aSAndroid Build Coastguard Worker     struct NonTransitiveTimeCmp {
3018*9356374aSAndroid Build Coastguard Worker       bool operator()(ClockTime lhs, ClockTime rhs) const {
3019*9356374aSAndroid Build Coastguard Worker         if (lhs.hour.has_value() && rhs.hour.has_value() &&
3020*9356374aSAndroid Build Coastguard Worker             *lhs.hour != *rhs.hour) {
3021*9356374aSAndroid Build Coastguard Worker           return *lhs.hour < *rhs.hour;
3022*9356374aSAndroid Build Coastguard Worker         }
3023*9356374aSAndroid Build Coastguard Worker         return lhs.minute < rhs.minute;
3024*9356374aSAndroid Build Coastguard Worker       }
3025*9356374aSAndroid Build Coastguard Worker     };
3026*9356374aSAndroid Build Coastguard Worker     NonTransitiveTimeCmp cmp;
3027*9356374aSAndroid Build Coastguard Worker     ASSERT_TRUE(cmp(a, b) && cmp(b, c) && !cmp(a, c));
3028*9356374aSAndroid Build Coastguard Worker     absl::btree_set<ClockTime, NonTransitiveTimeCmp> set;
3029*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.insert({a, b, c}), "is_ordered_correctly");
3030*9356374aSAndroid Build Coastguard Worker     absl::btree_multiset<ClockTime, NonTransitiveTimeCmp> mset;
3031*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(mset.insert({a, a, b, b, c, c}), "is_ordered_correctly");
3032*9356374aSAndroid Build Coastguard Worker   }
3033*9356374aSAndroid Build Coastguard Worker   {
3034*9356374aSAndroid Build Coastguard Worker     struct ThreeWayNonTransitiveTimeCmp {
3035*9356374aSAndroid Build Coastguard Worker       absl::weak_ordering operator()(ClockTime lhs, ClockTime rhs) const {
3036*9356374aSAndroid Build Coastguard Worker         if (lhs.hour.has_value() && rhs.hour.has_value() &&
3037*9356374aSAndroid Build Coastguard Worker             *lhs.hour != *rhs.hour) {
3038*9356374aSAndroid Build Coastguard Worker           return *lhs.hour < *rhs.hour ? absl::weak_ordering::less
3039*9356374aSAndroid Build Coastguard Worker                                        : absl::weak_ordering::greater;
3040*9356374aSAndroid Build Coastguard Worker         }
3041*9356374aSAndroid Build Coastguard Worker         return lhs.minute < rhs.minute    ? absl::weak_ordering::less
3042*9356374aSAndroid Build Coastguard Worker                : lhs.minute == rhs.minute ? absl::weak_ordering::equivalent
3043*9356374aSAndroid Build Coastguard Worker                                           : absl::weak_ordering::greater;
3044*9356374aSAndroid Build Coastguard Worker       }
3045*9356374aSAndroid Build Coastguard Worker     };
3046*9356374aSAndroid Build Coastguard Worker     ThreeWayNonTransitiveTimeCmp cmp;
3047*9356374aSAndroid Build Coastguard Worker     ASSERT_TRUE(cmp(a, b) < 0 && cmp(b, c) < 0 && cmp(a, c) > 0);
3048*9356374aSAndroid Build Coastguard Worker     absl::btree_set<ClockTime, ThreeWayNonTransitiveTimeCmp> set;
3049*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.insert({a, b, c}), "is_ordered_correctly");
3050*9356374aSAndroid Build Coastguard Worker     absl::btree_multiset<ClockTime, ThreeWayNonTransitiveTimeCmp> mset;
3051*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(mset.insert({a, a, b, b, c, c}), "is_ordered_correctly");
3052*9356374aSAndroid Build Coastguard Worker   }
3053*9356374aSAndroid Build Coastguard Worker }
3054*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,MutatedKeysCaught)3055*9356374aSAndroid Build Coastguard Worker TEST(Btree, MutatedKeysCaught) {
3056*9356374aSAndroid Build Coastguard Worker   if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3057*9356374aSAndroid Build Coastguard Worker 
3058*9356374aSAndroid Build Coastguard Worker   struct IntPtrCmp {
3059*9356374aSAndroid Build Coastguard Worker     bool operator()(int *lhs, int *rhs) const { return *lhs < *rhs; }
3060*9356374aSAndroid Build Coastguard Worker   };
3061*9356374aSAndroid Build Coastguard Worker   {
3062*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int *, IntPtrCmp> set;
3063*9356374aSAndroid Build Coastguard Worker     int arr[] = {0, 1, 2};
3064*9356374aSAndroid Build Coastguard Worker     set.insert({&arr[0], &arr[1], &arr[2]});
3065*9356374aSAndroid Build Coastguard Worker     arr[0] = 100;
3066*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.insert(&arr[0]), "is_ordered_correctly");
3067*9356374aSAndroid Build Coastguard Worker   }
3068*9356374aSAndroid Build Coastguard Worker   {
3069*9356374aSAndroid Build Coastguard Worker     absl::btree_multiset<int *, IntPtrCmp> set;
3070*9356374aSAndroid Build Coastguard Worker     int arr[] = {0, 1, 2};
3071*9356374aSAndroid Build Coastguard Worker     set.insert({&arr[0], &arr[0], &arr[1], &arr[1], &arr[2], &arr[2]});
3072*9356374aSAndroid Build Coastguard Worker     arr[0] = 100;
3073*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.insert(&arr[0]), "is_ordered_correctly");
3074*9356374aSAndroid Build Coastguard Worker   }
3075*9356374aSAndroid Build Coastguard Worker }
3076*9356374aSAndroid Build Coastguard Worker 
3077*9356374aSAndroid Build Coastguard Worker #ifndef _MSC_VER
3078*9356374aSAndroid Build Coastguard Worker // This test crashes on MSVC.
TEST(Btree,InvalidIteratorUse)3079*9356374aSAndroid Build Coastguard Worker TEST(Btree, InvalidIteratorUse) {
3080*9356374aSAndroid Build Coastguard Worker   if (!BtreeGenerationsEnabled())
3081*9356374aSAndroid Build Coastguard Worker     GTEST_SKIP() << "Generation validation for iterators is disabled.";
3082*9356374aSAndroid Build Coastguard Worker 
3083*9356374aSAndroid Build Coastguard Worker   // Invalid memory use can trigger use-after-free in ASan, HWASAN or
3084*9356374aSAndroid Build Coastguard Worker   // invalidated iterator assertions.
3085*9356374aSAndroid Build Coastguard Worker   constexpr const char *kInvalidMemoryDeathMessage =
3086*9356374aSAndroid Build Coastguard Worker       "use-after-free|invalidated iterator";
3087*9356374aSAndroid Build Coastguard Worker 
3088*9356374aSAndroid Build Coastguard Worker   {
3089*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> set;
3090*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i < 10; ++i) set.insert(i);
3091*9356374aSAndroid Build Coastguard Worker     auto it = set.begin();
3092*9356374aSAndroid Build Coastguard Worker     set.erase(it++);
3093*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(set.erase(it++), kInvalidMemoryDeathMessage);
3094*9356374aSAndroid Build Coastguard Worker   }
3095*9356374aSAndroid Build Coastguard Worker   {
3096*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> set;
3097*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i < 10; ++i) set.insert(i);
3098*9356374aSAndroid Build Coastguard Worker     auto it = set.insert(20).first;
3099*9356374aSAndroid Build Coastguard Worker     set.insert(30);
3100*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(*it, kInvalidMemoryDeathMessage);
3101*9356374aSAndroid Build Coastguard Worker   }
3102*9356374aSAndroid Build Coastguard Worker   {
3103*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> set;
3104*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i < 10000; ++i) set.insert(i);
3105*9356374aSAndroid Build Coastguard Worker     auto it = set.find(5000);
3106*9356374aSAndroid Build Coastguard Worker     ASSERT_NE(it, set.end());
3107*9356374aSAndroid Build Coastguard Worker     set.erase(1);
3108*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(*it, kInvalidMemoryDeathMessage);
3109*9356374aSAndroid Build Coastguard Worker   }
3110*9356374aSAndroid Build Coastguard Worker   {
3111*9356374aSAndroid Build Coastguard Worker     absl::btree_set<int> set;
3112*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i < 10; ++i) set.insert(i);
3113*9356374aSAndroid Build Coastguard Worker     auto it = set.insert(20).first;
3114*9356374aSAndroid Build Coastguard Worker     set.insert(30);
3115*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(void(it == set.begin()), kInvalidMemoryDeathMessage);
3116*9356374aSAndroid Build Coastguard Worker     EXPECT_DEATH(void(set.begin() == it), kInvalidMemoryDeathMessage);
3117*9356374aSAndroid Build Coastguard Worker   }
3118*9356374aSAndroid Build Coastguard Worker }
3119*9356374aSAndroid Build Coastguard Worker #endif
3120*9356374aSAndroid Build Coastguard Worker 
3121*9356374aSAndroid Build Coastguard Worker class OnlyConstructibleByAllocator {
OnlyConstructibleByAllocator(int i)3122*9356374aSAndroid Build Coastguard Worker   explicit OnlyConstructibleByAllocator(int i) : i_(i) {}
3123*9356374aSAndroid Build Coastguard Worker 
3124*9356374aSAndroid Build Coastguard Worker  public:
OnlyConstructibleByAllocator(const OnlyConstructibleByAllocator & other)3125*9356374aSAndroid Build Coastguard Worker   OnlyConstructibleByAllocator(const OnlyConstructibleByAllocator &other)
3126*9356374aSAndroid Build Coastguard Worker       : i_(other.i_) {}
operator =(const OnlyConstructibleByAllocator & other)3127*9356374aSAndroid Build Coastguard Worker   OnlyConstructibleByAllocator &operator=(
3128*9356374aSAndroid Build Coastguard Worker       const OnlyConstructibleByAllocator &other) {
3129*9356374aSAndroid Build Coastguard Worker     i_ = other.i_;
3130*9356374aSAndroid Build Coastguard Worker     return *this;
3131*9356374aSAndroid Build Coastguard Worker   }
Get() const3132*9356374aSAndroid Build Coastguard Worker   int Get() const { return i_; }
operator ==(int i) const3133*9356374aSAndroid Build Coastguard Worker   bool operator==(int i) const { return i_ == i; }
3134*9356374aSAndroid Build Coastguard Worker 
3135*9356374aSAndroid Build Coastguard Worker  private:
3136*9356374aSAndroid Build Coastguard Worker   template <typename T>
3137*9356374aSAndroid Build Coastguard Worker   friend class OnlyConstructibleAllocator;
3138*9356374aSAndroid Build Coastguard Worker 
3139*9356374aSAndroid Build Coastguard Worker   int i_;
3140*9356374aSAndroid Build Coastguard Worker };
3141*9356374aSAndroid Build Coastguard Worker 
3142*9356374aSAndroid Build Coastguard Worker template <typename T = OnlyConstructibleByAllocator>
3143*9356374aSAndroid Build Coastguard Worker class OnlyConstructibleAllocator : public std::allocator<T> {
3144*9356374aSAndroid Build Coastguard Worker  public:
3145*9356374aSAndroid Build Coastguard Worker   OnlyConstructibleAllocator() = default;
3146*9356374aSAndroid Build Coastguard Worker   template <class U>
OnlyConstructibleAllocator(const OnlyConstructibleAllocator<U> &)3147*9356374aSAndroid Build Coastguard Worker   explicit OnlyConstructibleAllocator(const OnlyConstructibleAllocator<U> &) {}
3148*9356374aSAndroid Build Coastguard Worker 
construct(OnlyConstructibleByAllocator * p,int i)3149*9356374aSAndroid Build Coastguard Worker   void construct(OnlyConstructibleByAllocator *p, int i) {
3150*9356374aSAndroid Build Coastguard Worker     new (p) OnlyConstructibleByAllocator(i);
3151*9356374aSAndroid Build Coastguard Worker   }
3152*9356374aSAndroid Build Coastguard Worker   template <typename Pair>
construct(Pair * p,const int i)3153*9356374aSAndroid Build Coastguard Worker   void construct(Pair *p, const int i) {
3154*9356374aSAndroid Build Coastguard Worker     OnlyConstructibleByAllocator only(i);
3155*9356374aSAndroid Build Coastguard Worker     new (p) Pair(std::move(only), i);
3156*9356374aSAndroid Build Coastguard Worker   }
3157*9356374aSAndroid Build Coastguard Worker 
3158*9356374aSAndroid Build Coastguard Worker   template <class U>
3159*9356374aSAndroid Build Coastguard Worker   struct rebind {
3160*9356374aSAndroid Build Coastguard Worker     using other = OnlyConstructibleAllocator<U>;
3161*9356374aSAndroid Build Coastguard Worker   };
3162*9356374aSAndroid Build Coastguard Worker };
3163*9356374aSAndroid Build Coastguard Worker 
3164*9356374aSAndroid Build Coastguard Worker struct OnlyConstructibleByAllocatorComp {
3165*9356374aSAndroid Build Coastguard Worker   using is_transparent = void;
operator ()absl::container_internal::__anon7e8713fe0311::OnlyConstructibleByAllocatorComp3166*9356374aSAndroid Build Coastguard Worker   bool operator()(OnlyConstructibleByAllocator a,
3167*9356374aSAndroid Build Coastguard Worker                   OnlyConstructibleByAllocator b) const {
3168*9356374aSAndroid Build Coastguard Worker     return a.Get() < b.Get();
3169*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0311::OnlyConstructibleByAllocatorComp3170*9356374aSAndroid Build Coastguard Worker   bool operator()(int a, OnlyConstructibleByAllocator b) const {
3171*9356374aSAndroid Build Coastguard Worker     return a < b.Get();
3172*9356374aSAndroid Build Coastguard Worker   }
operator ()absl::container_internal::__anon7e8713fe0311::OnlyConstructibleByAllocatorComp3173*9356374aSAndroid Build Coastguard Worker   bool operator()(OnlyConstructibleByAllocator a, int b) const {
3174*9356374aSAndroid Build Coastguard Worker     return a.Get() < b;
3175*9356374aSAndroid Build Coastguard Worker   }
3176*9356374aSAndroid Build Coastguard Worker };
3177*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,OnlyConstructibleByAllocatorType)3178*9356374aSAndroid Build Coastguard Worker TEST(Btree, OnlyConstructibleByAllocatorType) {
3179*9356374aSAndroid Build Coastguard Worker   const std::array<int, 2> arr = {3, 4};
3180*9356374aSAndroid Build Coastguard Worker   {
3181*9356374aSAndroid Build Coastguard Worker     absl::btree_set<OnlyConstructibleByAllocator,
3182*9356374aSAndroid Build Coastguard Worker                     OnlyConstructibleByAllocatorComp,
3183*9356374aSAndroid Build Coastguard Worker                     OnlyConstructibleAllocator<>>
3184*9356374aSAndroid Build Coastguard Worker         set;
3185*9356374aSAndroid Build Coastguard Worker     set.emplace(1);
3186*9356374aSAndroid Build Coastguard Worker     set.emplace_hint(set.end(), 2);
3187*9356374aSAndroid Build Coastguard Worker     set.insert(arr.begin(), arr.end());
3188*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(set, ElementsAre(1, 2, 3, 4));
3189*9356374aSAndroid Build Coastguard Worker   }
3190*9356374aSAndroid Build Coastguard Worker   {
3191*9356374aSAndroid Build Coastguard Worker     absl::btree_multiset<OnlyConstructibleByAllocator,
3192*9356374aSAndroid Build Coastguard Worker                          OnlyConstructibleByAllocatorComp,
3193*9356374aSAndroid Build Coastguard Worker                          OnlyConstructibleAllocator<>>
3194*9356374aSAndroid Build Coastguard Worker         set;
3195*9356374aSAndroid Build Coastguard Worker     set.emplace(1);
3196*9356374aSAndroid Build Coastguard Worker     set.emplace_hint(set.end(), 2);
3197*9356374aSAndroid Build Coastguard Worker     // TODO(ezb): fix insert_multi to allow this to compile.
3198*9356374aSAndroid Build Coastguard Worker     // set.insert(arr.begin(), arr.end());
3199*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(set, ElementsAre(1, 2));
3200*9356374aSAndroid Build Coastguard Worker   }
3201*9356374aSAndroid Build Coastguard Worker   {
3202*9356374aSAndroid Build Coastguard Worker     absl::btree_map<OnlyConstructibleByAllocator, int,
3203*9356374aSAndroid Build Coastguard Worker                     OnlyConstructibleByAllocatorComp,
3204*9356374aSAndroid Build Coastguard Worker                     OnlyConstructibleAllocator<>>
3205*9356374aSAndroid Build Coastguard Worker         map;
3206*9356374aSAndroid Build Coastguard Worker     map.emplace(1);
3207*9356374aSAndroid Build Coastguard Worker     map.emplace_hint(map.end(), 2);
3208*9356374aSAndroid Build Coastguard Worker     map.insert(arr.begin(), arr.end());
3209*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(map,
3210*9356374aSAndroid Build Coastguard Worker                 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3211*9356374aSAndroid Build Coastguard Worker   }
3212*9356374aSAndroid Build Coastguard Worker   {
3213*9356374aSAndroid Build Coastguard Worker     absl::btree_multimap<OnlyConstructibleByAllocator, int,
3214*9356374aSAndroid Build Coastguard Worker                          OnlyConstructibleByAllocatorComp,
3215*9356374aSAndroid Build Coastguard Worker                          OnlyConstructibleAllocator<>>
3216*9356374aSAndroid Build Coastguard Worker         map;
3217*9356374aSAndroid Build Coastguard Worker     map.emplace(1);
3218*9356374aSAndroid Build Coastguard Worker     map.emplace_hint(map.end(), 2);
3219*9356374aSAndroid Build Coastguard Worker     // TODO(ezb): fix insert_multi to allow this to compile.
3220*9356374aSAndroid Build Coastguard Worker     // map.insert(arr.begin(), arr.end());
3221*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(map, ElementsAre(Pair(1, 1), Pair(2, 2)));
3222*9356374aSAndroid Build Coastguard Worker   }
3223*9356374aSAndroid Build Coastguard Worker }
3224*9356374aSAndroid Build Coastguard Worker 
3225*9356374aSAndroid Build Coastguard Worker class NotAssignable {
3226*9356374aSAndroid Build Coastguard Worker  public:
NotAssignable(int i)3227*9356374aSAndroid Build Coastguard Worker   explicit NotAssignable(int i) : i_(i) {}
NotAssignable(const NotAssignable & other)3228*9356374aSAndroid Build Coastguard Worker   NotAssignable(const NotAssignable &other) : i_(other.i_) {}
3229*9356374aSAndroid Build Coastguard Worker   NotAssignable &operator=(NotAssignable &&other) = delete;
Get() const3230*9356374aSAndroid Build Coastguard Worker   int Get() const { return i_; }
operator ==(int i) const3231*9356374aSAndroid Build Coastguard Worker   bool operator==(int i) const { return i_ == i; }
operator <(NotAssignable a,NotAssignable b)3232*9356374aSAndroid Build Coastguard Worker   friend bool operator<(NotAssignable a, NotAssignable b) {
3233*9356374aSAndroid Build Coastguard Worker     return a.i_ < b.i_;
3234*9356374aSAndroid Build Coastguard Worker   }
3235*9356374aSAndroid Build Coastguard Worker 
3236*9356374aSAndroid Build Coastguard Worker  private:
3237*9356374aSAndroid Build Coastguard Worker   int i_;
3238*9356374aSAndroid Build Coastguard Worker };
3239*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,NotAssignableType)3240*9356374aSAndroid Build Coastguard Worker TEST(Btree, NotAssignableType) {
3241*9356374aSAndroid Build Coastguard Worker   {
3242*9356374aSAndroid Build Coastguard Worker     absl::btree_set<NotAssignable> set;
3243*9356374aSAndroid Build Coastguard Worker     set.emplace(1);
3244*9356374aSAndroid Build Coastguard Worker     set.emplace_hint(set.end(), 2);
3245*9356374aSAndroid Build Coastguard Worker     set.insert(NotAssignable(3));
3246*9356374aSAndroid Build Coastguard Worker     set.insert(set.end(), NotAssignable(4));
3247*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(set, ElementsAre(1, 2, 3, 4));
3248*9356374aSAndroid Build Coastguard Worker     set.erase(set.begin());
3249*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(set, ElementsAre(2, 3, 4));
3250*9356374aSAndroid Build Coastguard Worker   }
3251*9356374aSAndroid Build Coastguard Worker   {
3252*9356374aSAndroid Build Coastguard Worker     absl::btree_multiset<NotAssignable> set;
3253*9356374aSAndroid Build Coastguard Worker     set.emplace(1);
3254*9356374aSAndroid Build Coastguard Worker     set.emplace_hint(set.end(), 2);
3255*9356374aSAndroid Build Coastguard Worker     set.insert(NotAssignable(2));
3256*9356374aSAndroid Build Coastguard Worker     set.insert(set.end(), NotAssignable(3));
3257*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(set, ElementsAre(1, 2, 2, 3));
3258*9356374aSAndroid Build Coastguard Worker     set.erase(set.begin());
3259*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(set, ElementsAre(2, 2, 3));
3260*9356374aSAndroid Build Coastguard Worker   }
3261*9356374aSAndroid Build Coastguard Worker   {
3262*9356374aSAndroid Build Coastguard Worker     absl::btree_map<NotAssignable, int> map;
3263*9356374aSAndroid Build Coastguard Worker     map.emplace(NotAssignable(1), 1);
3264*9356374aSAndroid Build Coastguard Worker     map.emplace_hint(map.end(), NotAssignable(2), 2);
3265*9356374aSAndroid Build Coastguard Worker     map.insert({NotAssignable(3), 3});
3266*9356374aSAndroid Build Coastguard Worker     map.insert(map.end(), {NotAssignable(4), 4});
3267*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(map,
3268*9356374aSAndroid Build Coastguard Worker                 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3269*9356374aSAndroid Build Coastguard Worker     map.erase(map.begin());
3270*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(map, ElementsAre(Pair(2, 2), Pair(3, 3), Pair(4, 4)));
3271*9356374aSAndroid Build Coastguard Worker   }
3272*9356374aSAndroid Build Coastguard Worker   {
3273*9356374aSAndroid Build Coastguard Worker     absl::btree_multimap<NotAssignable, int> map;
3274*9356374aSAndroid Build Coastguard Worker     map.emplace(NotAssignable(1), 1);
3275*9356374aSAndroid Build Coastguard Worker     map.emplace_hint(map.end(), NotAssignable(2), 2);
3276*9356374aSAndroid Build Coastguard Worker     map.insert({NotAssignable(2), 3});
3277*9356374aSAndroid Build Coastguard Worker     map.insert(map.end(), {NotAssignable(3), 3});
3278*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(map,
3279*9356374aSAndroid Build Coastguard Worker                 ElementsAre(Pair(1, 1), Pair(2, 2), Pair(2, 3), Pair(3, 3)));
3280*9356374aSAndroid Build Coastguard Worker     map.erase(map.begin());
3281*9356374aSAndroid Build Coastguard Worker     EXPECT_THAT(map, ElementsAre(Pair(2, 2), Pair(2, 3), Pair(3, 3)));
3282*9356374aSAndroid Build Coastguard Worker   }
3283*9356374aSAndroid Build Coastguard Worker }
3284*9356374aSAndroid Build Coastguard Worker 
3285*9356374aSAndroid Build Coastguard Worker struct ArenaLike {
3286*9356374aSAndroid Build Coastguard Worker   void* recycled = nullptr;
3287*9356374aSAndroid Build Coastguard Worker   size_t recycled_size = 0;
3288*9356374aSAndroid Build Coastguard Worker };
3289*9356374aSAndroid Build Coastguard Worker 
3290*9356374aSAndroid Build Coastguard Worker // A very simple implementation of arena allocation.
3291*9356374aSAndroid Build Coastguard Worker template <typename T>
3292*9356374aSAndroid Build Coastguard Worker class ArenaLikeAllocator : public std::allocator<T> {
3293*9356374aSAndroid Build Coastguard Worker  public:
3294*9356374aSAndroid Build Coastguard Worker   // Standard library containers require the ability to allocate objects of
3295*9356374aSAndroid Build Coastguard Worker   // different types which they can do so via rebind.other.
3296*9356374aSAndroid Build Coastguard Worker   template <typename U>
3297*9356374aSAndroid Build Coastguard Worker   struct rebind {
3298*9356374aSAndroid Build Coastguard Worker     using other = ArenaLikeAllocator<U>;
3299*9356374aSAndroid Build Coastguard Worker   };
3300*9356374aSAndroid Build Coastguard Worker 
ArenaLikeAllocator(ArenaLike * arena)3301*9356374aSAndroid Build Coastguard Worker   explicit ArenaLikeAllocator(ArenaLike* arena) noexcept : arena_(arena) {}
3302*9356374aSAndroid Build Coastguard Worker 
~ArenaLikeAllocator()3303*9356374aSAndroid Build Coastguard Worker   ~ArenaLikeAllocator() {
3304*9356374aSAndroid Build Coastguard Worker     if (arena_->recycled != nullptr) {
3305*9356374aSAndroid Build Coastguard Worker       delete [] static_cast<T*>(arena_->recycled);
3306*9356374aSAndroid Build Coastguard Worker       arena_->recycled = nullptr;
3307*9356374aSAndroid Build Coastguard Worker     }
3308*9356374aSAndroid Build Coastguard Worker   }
3309*9356374aSAndroid Build Coastguard Worker 
3310*9356374aSAndroid Build Coastguard Worker   template<typename U>
ArenaLikeAllocator(const ArenaLikeAllocator<U> & other)3311*9356374aSAndroid Build Coastguard Worker   explicit ArenaLikeAllocator(const ArenaLikeAllocator<U>& other) noexcept
3312*9356374aSAndroid Build Coastguard Worker       : arena_(other.arena_) {}
3313*9356374aSAndroid Build Coastguard Worker 
allocate(size_t num_objects,const void * =nullptr)3314*9356374aSAndroid Build Coastguard Worker   T* allocate(size_t num_objects, const void* = nullptr) {
3315*9356374aSAndroid Build Coastguard Worker     size_t size = num_objects * sizeof(T);
3316*9356374aSAndroid Build Coastguard Worker     if (arena_->recycled != nullptr && arena_->recycled_size == size) {
3317*9356374aSAndroid Build Coastguard Worker       T* result = static_cast<T*>(arena_->recycled);
3318*9356374aSAndroid Build Coastguard Worker       arena_->recycled = nullptr;
3319*9356374aSAndroid Build Coastguard Worker       return result;
3320*9356374aSAndroid Build Coastguard Worker     }
3321*9356374aSAndroid Build Coastguard Worker     return new T[num_objects];
3322*9356374aSAndroid Build Coastguard Worker   }
3323*9356374aSAndroid Build Coastguard Worker 
deallocate(T * p,size_t num_objects)3324*9356374aSAndroid Build Coastguard Worker   void deallocate(T* p, size_t num_objects) {
3325*9356374aSAndroid Build Coastguard Worker     size_t size = num_objects * sizeof(T);
3326*9356374aSAndroid Build Coastguard Worker 
3327*9356374aSAndroid Build Coastguard Worker     // Simulate writing to the freed memory as an actual arena allocator might
3328*9356374aSAndroid Build Coastguard Worker     // do. This triggers an error report if the memory is poisoned.
3329*9356374aSAndroid Build Coastguard Worker     memset(p, 0xde, size);
3330*9356374aSAndroid Build Coastguard Worker 
3331*9356374aSAndroid Build Coastguard Worker     if (arena_->recycled == nullptr) {
3332*9356374aSAndroid Build Coastguard Worker       arena_->recycled = p;
3333*9356374aSAndroid Build Coastguard Worker       arena_->recycled_size = size;
3334*9356374aSAndroid Build Coastguard Worker     } else {
3335*9356374aSAndroid Build Coastguard Worker       delete [] p;
3336*9356374aSAndroid Build Coastguard Worker     }
3337*9356374aSAndroid Build Coastguard Worker   }
3338*9356374aSAndroid Build Coastguard Worker 
3339*9356374aSAndroid Build Coastguard Worker   ArenaLike* arena_;
3340*9356374aSAndroid Build Coastguard Worker };
3341*9356374aSAndroid Build Coastguard Worker 
3342*9356374aSAndroid Build Coastguard Worker // This test verifies that an arena allocator that reuses memory will not be
3343*9356374aSAndroid Build Coastguard Worker // asked to free poisoned BTree memory.
TEST(Btree,ReusePoisonMemory)3344*9356374aSAndroid Build Coastguard Worker TEST(Btree, ReusePoisonMemory) {
3345*9356374aSAndroid Build Coastguard Worker   using Alloc = ArenaLikeAllocator<int64_t>;
3346*9356374aSAndroid Build Coastguard Worker   using Set = absl::btree_set<int64_t, std::less<int64_t>, Alloc>;
3347*9356374aSAndroid Build Coastguard Worker   ArenaLike arena;
3348*9356374aSAndroid Build Coastguard Worker   Alloc alloc(&arena);
3349*9356374aSAndroid Build Coastguard Worker   Set set(alloc);
3350*9356374aSAndroid Build Coastguard Worker 
3351*9356374aSAndroid Build Coastguard Worker   set.insert(0);
3352*9356374aSAndroid Build Coastguard Worker   set.erase(0);
3353*9356374aSAndroid Build Coastguard Worker   set.insert(0);
3354*9356374aSAndroid Build Coastguard Worker }
3355*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,IteratorSubtraction)3356*9356374aSAndroid Build Coastguard Worker TEST(Btree, IteratorSubtraction) {
3357*9356374aSAndroid Build Coastguard Worker   absl::BitGen bitgen;
3358*9356374aSAndroid Build Coastguard Worker   std::vector<int> vec;
3359*9356374aSAndroid Build Coastguard Worker   // Randomize the set's insertion order so the nodes aren't all full.
3360*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 1000000; ++i) vec.push_back(i);
3361*9356374aSAndroid Build Coastguard Worker   absl::c_shuffle(vec, bitgen);
3362*9356374aSAndroid Build Coastguard Worker 
3363*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> set;
3364*9356374aSAndroid Build Coastguard Worker   for (int i : vec) set.insert(i);
3365*9356374aSAndroid Build Coastguard Worker 
3366*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 1000; ++i) {
3367*9356374aSAndroid Build Coastguard Worker     size_t begin = absl::Uniform(bitgen, 0u, set.size());
3368*9356374aSAndroid Build Coastguard Worker     size_t end = absl::Uniform(bitgen, begin, set.size());
3369*9356374aSAndroid Build Coastguard Worker     ASSERT_EQ(end - begin, set.find(end) - set.find(begin))
3370*9356374aSAndroid Build Coastguard Worker         << begin << " " << end;
3371*9356374aSAndroid Build Coastguard Worker   }
3372*9356374aSAndroid Build Coastguard Worker }
3373*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,DereferencingEndIterator)3374*9356374aSAndroid Build Coastguard Worker TEST(Btree, DereferencingEndIterator) {
3375*9356374aSAndroid Build Coastguard Worker   if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3376*9356374aSAndroid Build Coastguard Worker 
3377*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> set;
3378*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 1000; ++i) set.insert(i);
3379*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH(*set.end(), R"regex(Dereferencing end\(\) iterator)regex");
3380*9356374aSAndroid Build Coastguard Worker }
3381*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,InvalidIteratorComparison)3382*9356374aSAndroid Build Coastguard Worker TEST(Btree, InvalidIteratorComparison) {
3383*9356374aSAndroid Build Coastguard Worker   if (!IsAssertEnabled()) GTEST_SKIP() << "Assertions not enabled.";
3384*9356374aSAndroid Build Coastguard Worker 
3385*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> set1, set2;
3386*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 1000; ++i) {
3387*9356374aSAndroid Build Coastguard Worker     set1.insert(i);
3388*9356374aSAndroid Build Coastguard Worker     set2.insert(i);
3389*9356374aSAndroid Build Coastguard Worker   }
3390*9356374aSAndroid Build Coastguard Worker 
3391*9356374aSAndroid Build Coastguard Worker   constexpr const char *kValueInitDeathMessage =
3392*9356374aSAndroid Build Coastguard Worker       "Comparing default-constructed iterator with .*non-default-constructed "
3393*9356374aSAndroid Build Coastguard Worker       "iterator";
3394*9356374aSAndroid Build Coastguard Worker   typename absl::btree_set<int>::iterator iter1, iter2;
3395*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(iter1, iter2);
3396*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH(void(set1.begin() == iter1), kValueInitDeathMessage);
3397*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH(void(iter1 == set1.begin()), kValueInitDeathMessage);
3398*9356374aSAndroid Build Coastguard Worker 
3399*9356374aSAndroid Build Coastguard Worker   constexpr const char *kDifferentContainerDeathMessage =
3400*9356374aSAndroid Build Coastguard Worker       "Comparing iterators from different containers";
3401*9356374aSAndroid Build Coastguard Worker   iter1 = set1.begin();
3402*9356374aSAndroid Build Coastguard Worker   iter2 = set2.begin();
3403*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH(void(iter1 == iter2), kDifferentContainerDeathMessage);
3404*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH(void(iter2 == iter1), kDifferentContainerDeathMessage);
3405*9356374aSAndroid Build Coastguard Worker }
3406*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,InvalidPointerUse)3407*9356374aSAndroid Build Coastguard Worker TEST(Btree, InvalidPointerUse) {
3408*9356374aSAndroid Build Coastguard Worker   if (!kAsan)
3409*9356374aSAndroid Build Coastguard Worker     GTEST_SKIP() << "We only detect invalid pointer use in ASan mode.";
3410*9356374aSAndroid Build Coastguard Worker 
3411*9356374aSAndroid Build Coastguard Worker   absl::btree_set<int> set;
3412*9356374aSAndroid Build Coastguard Worker   set.insert(0);
3413*9356374aSAndroid Build Coastguard Worker   const int *ptr = &*set.begin();
3414*9356374aSAndroid Build Coastguard Worker   set.insert(1);
3415*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH(std::cout << *ptr, "use-after-free");
3416*9356374aSAndroid Build Coastguard Worker   size_t slots_per_node = BtreeNodePeer::GetNumSlotsPerNode<decltype(set)>();
3417*9356374aSAndroid Build Coastguard Worker   for (int i = 2; i < slots_per_node - 1; ++i) set.insert(i);
3418*9356374aSAndroid Build Coastguard Worker   ptr = &*set.begin();
3419*9356374aSAndroid Build Coastguard Worker   set.insert(static_cast<int>(slots_per_node));
3420*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH(std::cout << *ptr, "use-after-free");
3421*9356374aSAndroid Build Coastguard Worker }
3422*9356374aSAndroid Build Coastguard Worker 
3423*9356374aSAndroid Build Coastguard Worker template<typename Set>
TestBasicFunctionality(Set set)3424*9356374aSAndroid Build Coastguard Worker void TestBasicFunctionality(Set set) {
3425*9356374aSAndroid Build Coastguard Worker   using value_type = typename Set::value_type;
3426*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 100; ++i) { set.insert(value_type(i)); }
3427*9356374aSAndroid Build Coastguard Worker   for (int i = 50; i < 100; ++i) { set.erase(value_type(i)); }
3428*9356374aSAndroid Build Coastguard Worker   auto it = set.begin();
3429*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 50; ++i, ++it) {
3430*9356374aSAndroid Build Coastguard Worker     ASSERT_EQ(set.find(value_type(i)), it) << i;
3431*9356374aSAndroid Build Coastguard Worker   }
3432*9356374aSAndroid Build Coastguard Worker }
3433*9356374aSAndroid Build Coastguard Worker 
3434*9356374aSAndroid Build Coastguard Worker template<size_t align>
3435*9356374aSAndroid Build Coastguard Worker struct alignas(align) OveralignedKey {
OveralignedKeyabsl::container_internal::__anon7e8713fe0311::OveralignedKey3436*9356374aSAndroid Build Coastguard Worker   explicit OveralignedKey(int i) : key(i) {}
operator <absl::container_internal::__anon7e8713fe0311::OveralignedKey3437*9356374aSAndroid Build Coastguard Worker   bool operator<(const OveralignedKey &other) const { return key < other.key; }
3438*9356374aSAndroid Build Coastguard Worker   int key = 0;
3439*9356374aSAndroid Build Coastguard Worker };
3440*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,OveralignedKey)3441*9356374aSAndroid Build Coastguard Worker TEST(Btree, OveralignedKey) {
3442*9356374aSAndroid Build Coastguard Worker   // Test basic functionality with both even and odd numbers of slots per node.
3443*9356374aSAndroid Build Coastguard Worker   // The goal here is to detect cases where alignment may be incorrect.
3444*9356374aSAndroid Build Coastguard Worker   TestBasicFunctionality(
3445*9356374aSAndroid Build Coastguard Worker       SizedBtreeSet<OveralignedKey<16>, /*TargetValuesPerNode=*/8>());
3446*9356374aSAndroid Build Coastguard Worker   TestBasicFunctionality(
3447*9356374aSAndroid Build Coastguard Worker       SizedBtreeSet<OveralignedKey<16>, /*TargetValuesPerNode=*/9>());
3448*9356374aSAndroid Build Coastguard Worker }
3449*9356374aSAndroid Build Coastguard Worker 
TEST(Btree,FieldTypeEqualsSlotType)3450*9356374aSAndroid Build Coastguard Worker TEST(Btree, FieldTypeEqualsSlotType) {
3451*9356374aSAndroid Build Coastguard Worker   // This breaks if we try to do layout_type::Pointer<slot_type> because
3452*9356374aSAndroid Build Coastguard Worker   // slot_type is the same as field_type.
3453*9356374aSAndroid Build Coastguard Worker   using set_type = absl::btree_set<uint8_t>;
3454*9356374aSAndroid Build Coastguard Worker   static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>(), "");
3455*9356374aSAndroid Build Coastguard Worker   TestBasicFunctionality(set_type());
3456*9356374aSAndroid Build Coastguard Worker }
3457*9356374aSAndroid Build Coastguard Worker 
3458*9356374aSAndroid Build Coastguard Worker }  // namespace
3459*9356374aSAndroid Build Coastguard Worker }  // namespace container_internal
3460*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
3461*9356374aSAndroid Build Coastguard Worker }  // namespace absl
3462