1*635a8641SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/containers/flat_map.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <string>
8*635a8641SAndroid Build Coastguard Worker #include <vector>
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/test/move_only_int.h"
12*635a8641SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
13*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
14*635a8641SAndroid Build Coastguard Worker
15*635a8641SAndroid Build Coastguard Worker // A flat_map is basically a interface to flat_tree. So several basic
16*635a8641SAndroid Build Coastguard Worker // operations are tested to make sure things are set up properly, but the bulk
17*635a8641SAndroid Build Coastguard Worker // of the tests are in flat_tree_unittests.cc.
18*635a8641SAndroid Build Coastguard Worker
19*635a8641SAndroid Build Coastguard Worker using ::testing::ElementsAre;
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker namespace base {
22*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,IncompleteType)23*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, IncompleteType) {
24*635a8641SAndroid Build Coastguard Worker struct A {
25*635a8641SAndroid Build Coastguard Worker using Map = flat_map<A, A>;
26*635a8641SAndroid Build Coastguard Worker int data;
27*635a8641SAndroid Build Coastguard Worker Map set_with_incomplete_type;
28*635a8641SAndroid Build Coastguard Worker Map::iterator it;
29*635a8641SAndroid Build Coastguard Worker Map::const_iterator cit;
30*635a8641SAndroid Build Coastguard Worker
31*635a8641SAndroid Build Coastguard Worker // We do not declare operator< because clang complains that it's unused.
32*635a8641SAndroid Build Coastguard Worker };
33*635a8641SAndroid Build Coastguard Worker
34*635a8641SAndroid Build Coastguard Worker A a;
35*635a8641SAndroid Build Coastguard Worker }
36*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,RangeConstructor)37*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, RangeConstructor) {
38*635a8641SAndroid Build Coastguard Worker flat_map<int, int>::value_type input_vals[] = {
39*635a8641SAndroid Build Coastguard Worker {1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2}, {2, 3}, {3, 1}, {3, 2}, {3, 3}};
40*635a8641SAndroid Build Coastguard Worker
41*635a8641SAndroid Build Coastguard Worker flat_map<int, int> first(std::begin(input_vals), std::end(input_vals));
42*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(first, ElementsAre(std::make_pair(1, 1), std::make_pair(2, 1),
43*635a8641SAndroid Build Coastguard Worker std::make_pair(3, 1)));
44*635a8641SAndroid Build Coastguard Worker
45*635a8641SAndroid Build Coastguard Worker flat_map<int, int> last(std::begin(input_vals), std::end(input_vals),
46*635a8641SAndroid Build Coastguard Worker KEEP_LAST_OF_DUPES);
47*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(last, ElementsAre(std::make_pair(1, 3), std::make_pair(2, 3),
48*635a8641SAndroid Build Coastguard Worker std::make_pair(3, 3)));
49*635a8641SAndroid Build Coastguard Worker }
50*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,MoveConstructor)51*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, MoveConstructor) {
52*635a8641SAndroid Build Coastguard Worker using pair = std::pair<MoveOnlyInt, MoveOnlyInt>;
53*635a8641SAndroid Build Coastguard Worker
54*635a8641SAndroid Build Coastguard Worker flat_map<MoveOnlyInt, MoveOnlyInt> original;
55*635a8641SAndroid Build Coastguard Worker original.insert(pair(MoveOnlyInt(1), MoveOnlyInt(1)));
56*635a8641SAndroid Build Coastguard Worker original.insert(pair(MoveOnlyInt(2), MoveOnlyInt(2)));
57*635a8641SAndroid Build Coastguard Worker original.insert(pair(MoveOnlyInt(3), MoveOnlyInt(3)));
58*635a8641SAndroid Build Coastguard Worker original.insert(pair(MoveOnlyInt(4), MoveOnlyInt(4)));
59*635a8641SAndroid Build Coastguard Worker
60*635a8641SAndroid Build Coastguard Worker flat_map<MoveOnlyInt, MoveOnlyInt> moved(std::move(original));
61*635a8641SAndroid Build Coastguard Worker
62*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1U, moved.count(MoveOnlyInt(1)));
63*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1U, moved.count(MoveOnlyInt(2)));
64*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1U, moved.count(MoveOnlyInt(3)));
65*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1U, moved.count(MoveOnlyInt(4)));
66*635a8641SAndroid Build Coastguard Worker }
67*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,VectorConstructor)68*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, VectorConstructor) {
69*635a8641SAndroid Build Coastguard Worker using IntPair = std::pair<int, int>;
70*635a8641SAndroid Build Coastguard Worker using IntMap = flat_map<int, int>;
71*635a8641SAndroid Build Coastguard Worker {
72*635a8641SAndroid Build Coastguard Worker std::vector<IntPair> vect{{1, 1}, {1, 2}, {2, 1}};
73*635a8641SAndroid Build Coastguard Worker IntMap map(std::move(vect));
74*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(map, ElementsAre(IntPair(1, 1), IntPair(2, 1)));
75*635a8641SAndroid Build Coastguard Worker }
76*635a8641SAndroid Build Coastguard Worker {
77*635a8641SAndroid Build Coastguard Worker std::vector<IntPair> vect{{1, 1}, {1, 2}, {2, 1}};
78*635a8641SAndroid Build Coastguard Worker IntMap map(std::move(vect), KEEP_LAST_OF_DUPES);
79*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(map, ElementsAre(IntPair(1, 2), IntPair(2, 1)));
80*635a8641SAndroid Build Coastguard Worker }
81*635a8641SAndroid Build Coastguard Worker }
82*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,InitializerListConstructor)83*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, InitializerListConstructor) {
84*635a8641SAndroid Build Coastguard Worker {
85*635a8641SAndroid Build Coastguard Worker flat_map<int, int> cont(
86*635a8641SAndroid Build Coastguard Worker {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {1, 2}, {10, 10}, {8, 8}});
87*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(cont, ElementsAre(std::make_pair(1, 1), std::make_pair(2, 2),
88*635a8641SAndroid Build Coastguard Worker std::make_pair(3, 3), std::make_pair(4, 4),
89*635a8641SAndroid Build Coastguard Worker std::make_pair(5, 5), std::make_pair(8, 8),
90*635a8641SAndroid Build Coastguard Worker std::make_pair(10, 10)));
91*635a8641SAndroid Build Coastguard Worker }
92*635a8641SAndroid Build Coastguard Worker {
93*635a8641SAndroid Build Coastguard Worker flat_map<int, int> cont(
94*635a8641SAndroid Build Coastguard Worker {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {1, 2}, {10, 10}, {8, 8}},
95*635a8641SAndroid Build Coastguard Worker KEEP_LAST_OF_DUPES);
96*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(cont, ElementsAre(std::make_pair(1, 2), std::make_pair(2, 2),
97*635a8641SAndroid Build Coastguard Worker std::make_pair(3, 3), std::make_pair(4, 4),
98*635a8641SAndroid Build Coastguard Worker std::make_pair(5, 5), std::make_pair(8, 8),
99*635a8641SAndroid Build Coastguard Worker std::make_pair(10, 10)));
100*635a8641SAndroid Build Coastguard Worker }
101*635a8641SAndroid Build Coastguard Worker }
102*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,InitializerListAssignment)103*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, InitializerListAssignment) {
104*635a8641SAndroid Build Coastguard Worker flat_map<int, int> cont;
105*635a8641SAndroid Build Coastguard Worker cont = {{1, 1}, {2, 2}};
106*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(cont, ElementsAre(std::make_pair(1, 1), std::make_pair(2, 2)));
107*635a8641SAndroid Build Coastguard Worker }
108*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,InsertFindSize)109*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, InsertFindSize) {
110*635a8641SAndroid Build Coastguard Worker base::flat_map<int, int> s;
111*635a8641SAndroid Build Coastguard Worker s.insert(std::make_pair(1, 1));
112*635a8641SAndroid Build Coastguard Worker s.insert(std::make_pair(1, 1));
113*635a8641SAndroid Build Coastguard Worker s.insert(std::make_pair(2, 2));
114*635a8641SAndroid Build Coastguard Worker
115*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(2u, s.size());
116*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(std::make_pair(1, 1), *s.find(1));
117*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(std::make_pair(2, 2), *s.find(2));
118*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(s.end(), s.find(7));
119*635a8641SAndroid Build Coastguard Worker }
120*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,CopySwap)121*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, CopySwap) {
122*635a8641SAndroid Build Coastguard Worker base::flat_map<int, int> original;
123*635a8641SAndroid Build Coastguard Worker original.insert({1, 1});
124*635a8641SAndroid Build Coastguard Worker original.insert({2, 2});
125*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(original,
126*635a8641SAndroid Build Coastguard Worker ElementsAre(std::make_pair(1, 1), std::make_pair(2, 2)));
127*635a8641SAndroid Build Coastguard Worker
128*635a8641SAndroid Build Coastguard Worker base::flat_map<int, int> copy(original);
129*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(copy, ElementsAre(std::make_pair(1, 1), std::make_pair(2, 2)));
130*635a8641SAndroid Build Coastguard Worker
131*635a8641SAndroid Build Coastguard Worker copy.erase(copy.begin());
132*635a8641SAndroid Build Coastguard Worker copy.insert({10, 10});
133*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(copy, ElementsAre(std::make_pair(2, 2), std::make_pair(10, 10)));
134*635a8641SAndroid Build Coastguard Worker
135*635a8641SAndroid Build Coastguard Worker original.swap(copy);
136*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(original,
137*635a8641SAndroid Build Coastguard Worker ElementsAre(std::make_pair(2, 2), std::make_pair(10, 10)));
138*635a8641SAndroid Build Coastguard Worker EXPECT_THAT(copy, ElementsAre(std::make_pair(1, 1), std::make_pair(2, 2)));
139*635a8641SAndroid Build Coastguard Worker }
140*635a8641SAndroid Build Coastguard Worker
141*635a8641SAndroid Build Coastguard Worker // operator[](const Key&)
TEST(FlatMap,SubscriptConstKey)142*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, SubscriptConstKey) {
143*635a8641SAndroid Build Coastguard Worker base::flat_map<std::string, int> m;
144*635a8641SAndroid Build Coastguard Worker
145*635a8641SAndroid Build Coastguard Worker // Default construct elements that don't exist yet.
146*635a8641SAndroid Build Coastguard Worker int& s = m["a"];
147*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, s);
148*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
149*635a8641SAndroid Build Coastguard Worker
150*635a8641SAndroid Build Coastguard Worker // The returned mapped reference should refer into the map.
151*635a8641SAndroid Build Coastguard Worker s = 22;
152*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(22, m["a"]);
153*635a8641SAndroid Build Coastguard Worker
154*635a8641SAndroid Build Coastguard Worker // Overwrite existing elements.
155*635a8641SAndroid Build Coastguard Worker m["a"] = 44;
156*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(44, m["a"]);
157*635a8641SAndroid Build Coastguard Worker }
158*635a8641SAndroid Build Coastguard Worker
159*635a8641SAndroid Build Coastguard Worker // operator[](Key&&)
TEST(FlatMap,SubscriptMoveOnlyKey)160*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, SubscriptMoveOnlyKey) {
161*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, int> m;
162*635a8641SAndroid Build Coastguard Worker
163*635a8641SAndroid Build Coastguard Worker // Default construct elements that don't exist yet.
164*635a8641SAndroid Build Coastguard Worker int& s = m[MoveOnlyInt(1)];
165*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, s);
166*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
167*635a8641SAndroid Build Coastguard Worker
168*635a8641SAndroid Build Coastguard Worker // The returned mapped reference should refer into the map.
169*635a8641SAndroid Build Coastguard Worker s = 22;
170*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(22, m[MoveOnlyInt(1)]);
171*635a8641SAndroid Build Coastguard Worker
172*635a8641SAndroid Build Coastguard Worker // Overwrite existing elements.
173*635a8641SAndroid Build Coastguard Worker m[MoveOnlyInt(1)] = 44;
174*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(44, m[MoveOnlyInt(1)]);
175*635a8641SAndroid Build Coastguard Worker }
176*635a8641SAndroid Build Coastguard Worker
177*635a8641SAndroid Build Coastguard Worker // insert_or_assign(K&&, M&&)
TEST(FlatMap,InsertOrAssignMoveOnlyKey)178*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, InsertOrAssignMoveOnlyKey) {
179*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, MoveOnlyInt> m;
180*635a8641SAndroid Build Coastguard Worker
181*635a8641SAndroid Build Coastguard Worker // Initial insertion should return an iterator to the element and set the
182*635a8641SAndroid Build Coastguard Worker // second pair member to |true|. The inserted key and value should be moved
183*635a8641SAndroid Build Coastguard Worker // from.
184*635a8641SAndroid Build Coastguard Worker MoveOnlyInt key(1);
185*635a8641SAndroid Build Coastguard Worker MoveOnlyInt val(22);
186*635a8641SAndroid Build Coastguard Worker auto result = m.insert_or_assign(std::move(key), std::move(val));
187*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, result.first->first.data());
188*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(22, result.first->second.data());
189*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(result.second);
190*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
191*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, key.data()); // moved from
192*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, val.data()); // moved from
193*635a8641SAndroid Build Coastguard Worker
194*635a8641SAndroid Build Coastguard Worker // Second call with same key should result in an assignment, overwriting the
195*635a8641SAndroid Build Coastguard Worker // old value. Assignment should be indicated by setting the second pair member
196*635a8641SAndroid Build Coastguard Worker // to |false|. Only the inserted value should be moved from, the key should be
197*635a8641SAndroid Build Coastguard Worker // left intact.
198*635a8641SAndroid Build Coastguard Worker key = MoveOnlyInt(1);
199*635a8641SAndroid Build Coastguard Worker val = MoveOnlyInt(44);
200*635a8641SAndroid Build Coastguard Worker result = m.insert_or_assign(std::move(key), std::move(val));
201*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, result.first->first.data());
202*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(44, result.first->second.data());
203*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(result.second);
204*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
205*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, key.data()); // not moved from
206*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, val.data()); // moved from
207*635a8641SAndroid Build Coastguard Worker
208*635a8641SAndroid Build Coastguard Worker // Check that random insertion results in sorted range.
209*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, int> map;
210*635a8641SAndroid Build Coastguard Worker for (int i : {3, 1, 5, 6, 8, 7, 0, 9, 4, 2}) {
211*635a8641SAndroid Build Coastguard Worker map.insert_or_assign(MoveOnlyInt(i), i);
212*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(std::is_sorted(map.begin(), map.end()));
213*635a8641SAndroid Build Coastguard Worker }
214*635a8641SAndroid Build Coastguard Worker }
215*635a8641SAndroid Build Coastguard Worker
216*635a8641SAndroid Build Coastguard Worker // insert_or_assign(const_iterator hint, K&&, M&&)
TEST(FlatMap,InsertOrAssignMoveOnlyKeyWithHint)217*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, InsertOrAssignMoveOnlyKeyWithHint) {
218*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, MoveOnlyInt> m;
219*635a8641SAndroid Build Coastguard Worker
220*635a8641SAndroid Build Coastguard Worker // Initial insertion should return an iterator to the element. The inserted
221*635a8641SAndroid Build Coastguard Worker // key and value should be moved from.
222*635a8641SAndroid Build Coastguard Worker MoveOnlyInt key(1);
223*635a8641SAndroid Build Coastguard Worker MoveOnlyInt val(22);
224*635a8641SAndroid Build Coastguard Worker auto result = m.insert_or_assign(m.end(), std::move(key), std::move(val));
225*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, result->first.data());
226*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(22, result->second.data());
227*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
228*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, key.data()); // moved from
229*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, val.data()); // moved from
230*635a8641SAndroid Build Coastguard Worker
231*635a8641SAndroid Build Coastguard Worker // Second call with same key should result in an assignment, overwriting the
232*635a8641SAndroid Build Coastguard Worker // old value. Only the inserted value should be moved from, the key should be
233*635a8641SAndroid Build Coastguard Worker // left intact.
234*635a8641SAndroid Build Coastguard Worker key = MoveOnlyInt(1);
235*635a8641SAndroid Build Coastguard Worker val = MoveOnlyInt(44);
236*635a8641SAndroid Build Coastguard Worker result = m.insert_or_assign(m.end(), std::move(key), std::move(val));
237*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, result->first.data());
238*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(44, result->second.data());
239*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
240*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, key.data()); // not moved from
241*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, val.data()); // moved from
242*635a8641SAndroid Build Coastguard Worker
243*635a8641SAndroid Build Coastguard Worker // Check that random insertion results in sorted range.
244*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, int> map;
245*635a8641SAndroid Build Coastguard Worker for (int i : {3, 1, 5, 6, 8, 7, 0, 9, 4, 2}) {
246*635a8641SAndroid Build Coastguard Worker map.insert_or_assign(map.end(), MoveOnlyInt(i), i);
247*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(std::is_sorted(map.begin(), map.end()));
248*635a8641SAndroid Build Coastguard Worker }
249*635a8641SAndroid Build Coastguard Worker }
250*635a8641SAndroid Build Coastguard Worker
251*635a8641SAndroid Build Coastguard Worker // try_emplace(K&&, Args&&...)
TEST(FlatMap,TryEmplaceMoveOnlyKey)252*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, TryEmplaceMoveOnlyKey) {
253*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, std::pair<MoveOnlyInt, MoveOnlyInt>> m;
254*635a8641SAndroid Build Coastguard Worker
255*635a8641SAndroid Build Coastguard Worker // Trying to emplace into an empty map should succeed. Insertion should return
256*635a8641SAndroid Build Coastguard Worker // an iterator to the element and set the second pair member to |true|. The
257*635a8641SAndroid Build Coastguard Worker // inserted key and value should be moved from.
258*635a8641SAndroid Build Coastguard Worker MoveOnlyInt key(1);
259*635a8641SAndroid Build Coastguard Worker MoveOnlyInt val1(22);
260*635a8641SAndroid Build Coastguard Worker MoveOnlyInt val2(44);
261*635a8641SAndroid Build Coastguard Worker // Test piecewise construction of mapped_type.
262*635a8641SAndroid Build Coastguard Worker auto result = m.try_emplace(std::move(key), std::move(val1), std::move(val2));
263*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, result.first->first.data());
264*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(22, result.first->second.first.data());
265*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(44, result.first->second.second.data());
266*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(result.second);
267*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
268*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, key.data()); // moved from
269*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, val1.data()); // moved from
270*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, val2.data()); // moved from
271*635a8641SAndroid Build Coastguard Worker
272*635a8641SAndroid Build Coastguard Worker // Second call with same key should result in a no-op, returning an iterator
273*635a8641SAndroid Build Coastguard Worker // to the existing element and returning false as the second pair member.
274*635a8641SAndroid Build Coastguard Worker // Key and values that were attempted to be inserted should be left intact.
275*635a8641SAndroid Build Coastguard Worker key = MoveOnlyInt(1);
276*635a8641SAndroid Build Coastguard Worker auto paired_val = std::make_pair(MoveOnlyInt(33), MoveOnlyInt(55));
277*635a8641SAndroid Build Coastguard Worker // Test construction of mapped_type from pair.
278*635a8641SAndroid Build Coastguard Worker result = m.try_emplace(std::move(key), std::move(paired_val));
279*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, result.first->first.data());
280*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(22, result.first->second.first.data());
281*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(44, result.first->second.second.data());
282*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(result.second);
283*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
284*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, key.data()); // not moved from
285*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(33, paired_val.first.data()); // not moved from
286*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(55, paired_val.second.data()); // not moved from
287*635a8641SAndroid Build Coastguard Worker
288*635a8641SAndroid Build Coastguard Worker // Check that random insertion results in sorted range.
289*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, int> map;
290*635a8641SAndroid Build Coastguard Worker for (int i : {3, 1, 5, 6, 8, 7, 0, 9, 4, 2}) {
291*635a8641SAndroid Build Coastguard Worker map.try_emplace(MoveOnlyInt(i), i);
292*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(std::is_sorted(map.begin(), map.end()));
293*635a8641SAndroid Build Coastguard Worker }
294*635a8641SAndroid Build Coastguard Worker }
295*635a8641SAndroid Build Coastguard Worker
296*635a8641SAndroid Build Coastguard Worker // try_emplace(const_iterator hint, K&&, Args&&...)
TEST(FlatMap,TryEmplaceMoveOnlyKeyWithHint)297*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, TryEmplaceMoveOnlyKeyWithHint) {
298*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, std::pair<MoveOnlyInt, MoveOnlyInt>> m;
299*635a8641SAndroid Build Coastguard Worker
300*635a8641SAndroid Build Coastguard Worker // Trying to emplace into an empty map should succeed. Insertion should return
301*635a8641SAndroid Build Coastguard Worker // an iterator to the element. The inserted key and value should be moved
302*635a8641SAndroid Build Coastguard Worker // from.
303*635a8641SAndroid Build Coastguard Worker MoveOnlyInt key(1);
304*635a8641SAndroid Build Coastguard Worker MoveOnlyInt val1(22);
305*635a8641SAndroid Build Coastguard Worker MoveOnlyInt val2(44);
306*635a8641SAndroid Build Coastguard Worker // Test piecewise construction of mapped_type.
307*635a8641SAndroid Build Coastguard Worker auto result =
308*635a8641SAndroid Build Coastguard Worker m.try_emplace(m.end(), std::move(key), std::move(val1), std::move(val2));
309*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, result->first.data());
310*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(22, result->second.first.data());
311*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(44, result->second.second.data());
312*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
313*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, key.data()); // moved from
314*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, val1.data()); // moved from
315*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, val2.data()); // moved from
316*635a8641SAndroid Build Coastguard Worker
317*635a8641SAndroid Build Coastguard Worker // Second call with same key should result in a no-op, returning an iterator
318*635a8641SAndroid Build Coastguard Worker // to the existing element. Key and values that were attempted to be inserted
319*635a8641SAndroid Build Coastguard Worker // should be left intact.
320*635a8641SAndroid Build Coastguard Worker key = MoveOnlyInt(1);
321*635a8641SAndroid Build Coastguard Worker val1 = MoveOnlyInt(33);
322*635a8641SAndroid Build Coastguard Worker val2 = MoveOnlyInt(55);
323*635a8641SAndroid Build Coastguard Worker auto paired_val = std::make_pair(MoveOnlyInt(33), MoveOnlyInt(55));
324*635a8641SAndroid Build Coastguard Worker // Test construction of mapped_type from pair.
325*635a8641SAndroid Build Coastguard Worker result = m.try_emplace(m.end(), std::move(key), std::move(paired_val));
326*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, result->first.data());
327*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(22, result->second.first.data());
328*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(44, result->second.second.data());
329*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1u, m.size());
330*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, key.data()); // not moved from
331*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(33, paired_val.first.data()); // not moved from
332*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(55, paired_val.second.data()); // not moved from
333*635a8641SAndroid Build Coastguard Worker
334*635a8641SAndroid Build Coastguard Worker // Check that random insertion results in sorted range.
335*635a8641SAndroid Build Coastguard Worker base::flat_map<MoveOnlyInt, int> map;
336*635a8641SAndroid Build Coastguard Worker for (int i : {3, 1, 5, 6, 8, 7, 0, 9, 4, 2}) {
337*635a8641SAndroid Build Coastguard Worker map.try_emplace(map.end(), MoveOnlyInt(i), i);
338*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(std::is_sorted(map.begin(), map.end()));
339*635a8641SAndroid Build Coastguard Worker }
340*635a8641SAndroid Build Coastguard Worker }
341*635a8641SAndroid Build Coastguard Worker
TEST(FlatMap,UsingTransparentCompare)342*635a8641SAndroid Build Coastguard Worker TEST(FlatMap, UsingTransparentCompare) {
343*635a8641SAndroid Build Coastguard Worker using ExplicitInt = base::MoveOnlyInt;
344*635a8641SAndroid Build Coastguard Worker base::flat_map<ExplicitInt, int> m;
345*635a8641SAndroid Build Coastguard Worker const auto& m1 = m;
346*635a8641SAndroid Build Coastguard Worker int x = 0;
347*635a8641SAndroid Build Coastguard Worker
348*635a8641SAndroid Build Coastguard Worker // Check if we can use lookup functions without converting to key_type.
349*635a8641SAndroid Build Coastguard Worker // Correctness is checked in flat_tree tests.
350*635a8641SAndroid Build Coastguard Worker m.count(x);
351*635a8641SAndroid Build Coastguard Worker m1.count(x);
352*635a8641SAndroid Build Coastguard Worker m.find(x);
353*635a8641SAndroid Build Coastguard Worker m1.find(x);
354*635a8641SAndroid Build Coastguard Worker m.equal_range(x);
355*635a8641SAndroid Build Coastguard Worker m1.equal_range(x);
356*635a8641SAndroid Build Coastguard Worker m.lower_bound(x);
357*635a8641SAndroid Build Coastguard Worker m1.lower_bound(x);
358*635a8641SAndroid Build Coastguard Worker m.upper_bound(x);
359*635a8641SAndroid Build Coastguard Worker m1.upper_bound(x);
360*635a8641SAndroid Build Coastguard Worker m.erase(x);
361*635a8641SAndroid Build Coastguard Worker
362*635a8641SAndroid Build Coastguard Worker // Check if we broke overload resolution.
363*635a8641SAndroid Build Coastguard Worker m.emplace(ExplicitInt(0), 0);
364*635a8641SAndroid Build Coastguard Worker m.emplace(ExplicitInt(1), 0);
365*635a8641SAndroid Build Coastguard Worker m.erase(m.begin());
366*635a8641SAndroid Build Coastguard Worker m.erase(m.cbegin());
367*635a8641SAndroid Build Coastguard Worker }
368*635a8641SAndroid Build Coastguard Worker
369*635a8641SAndroid Build Coastguard Worker } // namespace base
370