xref: /aosp_15_r20/external/pigweed/pw_containers/flat_map_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker 
15*61c4878aSAndroid Build Coastguard Worker #include "pw_containers/flat_map.h"
16*61c4878aSAndroid Build Coastguard Worker 
17*61c4878aSAndroid Build Coastguard Worker #include <limits>
18*61c4878aSAndroid Build Coastguard Worker 
19*61c4878aSAndroid Build Coastguard Worker #include "pw_polyfill/language_feature_macros.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
21*61c4878aSAndroid Build Coastguard Worker 
22*61c4878aSAndroid Build Coastguard Worker namespace pw::containers {
23*61c4878aSAndroid Build Coastguard Worker namespace {
24*61c4878aSAndroid Build Coastguard Worker 
25*61c4878aSAndroid Build Coastguard Worker using Single = FlatMap<int, char, 1>;
26*61c4878aSAndroid Build Coastguard Worker 
27*61c4878aSAndroid Build Coastguard Worker constexpr FlatMap<int, char, 5> kOddMap({{
28*61c4878aSAndroid Build Coastguard Worker     {-3, 'a'},
29*61c4878aSAndroid Build Coastguard Worker     {0, 'b'},
30*61c4878aSAndroid Build Coastguard Worker     {1, 'c'},
31*61c4878aSAndroid Build Coastguard Worker     {50, 'd'},
32*61c4878aSAndroid Build Coastguard Worker     {100, 'e'},
33*61c4878aSAndroid Build Coastguard Worker }});
34*61c4878aSAndroid Build Coastguard Worker 
35*61c4878aSAndroid Build Coastguard Worker }  // namespace
36*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,PairEquality)37*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, PairEquality) {
38*61c4878aSAndroid Build Coastguard Worker   Pair<char, int> p1{'a', 1};
39*61c4878aSAndroid Build Coastguard Worker   Pair<char, int> p2{'a', 1};
40*61c4878aSAndroid Build Coastguard Worker   Pair<char, int> p3{'b', 1};
41*61c4878aSAndroid Build Coastguard Worker   Pair<char, int> p4{'a', 2};
42*61c4878aSAndroid Build Coastguard Worker 
43*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(p1, p2);
44*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(p1, p3);
45*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(p1, p4);
46*61c4878aSAndroid Build Coastguard Worker }
47*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,Size)48*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, Size) { EXPECT_EQ(kOddMap.size(), static_cast<uint32_t>(5)); }
49*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,EmptyFlatMapSize)50*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, EmptyFlatMapSize) {
51*61c4878aSAndroid Build Coastguard Worker   PW_CONSTEXPR_CPP20 FlatMap<int, char, 0> kEmpty({{}});
52*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kEmpty.size(), static_cast<uint32_t>(0));
53*61c4878aSAndroid Build Coastguard Worker }
54*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,Empty)55*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, Empty) {
56*61c4878aSAndroid Build Coastguard Worker   PW_CONSTEXPR_CPP20 FlatMap<int, char, 0> kEmpty({{}});
57*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(kEmpty.empty());
58*61c4878aSAndroid Build Coastguard Worker }
59*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,NotEmpty)60*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, NotEmpty) {
61*61c4878aSAndroid Build Coastguard Worker   PW_CONSTEXPR_CPP20 FlatMap<int, char, 1> kNotEmpty({{}});
62*61c4878aSAndroid Build Coastguard Worker   EXPECT_FALSE(kNotEmpty.empty());
63*61c4878aSAndroid Build Coastguard Worker }
64*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,EmptyFlatMapFind)65*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, EmptyFlatMapFind) {
66*61c4878aSAndroid Build Coastguard Worker   PW_CONSTEXPR_CPP20 FlatMap<int, char, 0> kEmpty({{}});
67*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kEmpty.find(0), kEmpty.end());
68*61c4878aSAndroid Build Coastguard Worker }
69*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,EmptyFlatMapLowerBound)70*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, EmptyFlatMapLowerBound) {
71*61c4878aSAndroid Build Coastguard Worker   PW_CONSTEXPR_CPP20 FlatMap<int, char, 0> kEmpty({{}});
72*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kEmpty.lower_bound(0), kEmpty.end());
73*61c4878aSAndroid Build Coastguard Worker }
74*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,EmptyFlatMapUpperBound)75*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, EmptyFlatMapUpperBound) {
76*61c4878aSAndroid Build Coastguard Worker   PW_CONSTEXPR_CPP20 FlatMap<int, char, 0> kEmpty({{}});
77*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kEmpty.upper_bound(0), kEmpty.end());
78*61c4878aSAndroid Build Coastguard Worker }
79*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,EmptyEqualRange)80*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, EmptyEqualRange) {
81*61c4878aSAndroid Build Coastguard Worker   PW_CONSTEXPR_CPP20 FlatMap<int, char, 0> kEmpty({{}});
82*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kEmpty.equal_range(0).first, kEmpty.end());
83*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kEmpty.equal_range(0).second, kEmpty.end());
84*61c4878aSAndroid Build Coastguard Worker }
85*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,ConstAtReturnsCorrectValues)86*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, ConstAtReturnsCorrectValues) {
87*61c4878aSAndroid Build Coastguard Worker   for (const auto& [key, value] : kOddMap) {
88*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(value, kOddMap.at(key));
89*61c4878aSAndroid Build Coastguard Worker   }
90*61c4878aSAndroid Build Coastguard Worker }
91*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MutableAtReturnsCorrectMutableValues)92*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MutableAtReturnsCorrectMutableValues) {
93*61c4878aSAndroid Build Coastguard Worker   FlatMap<int, char, 5> mutable_map({{
94*61c4878aSAndroid Build Coastguard Worker       {-4, 'a'},
95*61c4878aSAndroid Build Coastguard Worker       {-1, 'b'},
96*61c4878aSAndroid Build Coastguard Worker       {0, 'c'},
97*61c4878aSAndroid Build Coastguard Worker       {49, 'd'},
98*61c4878aSAndroid Build Coastguard Worker       {99, 'e'},
99*61c4878aSAndroid Build Coastguard Worker   }});
100*61c4878aSAndroid Build Coastguard Worker 
101*61c4878aSAndroid Build Coastguard Worker   for (const auto& [key, value] : mutable_map) {
102*61c4878aSAndroid Build Coastguard Worker     const char original_value{value};
103*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(original_value, mutable_map.at(key));
104*61c4878aSAndroid Build Coastguard Worker     ++mutable_map.at(key);
105*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(original_value + 1, mutable_map.at(key));
106*61c4878aSAndroid Build Coastguard Worker   }
107*61c4878aSAndroid Build Coastguard Worker }
108*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,Contains)109*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, Contains) {
110*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(kOddMap.contains(0));
111*61c4878aSAndroid Build Coastguard Worker   EXPECT_FALSE(kOddMap.contains(10));
112*61c4878aSAndroid Build Coastguard Worker }
113*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,Iterate)114*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, Iterate) {
115*61c4878aSAndroid Build Coastguard Worker   char value = 'a';
116*61c4878aSAndroid Build Coastguard Worker   for (const auto& item : kOddMap) {
117*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(value, item.second);
118*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(&item, &(*kOddMap.find(item.first)));
119*61c4878aSAndroid Build Coastguard Worker     value += 1;
120*61c4878aSAndroid Build Coastguard Worker   }
121*61c4878aSAndroid Build Coastguard Worker }
122*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,ForwardsMappedValuesIterationWithDeferenceWorks)123*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, ForwardsMappedValuesIterationWithDeferenceWorks) {
124*61c4878aSAndroid Build Coastguard Worker   FlatMap<int, char, 5> map({{
125*61c4878aSAndroid Build Coastguard Worker       {-4, 'a'},
126*61c4878aSAndroid Build Coastguard Worker       {-1, 'b'},
127*61c4878aSAndroid Build Coastguard Worker       {0, 'c'},
128*61c4878aSAndroid Build Coastguard Worker       {49, 'd'},
129*61c4878aSAndroid Build Coastguard Worker       {99, 'e'},
130*61c4878aSAndroid Build Coastguard Worker   }});
131*61c4878aSAndroid Build Coastguard Worker 
132*61c4878aSAndroid Build Coastguard Worker   char value = 'a';
133*61c4878aSAndroid Build Coastguard Worker   for (auto it = map.mapped_begin(); it != map.mapped_end(); ++it) {
134*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(value, *it);
135*61c4878aSAndroid Build Coastguard Worker     ++value;
136*61c4878aSAndroid Build Coastguard Worker   }
137*61c4878aSAndroid Build Coastguard Worker }
138*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,BackwardsMappedValuesIterationWithDereferenceWorks)139*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, BackwardsMappedValuesIterationWithDereferenceWorks) {
140*61c4878aSAndroid Build Coastguard Worker   FlatMap<int, char, 5> map({{
141*61c4878aSAndroid Build Coastguard Worker       {-4, 'a'},
142*61c4878aSAndroid Build Coastguard Worker       {-1, 'b'},
143*61c4878aSAndroid Build Coastguard Worker       {0, 'c'},
144*61c4878aSAndroid Build Coastguard Worker       {49, 'd'},
145*61c4878aSAndroid Build Coastguard Worker       {99, 'e'},
146*61c4878aSAndroid Build Coastguard Worker   }});
147*61c4878aSAndroid Build Coastguard Worker 
148*61c4878aSAndroid Build Coastguard Worker   char value = 'e';
149*61c4878aSAndroid Build Coastguard Worker   auto it = map.mapped_end();
150*61c4878aSAndroid Build Coastguard Worker   do {
151*61c4878aSAndroid Build Coastguard Worker     --it;
152*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(value, *it);
153*61c4878aSAndroid Build Coastguard Worker     --value;
154*61c4878aSAndroid Build Coastguard Worker   } while (it != map.mapped_begin());
155*61c4878aSAndroid Build Coastguard Worker }
156*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,EqualRange)157*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, EqualRange) {
158*61c4878aSAndroid Build Coastguard Worker   auto pair = kOddMap.equal_range(1);
159*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(1, pair.first->first);
160*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(50, pair.second->first);
161*61c4878aSAndroid Build Coastguard Worker 
162*61c4878aSAndroid Build Coastguard Worker   pair = kOddMap.equal_range(75);
163*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(100, pair.first->first);
164*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(100, pair.second->first);
165*61c4878aSAndroid Build Coastguard Worker }
166*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,Find)167*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, Find) {
168*61c4878aSAndroid Build Coastguard Worker   auto it = kOddMap.find(50);
169*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(50, it->first);
170*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ('d', it->second);
171*61c4878aSAndroid Build Coastguard Worker 
172*61c4878aSAndroid Build Coastguard Worker   auto not_found = kOddMap.find(-1);
173*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kOddMap.cend(), not_found);
174*61c4878aSAndroid Build Coastguard Worker }
175*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,UpperBoundLessThanSmallestKey)176*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, UpperBoundLessThanSmallestKey) {
177*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(-3, kOddMap.upper_bound(std::numeric_limits<int>::min())->first);
178*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(-3, kOddMap.upper_bound(-123)->first);
179*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(-3, kOddMap.upper_bound(-4)->first);
180*61c4878aSAndroid Build Coastguard Worker }
181*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,UpperBoundBetweenTheTwoSmallestKeys)182*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, UpperBoundBetweenTheTwoSmallestKeys) {
183*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(0, kOddMap.upper_bound(-3)->first);
184*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(0, kOddMap.upper_bound(-2)->first);
185*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(0, kOddMap.upper_bound(-1)->first);
186*61c4878aSAndroid Build Coastguard Worker }
187*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,UpperBoundIntermediateKeys)188*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, UpperBoundIntermediateKeys) {
189*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(1, kOddMap.upper_bound(0)->first);
190*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ('c', kOddMap.upper_bound(0)->second);
191*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(50, kOddMap.upper_bound(1)->first);
192*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ('d', kOddMap.upper_bound(1)->second);
193*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(50, kOddMap.upper_bound(2)->first);
194*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(50, kOddMap.upper_bound(49)->first);
195*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(100, kOddMap.upper_bound(51)->first);
196*61c4878aSAndroid Build Coastguard Worker }
197*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,UpperBoundGreaterThanLargestKey)198*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, UpperBoundGreaterThanLargestKey) {
199*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kOddMap.end(), kOddMap.upper_bound(100));
200*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kOddMap.end(), kOddMap.upper_bound(2384924));
201*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kOddMap.end(),
202*61c4878aSAndroid Build Coastguard Worker             kOddMap.upper_bound(std::numeric_limits<int>::max()));
203*61c4878aSAndroid Build Coastguard Worker }
204*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,LowerBoundLessThanSmallestKey)205*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, LowerBoundLessThanSmallestKey) {
206*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(-3, kOddMap.lower_bound(std::numeric_limits<int>::min())->first);
207*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(-3, kOddMap.lower_bound(-123)->first);
208*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(-3, kOddMap.lower_bound(-4)->first);
209*61c4878aSAndroid Build Coastguard Worker }
210*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,LowerBoundBetweenTwoSmallestKeys)211*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, LowerBoundBetweenTwoSmallestKeys) {
212*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(-3, kOddMap.lower_bound(-3)->first);
213*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(0, kOddMap.lower_bound(-2)->first);
214*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(0, kOddMap.lower_bound(-1)->first);
215*61c4878aSAndroid Build Coastguard Worker }
216*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,LowerBoundIntermediateKeys)217*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, LowerBoundIntermediateKeys) {
218*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(0, kOddMap.lower_bound(0)->first);
219*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ('b', kOddMap.lower_bound(0)->second);
220*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(1, kOddMap.lower_bound(1)->first);
221*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ('c', kOddMap.lower_bound(1)->second);
222*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(50, kOddMap.lower_bound(2)->first);
223*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(50, kOddMap.lower_bound(49)->first);
224*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(100, kOddMap.lower_bound(51)->first);
225*61c4878aSAndroid Build Coastguard Worker }
226*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,LowerBoundGreaterThanLargestKey)227*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, LowerBoundGreaterThanLargestKey) {
228*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(100, kOddMap.lower_bound(100)->first);
229*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kOddMap.end(), kOddMap.lower_bound(2384924));
230*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kOddMap.end(),
231*61c4878aSAndroid Build Coastguard Worker             kOddMap.lower_bound(std::numeric_limits<int>::max()));
232*61c4878aSAndroid Build Coastguard Worker }
233*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,ForEachIteration)234*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, ForEachIteration) {
235*61c4878aSAndroid Build Coastguard Worker   for (const auto& item : kOddMap) {
236*61c4878aSAndroid Build Coastguard Worker     EXPECT_NE(item.first, 2);
237*61c4878aSAndroid Build Coastguard Worker   }
238*61c4878aSAndroid Build Coastguard Worker }
239*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MapsWithUnsortedKeys)240*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MapsWithUnsortedKeys) {
241*61c4878aSAndroid Build Coastguard Worker   constexpr FlatMap<int, const char*, 2> bad_array({{
242*61c4878aSAndroid Build Coastguard Worker       {2, "hello"},
243*61c4878aSAndroid Build Coastguard Worker       {1, "goodbye"},
244*61c4878aSAndroid Build Coastguard Worker   }});
245*61c4878aSAndroid Build Coastguard Worker 
246*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(bad_array.begin()->first, 1);
247*61c4878aSAndroid Build Coastguard Worker 
248*61c4878aSAndroid Build Coastguard Worker   constexpr FlatMap<int, const char*, 2> too_short({{
249*61c4878aSAndroid Build Coastguard Worker       {1, "goodbye"},
250*61c4878aSAndroid Build Coastguard Worker   }});
251*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(too_short.begin()->first, 0);
252*61c4878aSAndroid Build Coastguard Worker }
253*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,DontDereferenceEnd)254*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, DontDereferenceEnd) {
255*61c4878aSAndroid Build Coastguard Worker   constexpr FlatMap<int, const char*, 2> unsorted_array({{
256*61c4878aSAndroid Build Coastguard Worker       {2, "hello"},
257*61c4878aSAndroid Build Coastguard Worker       {1, "goodbye"},
258*61c4878aSAndroid Build Coastguard Worker   }});
259*61c4878aSAndroid Build Coastguard Worker 
260*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(unsorted_array.contains(3), false);
261*61c4878aSAndroid Build Coastguard Worker }
262*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,NullMappedIteratorNotEqualToValidOne)263*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, NullMappedIteratorNotEqualToValidOne) {
264*61c4878aSAndroid Build Coastguard Worker   Single map({{{-4, 'a'}}});
265*61c4878aSAndroid Build Coastguard Worker 
266*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(Single::mapped_iterator(), map.mapped_begin());
267*61c4878aSAndroid Build Coastguard Worker }
268*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,CopyConstructedMapIteratorEqualToSource)269*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, CopyConstructedMapIteratorEqualToSource) {
270*61c4878aSAndroid Build Coastguard Worker   Single map({{{-4, 'a'}}});
271*61c4878aSAndroid Build Coastguard Worker 
272*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(Single::mapped_iterator(map.mapped_begin()), map.mapped_begin());
273*61c4878aSAndroid Build Coastguard Worker }
274*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,CopyAssignedMapIteratorEqualToSource)275*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, CopyAssignedMapIteratorEqualToSource) {
276*61c4878aSAndroid Build Coastguard Worker   Single map({{{-4, 'a'}}});
277*61c4878aSAndroid Build Coastguard Worker 
278*61c4878aSAndroid Build Coastguard Worker   Single::mapped_iterator it;
279*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(it, map.mapped_begin());
280*61c4878aSAndroid Build Coastguard Worker   it = map.mapped_begin();
281*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(it, map.mapped_begin());
282*61c4878aSAndroid Build Coastguard Worker }
283*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MappedIteratorCorrectDereferenceMutation)284*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MappedIteratorCorrectDereferenceMutation) {
285*61c4878aSAndroid Build Coastguard Worker   constexpr int kKey = -4;
286*61c4878aSAndroid Build Coastguard Worker   constexpr char kValue = 'a';
287*61c4878aSAndroid Build Coastguard Worker   Single mutable_map({{{kKey, kValue}}});
288*61c4878aSAndroid Build Coastguard Worker 
289*61c4878aSAndroid Build Coastguard Worker   ++*mutable_map.mapped_begin();
290*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kValue + 1, mutable_map.at(kKey));
291*61c4878aSAndroid Build Coastguard Worker }
292*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MappedIteratorValueCorrectMemberAccess)293*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MappedIteratorValueCorrectMemberAccess) {
294*61c4878aSAndroid Build Coastguard Worker   constexpr int kAValue{5};
295*61c4878aSAndroid Build Coastguard Worker   struct A {
296*61c4878aSAndroid Build Coastguard Worker     int a;
297*61c4878aSAndroid Build Coastguard Worker   };
298*61c4878aSAndroid Build Coastguard Worker   FlatMap<int, A, 1> map({{{-4, A{kAValue}}}});
299*61c4878aSAndroid Build Coastguard Worker 
300*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kAValue, map.mapped_begin()->a);
301*61c4878aSAndroid Build Coastguard Worker }
302*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MappedIteratorValueCorrectMemberMutation)303*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MappedIteratorValueCorrectMemberMutation) {
304*61c4878aSAndroid Build Coastguard Worker   constexpr int kAValue{5};
305*61c4878aSAndroid Build Coastguard Worker   struct A {
306*61c4878aSAndroid Build Coastguard Worker     int a;
307*61c4878aSAndroid Build Coastguard Worker   };
308*61c4878aSAndroid Build Coastguard Worker   FlatMap<int, A, 1> map({{{-4, A{kAValue}}}});
309*61c4878aSAndroid Build Coastguard Worker 
310*61c4878aSAndroid Build Coastguard Worker   ++map.mapped_begin()->a;
311*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kAValue + 1, map.mapped_begin()->a);
312*61c4878aSAndroid Build Coastguard Worker }
313*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MappedIteratorPrefixIncrementCorrectReturnAndSideEffect)314*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MappedIteratorPrefixIncrementCorrectReturnAndSideEffect) {
315*61c4878aSAndroid Build Coastguard Worker   Single map({{{-4, 'a'}}});
316*61c4878aSAndroid Build Coastguard Worker 
317*61c4878aSAndroid Build Coastguard Worker   auto it = map.mapped_begin();
318*61c4878aSAndroid Build Coastguard Worker   auto it_incremented = ++it;
319*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(it, it_incremented);
320*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(map.mapped_begin(), it_incremented);
321*61c4878aSAndroid Build Coastguard Worker }
322*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MappedIteratorPostfixIncrementCorrectReturnAndSideEffect)323*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MappedIteratorPostfixIncrementCorrectReturnAndSideEffect) {
324*61c4878aSAndroid Build Coastguard Worker   Single map({{{-4, 'a'}}});
325*61c4878aSAndroid Build Coastguard Worker 
326*61c4878aSAndroid Build Coastguard Worker   auto it = map.mapped_begin();
327*61c4878aSAndroid Build Coastguard Worker   auto it_original = it++;
328*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(map.mapped_begin(), it_original);
329*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(it, it_original);
330*61c4878aSAndroid Build Coastguard Worker }
331*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MappedIteratorPrefixDecrementCorrectReturnAndSideEffect)332*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MappedIteratorPrefixDecrementCorrectReturnAndSideEffect) {
333*61c4878aSAndroid Build Coastguard Worker   Single map({{{-4, 'a'}}});
334*61c4878aSAndroid Build Coastguard Worker 
335*61c4878aSAndroid Build Coastguard Worker   auto it = map.mapped_end();
336*61c4878aSAndroid Build Coastguard Worker   auto it_decremented = --it;
337*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(it, it_decremented);
338*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(map.mapped_end(), it_decremented);
339*61c4878aSAndroid Build Coastguard Worker }
340*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,MappedIteratorPostfixDecrementCorrectReturnAndSideEffect)341*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, MappedIteratorPostfixDecrementCorrectReturnAndSideEffect) {
342*61c4878aSAndroid Build Coastguard Worker   Single map({{{-4, 'a'}}});
343*61c4878aSAndroid Build Coastguard Worker 
344*61c4878aSAndroid Build Coastguard Worker   auto it = map.mapped_end();
345*61c4878aSAndroid Build Coastguard Worker   auto it_original = it--;
346*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(map.mapped_end(), it_original);
347*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(it, it_original);
348*61c4878aSAndroid Build Coastguard Worker }
349*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,PairsConstructionWithOneElement)350*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, PairsConstructionWithOneElement) {
351*61c4878aSAndroid Build Coastguard Worker   constexpr FlatMap kMap(Pair<int, char>{1, 'a'});
352*61c4878aSAndroid Build Coastguard Worker 
353*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(kMap.size(), 1u);
354*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(kMap.find(1), kMap.cend());
355*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(kMap.at(1), 'a');
356*61c4878aSAndroid Build Coastguard Worker }
357*61c4878aSAndroid Build Coastguard Worker 
TEST(FlatMap,PairsConstructionWithMoreThanOneElements)358*61c4878aSAndroid Build Coastguard Worker TEST(FlatMap, PairsConstructionWithMoreThanOneElements) {
359*61c4878aSAndroid Build Coastguard Worker   using FlatMapItem = Pair<int, char>;
360*61c4878aSAndroid Build Coastguard Worker   constexpr FlatMap kMap = {
361*61c4878aSAndroid Build Coastguard Worker       FlatMapItem{-4, 'a'},
362*61c4878aSAndroid Build Coastguard Worker       FlatMapItem{-1, 'b'},
363*61c4878aSAndroid Build Coastguard Worker       FlatMapItem{0, 'c'},
364*61c4878aSAndroid Build Coastguard Worker       FlatMapItem{49, 'd'},
365*61c4878aSAndroid Build Coastguard Worker       FlatMapItem{99, 'e'},
366*61c4878aSAndroid Build Coastguard Worker   };
367*61c4878aSAndroid Build Coastguard Worker 
368*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(kMap.size(), 5u);
369*61c4878aSAndroid Build Coastguard Worker   for (const auto& [key, value] : kMap) {
370*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(kMap.at(key), value);
371*61c4878aSAndroid Build Coastguard Worker   }
372*61c4878aSAndroid Build Coastguard Worker }
373*61c4878aSAndroid Build Coastguard Worker 
374*61c4878aSAndroid Build Coastguard Worker }  // namespace pw::containers
375