xref: /aosp_15_r20/external/pigweed/pw_containers/intrusive_multimap_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2024 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/intrusive_multimap.h"
16*61c4878aSAndroid Build Coastguard Worker 
17*61c4878aSAndroid Build Coastguard Worker #include "pw_compilation_testing/negative_compilation.h"
18*61c4878aSAndroid Build Coastguard Worker #include "pw_containers/intrusive_map.h"
19*61c4878aSAndroid Build Coastguard Worker #include "pw_span/span.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
21*61c4878aSAndroid Build Coastguard Worker 
22*61c4878aSAndroid Build Coastguard Worker namespace {
23*61c4878aSAndroid Build Coastguard Worker 
24*61c4878aSAndroid Build Coastguard Worker // Base pair.
25*61c4878aSAndroid Build Coastguard Worker class BaseItem {
26*61c4878aSAndroid Build Coastguard Worker  public:
BaseItem(const char * name)27*61c4878aSAndroid Build Coastguard Worker   explicit BaseItem(const char* name) : name_(name) {}
28*61c4878aSAndroid Build Coastguard Worker 
name() const29*61c4878aSAndroid Build Coastguard Worker   constexpr const char* name() const { return name_; }
set_name(const char * name)30*61c4878aSAndroid Build Coastguard Worker   void set_name(const char* name) { name_ = name; }
31*61c4878aSAndroid Build Coastguard Worker 
32*61c4878aSAndroid Build Coastguard Worker  private:
33*61c4878aSAndroid Build Coastguard Worker   const char* name_;
34*61c4878aSAndroid Build Coastguard Worker };
35*61c4878aSAndroid Build Coastguard Worker 
36*61c4878aSAndroid Build Coastguard Worker // A basic pair that can be used in a map.
37*61c4878aSAndroid Build Coastguard Worker class TestPair : public ::pw::IntrusiveMultiMap<size_t, TestPair>::Pair,
38*61c4878aSAndroid Build Coastguard Worker                  public BaseItem {
39*61c4878aSAndroid Build Coastguard Worker  private:
40*61c4878aSAndroid Build Coastguard Worker   using Pair = ::pw::IntrusiveMultiMap<size_t, TestPair>::Pair;
41*61c4878aSAndroid Build Coastguard Worker 
42*61c4878aSAndroid Build Coastguard Worker  public:
TestPair(size_t key,const char * name)43*61c4878aSAndroid Build Coastguard Worker   TestPair(size_t key, const char* name) : Pair(key), BaseItem(name) {}
44*61c4878aSAndroid Build Coastguard Worker };
45*61c4878aSAndroid Build Coastguard Worker 
46*61c4878aSAndroid Build Coastguard Worker // Test fixture.
47*61c4878aSAndroid Build Coastguard Worker class IntrusiveMultiMapTest : public ::testing::Test {
48*61c4878aSAndroid Build Coastguard Worker  protected:
49*61c4878aSAndroid Build Coastguard Worker   using IntrusiveMultiMap = ::pw::IntrusiveMultiMap<size_t, TestPair>;
50*61c4878aSAndroid Build Coastguard Worker   static constexpr size_t kNumPairs = 10;
51*61c4878aSAndroid Build Coastguard Worker 
SetUp()52*61c4878aSAndroid Build Coastguard Worker   void SetUp() override { multimap_.insert(pairs_.begin(), pairs_.end()); }
53*61c4878aSAndroid Build Coastguard Worker 
TearDown()54*61c4878aSAndroid Build Coastguard Worker   void TearDown() override { multimap_.clear(); }
55*61c4878aSAndroid Build Coastguard Worker 
56*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair, kNumPairs> pairs_ = {{
57*61c4878aSAndroid Build Coastguard Worker       {30, "a"},
58*61c4878aSAndroid Build Coastguard Worker       {50, "b"},
59*61c4878aSAndroid Build Coastguard Worker       {20, "c"},
60*61c4878aSAndroid Build Coastguard Worker       {40, "d"},
61*61c4878aSAndroid Build Coastguard Worker       {10, "e"},
62*61c4878aSAndroid Build Coastguard Worker       {30, "A"},
63*61c4878aSAndroid Build Coastguard Worker       {50, "B"},
64*61c4878aSAndroid Build Coastguard Worker       {20, "C"},
65*61c4878aSAndroid Build Coastguard Worker       {40, "D"},
66*61c4878aSAndroid Build Coastguard Worker       {10, "E"},
67*61c4878aSAndroid Build Coastguard Worker   }};
68*61c4878aSAndroid Build Coastguard Worker 
69*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap_;
70*61c4878aSAndroid Build Coastguard Worker };
71*61c4878aSAndroid Build Coastguard Worker 
72*61c4878aSAndroid Build Coastguard Worker // Unit tests.
73*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_Default)74*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_Default) {
75*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap;
76*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(multimap.empty());
77*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.begin(), multimap.end());
78*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.rbegin(), multimap.rend());
79*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), 0U);
80*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.lower_bound(0), multimap.end());
81*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.upper_bound(0), multimap.end());
82*61c4878aSAndroid Build Coastguard Worker }
83*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_ObjectIterators)84*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_ObjectIterators) {
85*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
86*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap(pairs_.begin(), pairs_.end());
87*61c4878aSAndroid Build Coastguard Worker   EXPECT_FALSE(multimap.empty());
88*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), pairs_.size());
89*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
90*61c4878aSAndroid Build Coastguard Worker }
91*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_ObjectIterators_Empty)92*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_ObjectIterators_Empty) {
93*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap(pairs_.end(), pairs_.end());
94*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(multimap.empty());
95*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), 0U);
96*61c4878aSAndroid Build Coastguard Worker }
97*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_PointerIterators)98*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_PointerIterators) {
99*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair*, 3> ptrs = {&pairs_[0], &pairs_[1], &pairs_[2]};
100*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
101*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap(ptrs.begin(), ptrs.end());
102*61c4878aSAndroid Build Coastguard Worker   EXPECT_FALSE(multimap.empty());
103*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), 3U);
104*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
105*61c4878aSAndroid Build Coastguard Worker }
106*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_PointerIterators_Empty)107*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_PointerIterators_Empty) {
108*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair*, 0> ptrs;
109*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap(ptrs.begin(), ptrs.end());
110*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(multimap.empty());
111*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), 0U);
112*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
113*61c4878aSAndroid Build Coastguard Worker }
114*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_InitializerList)115*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_InitializerList) {
116*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
117*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap({&pairs_[0], &pairs_[2], &pairs_[4]});
118*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.begin();
119*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ((iter++)->key(), 10U);
120*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ((iter++)->key(), 20U);
121*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ((iter++)->key(), 30U);
122*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.end());
123*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
124*61c4878aSAndroid Build Coastguard Worker }
125*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_InitializerList_Empty)126*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_InitializerList_Empty) {
127*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap({});
128*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(multimap.empty());
129*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), 0U);
130*61c4878aSAndroid Build Coastguard Worker }
131*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_CustomCompare)132*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_CustomCompare) {
133*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
134*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap({&pairs_[0], &pairs_[2], &pairs_[4]},
135*61c4878aSAndroid Build Coastguard Worker                              std::greater<>());
136*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.begin();
137*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ((iter++)->key(), 30U);
138*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ((iter++)->key(), 20U);
139*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ((iter++)->key(), 10U);
140*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.end());
141*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
142*61c4878aSAndroid Build Coastguard Worker }
143*61c4878aSAndroid Build Coastguard Worker 
144*61c4878aSAndroid Build Coastguard Worker // A map pair that includes a key accessor method.
145*61c4878aSAndroid Build Coastguard Worker struct HalvedKey : public ::pw::IntrusiveMultiMap<size_t, HalvedKey>::Item,
146*61c4878aSAndroid Build Coastguard Worker                    public BaseItem {
147*61c4878aSAndroid Build Coastguard Worker  private:
148*61c4878aSAndroid Build Coastguard Worker   using MapItem = ::pw::IntrusiveMultiMap<size_t, HalvedKey>::Item;
149*61c4878aSAndroid Build Coastguard Worker 
150*61c4878aSAndroid Build Coastguard Worker  public:
HalvedKey__anond08d356a0111::HalvedKey151*61c4878aSAndroid Build Coastguard Worker   HalvedKey(size_t half_key, const char* name)
152*61c4878aSAndroid Build Coastguard Worker       : BaseItem(name), half_key_(half_key) {}
key__anond08d356a0111::HalvedKey153*61c4878aSAndroid Build Coastguard Worker   size_t key() const { return half_key_ * 2; }
154*61c4878aSAndroid Build Coastguard Worker 
155*61c4878aSAndroid Build Coastguard Worker  private:
156*61c4878aSAndroid Build Coastguard Worker   const size_t half_key_;
157*61c4878aSAndroid Build Coastguard Worker };
158*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_CustomItem)159*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_CustomItem) {
160*61c4878aSAndroid Build Coastguard Worker   std::array<HalvedKey, 3> items = {{
161*61c4878aSAndroid Build Coastguard Worker       {50, "B"},
162*61c4878aSAndroid Build Coastguard Worker       {40, "D"},
163*61c4878aSAndroid Build Coastguard Worker       {60, "F"},
164*61c4878aSAndroid Build Coastguard Worker   }};
165*61c4878aSAndroid Build Coastguard Worker   pw::IntrusiveMultiMap<size_t, HalvedKey> multimap(items.begin(), items.end());
166*61c4878aSAndroid Build Coastguard Worker 
167*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.find(80);
168*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
169*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "D");
170*61c4878aSAndroid Build Coastguard Worker 
171*61c4878aSAndroid Build Coastguard Worker   iter = multimap.find(100);
172*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
173*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "B");
174*61c4878aSAndroid Build Coastguard Worker 
175*61c4878aSAndroid Build Coastguard Worker   iter = multimap.find(120);
176*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
177*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "F");
178*61c4878aSAndroid Build Coastguard Worker 
179*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
180*61c4878aSAndroid Build Coastguard Worker }
181*61c4878aSAndroid Build Coastguard Worker 
182*61c4878aSAndroid Build Coastguard Worker // A map item that has no explicit key.
183*61c4878aSAndroid Build Coastguard Worker struct NoKey : public ::pw::IntrusiveMultiMap<size_t, NoKey>::Item,
184*61c4878aSAndroid Build Coastguard Worker                public BaseItem {
185*61c4878aSAndroid Build Coastguard Worker  public:
NoKey__anond08d356a0111::NoKey186*61c4878aSAndroid Build Coastguard Worker   explicit NoKey(const char* name) : BaseItem(name) {}
187*61c4878aSAndroid Build Coastguard Worker };
188*61c4878aSAndroid Build Coastguard Worker 
189*61c4878aSAndroid Build Coastguard Worker // A functor to get an implied key from a `NoKey` item.
190*61c4878aSAndroid Build Coastguard Worker struct GetImpliedKey {
operator ()__anond08d356a0111::GetImpliedKey191*61c4878aSAndroid Build Coastguard Worker   size_t operator()(const NoKey& item) const {
192*61c4878aSAndroid Build Coastguard Worker     return std::strlen(item.name());
193*61c4878aSAndroid Build Coastguard Worker   }
194*61c4878aSAndroid Build Coastguard Worker };
195*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Construct_CustomGetKey)196*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Construct_CustomGetKey) {
197*61c4878aSAndroid Build Coastguard Worker   std::array<NoKey, 5> items = {
198*61c4878aSAndroid Build Coastguard Worker       NoKey("CC"),
199*61c4878aSAndroid Build Coastguard Worker       NoKey("AAA"),
200*61c4878aSAndroid Build Coastguard Worker       NoKey("AAA"),
201*61c4878aSAndroid Build Coastguard Worker       NoKey("B"),
202*61c4878aSAndroid Build Coastguard Worker       NoKey("DDDD"),
203*61c4878aSAndroid Build Coastguard Worker   };
204*61c4878aSAndroid Build Coastguard Worker   pw::IntrusiveMultiMap<size_t, NoKey> multimap(
205*61c4878aSAndroid Build Coastguard Worker       items.begin(), items.end(), std::less<>(), GetImpliedKey());
206*61c4878aSAndroid Build Coastguard Worker 
207*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.begin();
208*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "B");
209*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "CC");
210*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "AAA");
211*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "AAA");
212*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "DDDD");
213*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
214*61c4878aSAndroid Build Coastguard Worker }
215*61c4878aSAndroid Build Coastguard Worker 
216*61c4878aSAndroid Build Coastguard Worker //  A struct that is not a multimap pair.
217*61c4878aSAndroid Build Coastguard Worker class NotAnItem : public BaseItem {
218*61c4878aSAndroid Build Coastguard Worker  public:
NotAnItem(const char * name,size_t key)219*61c4878aSAndroid Build Coastguard Worker   NotAnItem(const char* name, size_t key) : BaseItem(name), key_(key) {}
key() const220*61c4878aSAndroid Build Coastguard Worker   size_t key() const { return key_; }
221*61c4878aSAndroid Build Coastguard Worker 
222*61c4878aSAndroid Build Coastguard Worker  private:
223*61c4878aSAndroid Build Coastguard Worker   const size_t key_;
224*61c4878aSAndroid Build Coastguard Worker };
225*61c4878aSAndroid Build Coastguard Worker 
226*61c4878aSAndroid Build Coastguard Worker #if PW_NC_TEST(IncompatibleItem)
227*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT(
228*61c4878aSAndroid Build Coastguard Worker     "IntrusiveMultiMap items must be derived from IntrusiveMultiMap<Key, "
229*61c4878aSAndroid Build Coastguard Worker     "T>::Item");
230*61c4878aSAndroid Build Coastguard Worker 
231*61c4878aSAndroid Build Coastguard Worker struct BadItem : public ::pw::IntrusiveMultiMap<size_t, NotAnItem>::Item {
BadItem__anond08d356a0111::BadItem232*61c4878aSAndroid Build Coastguard Worker   constexpr explicit BadItem(size_t key) : key_(key) {}
key__anond08d356a0111::BadItem233*61c4878aSAndroid Build Coastguard Worker   constexpr size_t key() const { return key_; }
operator <__anond08d356a0111::BadItem234*61c4878aSAndroid Build Coastguard Worker   constexpr bool operator<(const Pair& rhs) { return key_ < rhs.key(); }
235*61c4878aSAndroid Build Coastguard Worker 
236*61c4878aSAndroid Build Coastguard Worker  private:
237*61c4878aSAndroid Build Coastguard Worker   const size_t key_;
238*61c4878aSAndroid Build Coastguard Worker };
239*61c4878aSAndroid Build Coastguard Worker 
240*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] ::pw::IntrusiveMultiMap<size_t, BadItem> bad_multimap1;
241*61c4878aSAndroid Build Coastguard Worker 
242*61c4878aSAndroid Build Coastguard Worker #elif PW_NC_TEST(DoesNotInheritFromItem)
243*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT(
244*61c4878aSAndroid Build Coastguard Worker     "IntrusiveMultiMap items must be derived from IntrusiveMultiMap<Key, "
245*61c4878aSAndroid Build Coastguard Worker     "T>::Item");
246*61c4878aSAndroid Build Coastguard Worker 
247*61c4878aSAndroid Build Coastguard Worker [[maybe_unused]] ::pw::IntrusiveMultiMap<size_t, NotAnItem> bad_multimap2;
248*61c4878aSAndroid Build Coastguard Worker 
249*61c4878aSAndroid Build Coastguard Worker #endif  // PW_NC_TEST
250*61c4878aSAndroid Build Coastguard Worker 
251*61c4878aSAndroid Build Coastguard Worker // Iterators
252*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Iterator)253*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Iterator) {
254*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
255*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.begin();
256*61c4878aSAndroid Build Coastguard Worker   size_t key = 10;
257*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumPairs; i += 2) {
258*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ((*iter++).key(), key);
259*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ((*iter++).key(), key);
260*61c4878aSAndroid Build Coastguard Worker     key += 10;
261*61c4878aSAndroid Build Coastguard Worker   }
262*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(key, 60U);
263*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.end());
264*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.cend());
265*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumPairs; i += 2) {
266*61c4878aSAndroid Build Coastguard Worker     key -= 10;
267*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ((--iter)->key(), key);
268*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ((--iter)->key(), key);
269*61c4878aSAndroid Build Coastguard Worker   }
270*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(key, 10U);
271*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.begin());
272*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.cbegin());
273*61c4878aSAndroid Build Coastguard Worker }
274*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,ReverseIterator)275*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, ReverseIterator) {
276*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
277*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.rbegin();
278*61c4878aSAndroid Build Coastguard Worker   size_t key = 50;
279*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumPairs; i += 2) {
280*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ((*iter++).key(), key);
281*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ((*iter++).key(), key);
282*61c4878aSAndroid Build Coastguard Worker     key -= 10;
283*61c4878aSAndroid Build Coastguard Worker   }
284*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(key, 0U);
285*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.rend());
286*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.crend());
287*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumPairs; i += 2) {
288*61c4878aSAndroid Build Coastguard Worker     key += 10;
289*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ((--iter)->key(), key);
290*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ((--iter)->key(), key);
291*61c4878aSAndroid Build Coastguard Worker   }
292*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(key, 50U);
293*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.rbegin());
294*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.crbegin());
295*61c4878aSAndroid Build Coastguard Worker }
296*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,ConstIterator_CompareNonConst)297*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, ConstIterator_CompareNonConst) {
298*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.end(), multimap_.cend());
299*61c4878aSAndroid Build Coastguard Worker }
300*61c4878aSAndroid Build Coastguard Worker 
301*61c4878aSAndroid Build Coastguard Worker // A multimap pair that is distinct from TestPair
302*61c4878aSAndroid Build Coastguard Worker class OtherPair : public ::pw::IntrusiveMultiMap<size_t, OtherPair>::Pair,
303*61c4878aSAndroid Build Coastguard Worker                   public BaseItem {
304*61c4878aSAndroid Build Coastguard Worker  private:
305*61c4878aSAndroid Build Coastguard Worker   using Pair = ::pw::IntrusiveMultiMap<size_t, OtherPair>::Pair;
306*61c4878aSAndroid Build Coastguard Worker 
307*61c4878aSAndroid Build Coastguard Worker  public:
OtherPair(size_t key,const char * name)308*61c4878aSAndroid Build Coastguard Worker   OtherPair(size_t key, const char* name) : Pair(key), BaseItem(name) {}
309*61c4878aSAndroid Build Coastguard Worker };
310*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,ConstIterator_CompareNonConst_CompilationFails)311*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, ConstIterator_CompareNonConst_CompilationFails) {
312*61c4878aSAndroid Build Coastguard Worker   ::pw::IntrusiveMultiMap<size_t, OtherPair> multimap;
313*61c4878aSAndroid Build Coastguard Worker #if PW_NC_TEST(CannotCompareIncompatibleIteratorsEqual)
314*61c4878aSAndroid Build Coastguard Worker   PW_NC_EXPECT("multimap_\.end\(\) == multimap\.end\(\)");
315*61c4878aSAndroid Build Coastguard Worker   static_cast<void>(multimap_.end() == multimap.end());
316*61c4878aSAndroid Build Coastguard Worker #elif PW_NC_TEST(CannotCompareIncompatibleIteratorsInequal)
317*61c4878aSAndroid Build Coastguard Worker   PW_NC_EXPECT("multimap_\.end\(\) != multimap\.end\(\)");
318*61c4878aSAndroid Build Coastguard Worker   static_cast<void>(multimap_.end() != multimap.end());
319*61c4878aSAndroid Build Coastguard Worker #endif  // PW_NC_TEST
320*61c4878aSAndroid Build Coastguard Worker }
321*61c4878aSAndroid Build Coastguard Worker 
322*61c4878aSAndroid Build Coastguard Worker #if PW_NC_TEST(CannotModifyThroughConstIterator)
323*61c4878aSAndroid Build Coastguard Worker PW_NC_EXPECT("function is not marked const|discards qualifiers");
324*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,ConstIterator_Modify)325*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, ConstIterator_Modify) {
326*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
327*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.begin();
328*61c4878aSAndroid Build Coastguard Worker   iter->set_name("nope");
329*61c4878aSAndroid Build Coastguard Worker }
330*61c4878aSAndroid Build Coastguard Worker 
331*61c4878aSAndroid Build Coastguard Worker #endif  // PW_NC_TEST
332*61c4878aSAndroid Build Coastguard Worker 
333*61c4878aSAndroid Build Coastguard Worker // Capacity
334*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,IsEmpty)335*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, IsEmpty) {
336*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
337*61c4878aSAndroid Build Coastguard Worker   EXPECT_FALSE(multimap.empty());
338*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
339*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(multimap.empty());
340*61c4878aSAndroid Build Coastguard Worker }
341*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,GetSize)342*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, GetSize) {
343*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
344*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), kNumPairs);
345*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
346*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), 0U);
347*61c4878aSAndroid Build Coastguard Worker }
348*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,GetMaxSize)349*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, GetMaxSize) {
350*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
351*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.max_size(), size_t(std::numeric_limits<ptrdiff_t>::max()));
352*61c4878aSAndroid Build Coastguard Worker }
353*61c4878aSAndroid Build Coastguard Worker 
354*61c4878aSAndroid Build Coastguard Worker // Modifiers
355*61c4878aSAndroid Build Coastguard Worker 
356*61c4878aSAndroid Build Coastguard Worker // This functions allows tests to use `std::is_sorted` without specializing
357*61c4878aSAndroid Build Coastguard Worker // `std::less<TestPair>`. Since `std::less` is the default value for the
358*61c4878aSAndroid Build Coastguard Worker // `Compare` template parameter, leaving it untouched avoids accidentally
359*61c4878aSAndroid Build Coastguard Worker // masking type-handling errors.
LessThan(const TestPair & lhs,const TestPair & rhs)360*61c4878aSAndroid Build Coastguard Worker constexpr bool LessThan(const TestPair& lhs, const TestPair& rhs) {
361*61c4878aSAndroid Build Coastguard Worker   return lhs.key() < rhs.key();
362*61c4878aSAndroid Build Coastguard Worker }
363*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert)364*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert) {
365*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
366*61c4878aSAndroid Build Coastguard Worker   bool sorted = true;
367*61c4878aSAndroid Build Coastguard Worker   size_t prev_key = 0;
368*61c4878aSAndroid Build Coastguard Worker   for (auto& pair : pairs_) {
369*61c4878aSAndroid Build Coastguard Worker     sorted &= prev_key < pair.key();
370*61c4878aSAndroid Build Coastguard Worker 
371*61c4878aSAndroid Build Coastguard Worker     // Use the "hinted" version of insert.
372*61c4878aSAndroid Build Coastguard Worker     multimap_.insert(multimap_.end(), pair);
373*61c4878aSAndroid Build Coastguard Worker     prev_key = pair.key();
374*61c4878aSAndroid Build Coastguard Worker   }
375*61c4878aSAndroid Build Coastguard Worker   EXPECT_FALSE(sorted);
376*61c4878aSAndroid Build Coastguard Worker 
377*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs);
378*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
379*61c4878aSAndroid Build Coastguard Worker }
380*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_Duplicate)381*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_Duplicate) {
382*61c4878aSAndroid Build Coastguard Worker   TestPair pair1(60, "1");
383*61c4878aSAndroid Build Coastguard Worker   TestPair pair2(60, "2");
384*61c4878aSAndroid Build Coastguard Worker 
385*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.insert(pair1);
386*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "1");
387*61c4878aSAndroid Build Coastguard Worker 
388*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.insert(pair2);
389*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "2");
390*61c4878aSAndroid Build Coastguard Worker 
391*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs + 2);
392*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
393*61c4878aSAndroid Build Coastguard Worker 
394*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pair 1 goes out of scope.
395*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
396*61c4878aSAndroid Build Coastguard Worker }
397*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_ObjectIterators)398*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_ObjectIterators) {
399*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
400*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs_.begin(), pairs_.end());
401*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs);
402*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
403*61c4878aSAndroid Build Coastguard Worker }
404*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_ObjectIterators_Empty)405*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_ObjectIterators_Empty) {
406*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs_.end(), pairs_.end());
407*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs);
408*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
409*61c4878aSAndroid Build Coastguard Worker }
410*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_ObjectIterators_WithDuplicates)411*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_ObjectIterators_WithDuplicates) {
412*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair, 3> pairs = {{
413*61c4878aSAndroid Build Coastguard Worker       {50, "B"},
414*61c4878aSAndroid Build Coastguard Worker       {40, "D"},
415*61c4878aSAndroid Build Coastguard Worker       {60, "F"},
416*61c4878aSAndroid Build Coastguard Worker   }};
417*61c4878aSAndroid Build Coastguard Worker 
418*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs.begin(), pairs.end());
419*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs + 3);
420*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
421*61c4878aSAndroid Build Coastguard Worker 
422*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.find(40);
423*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
424*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "d");
425*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "D");
426*61c4878aSAndroid Build Coastguard Worker 
427*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(50);
428*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
429*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "b");
430*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "B");
431*61c4878aSAndroid Build Coastguard Worker 
432*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(60);
433*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
434*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "F");
435*61c4878aSAndroid Build Coastguard Worker 
436*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
437*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
438*61c4878aSAndroid Build Coastguard Worker }
439*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_PointerIterators)440*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_PointerIterators) {
441*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
442*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair*, 3> ptrs = {&pairs_[0], &pairs_[1], &pairs_[2]};
443*61c4878aSAndroid Build Coastguard Worker 
444*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(ptrs.begin(), ptrs.end());
445*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), 3U);
446*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
447*61c4878aSAndroid Build Coastguard Worker }
448*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_PointerIterators_Empty)449*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_PointerIterators_Empty) {
450*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair*, 0> ptrs;
451*61c4878aSAndroid Build Coastguard Worker 
452*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(ptrs.begin(), ptrs.end());
453*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs);
454*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
455*61c4878aSAndroid Build Coastguard Worker }
456*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_PointerIterators_WithDuplicates)457*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_PointerIterators_WithDuplicates) {
458*61c4878aSAndroid Build Coastguard Worker   TestPair pair1(50, "B");
459*61c4878aSAndroid Build Coastguard Worker   TestPair pair2(40, "D");
460*61c4878aSAndroid Build Coastguard Worker   TestPair pair3(60, "F");
461*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair*, 3> ptrs = {&pair1, &pair2, &pair3};
462*61c4878aSAndroid Build Coastguard Worker 
463*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(ptrs.begin(), ptrs.end());
464*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs + 3);
465*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
466*61c4878aSAndroid Build Coastguard Worker 
467*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.find(40);
468*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
469*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "d");
470*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "D");
471*61c4878aSAndroid Build Coastguard Worker 
472*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(50);
473*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
474*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "b");
475*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "B");
476*61c4878aSAndroid Build Coastguard Worker 
477*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(60);
478*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
479*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "F");
480*61c4878aSAndroid Build Coastguard Worker 
481*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
482*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
483*61c4878aSAndroid Build Coastguard Worker }
484*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_InitializerList)485*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_InitializerList) {
486*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
487*61c4878aSAndroid Build Coastguard Worker   multimap_.insert({&pairs_[0], &pairs_[2], &pairs_[4]});
488*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), 3U);
489*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
490*61c4878aSAndroid Build Coastguard Worker }
491*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_InitializerList_Empty)492*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_InitializerList_Empty) {
493*61c4878aSAndroid Build Coastguard Worker   multimap_.insert({});
494*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs);
495*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
496*61c4878aSAndroid Build Coastguard Worker }
497*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_InitializerList_WithDuplicates)498*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_InitializerList_WithDuplicates) {
499*61c4878aSAndroid Build Coastguard Worker   TestPair pair1(50, "B");
500*61c4878aSAndroid Build Coastguard Worker   TestPair pair2(40, "D");
501*61c4878aSAndroid Build Coastguard Worker   TestPair pair3(60, "F");
502*61c4878aSAndroid Build Coastguard Worker 
503*61c4878aSAndroid Build Coastguard Worker   multimap_.insert({&pair1, &pair2, &pair3});
504*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs + 3);
505*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
506*61c4878aSAndroid Build Coastguard Worker 
507*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.find(40);
508*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
509*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "d");
510*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "D");
511*61c4878aSAndroid Build Coastguard Worker 
512*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(50);
513*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
514*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "b");
515*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "B");
516*61c4878aSAndroid Build Coastguard Worker 
517*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(60);
518*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
519*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "F");
520*61c4878aSAndroid Build Coastguard Worker 
521*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
522*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
523*61c4878aSAndroid Build Coastguard Worker }
524*61c4878aSAndroid Build Coastguard Worker 
525*61c4878aSAndroid Build Coastguard Worker // A pair derived from TestPair.
526*61c4878aSAndroid Build Coastguard Worker struct DerivedPair : public TestPair {
DerivedPair__anond08d356a0111::DerivedPair527*61c4878aSAndroid Build Coastguard Worker   DerivedPair(size_t n, const char* name) : TestPair(n * 10, name) {}
528*61c4878aSAndroid Build Coastguard Worker };
529*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_DerivedPairs)530*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_DerivedPairs) {
531*61c4878aSAndroid Build Coastguard Worker   DerivedPair pair1(6, "f");
532*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pair1);
533*61c4878aSAndroid Build Coastguard Worker 
534*61c4878aSAndroid Build Coastguard Worker   DerivedPair pair2(7, "g");
535*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pair2);
536*61c4878aSAndroid Build Coastguard Worker 
537*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs + 2);
538*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
539*61c4878aSAndroid Build Coastguard Worker 
540*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
541*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
542*61c4878aSAndroid Build Coastguard Worker }
543*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Insert_DerivedPairs_CompilationFails)544*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Insert_DerivedPairs_CompilationFails) {
545*61c4878aSAndroid Build Coastguard Worker   ::pw::IntrusiveMultiMap<size_t, DerivedPair>
546*61c4878aSAndroid Build Coastguard Worker       derived_from_compatible_pair_type;
547*61c4878aSAndroid Build Coastguard Worker 
548*61c4878aSAndroid Build Coastguard Worker   DerivedPair pair1(6, "f");
549*61c4878aSAndroid Build Coastguard Worker   derived_from_compatible_pair_type.insert(pair1);
550*61c4878aSAndroid Build Coastguard Worker 
551*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(derived_from_compatible_pair_type.size(), 1U);
552*61c4878aSAndroid Build Coastguard Worker 
553*61c4878aSAndroid Build Coastguard Worker #if PW_NC_TEST(CannotAddBaseClassToDerivedClassMap)
554*61c4878aSAndroid Build Coastguard Worker   PW_NC_EXPECT("derived_from_compatible_pair_type\.insert\(pair2\)");
555*61c4878aSAndroid Build Coastguard Worker 
556*61c4878aSAndroid Build Coastguard Worker   TestPair pair2(70, "g");
557*61c4878aSAndroid Build Coastguard Worker   derived_from_compatible_pair_type.insert(pair2);
558*61c4878aSAndroid Build Coastguard Worker #endif
559*61c4878aSAndroid Build Coastguard Worker   derived_from_compatible_pair_type.clear();
560*61c4878aSAndroid Build Coastguard Worker }
561*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Erase_One_ByItem)562*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Erase_One_ByItem) {
563*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumPairs; ++i) {
564*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(multimap_.size(), kNumPairs);
565*61c4878aSAndroid Build Coastguard Worker     auto iter = multimap_.erase(pairs_[i]);
566*61c4878aSAndroid Build Coastguard Worker     if (iter != multimap_.end()) {
567*61c4878aSAndroid Build Coastguard Worker       EXPECT_GE(iter->key(), pairs_[i].key());
568*61c4878aSAndroid Build Coastguard Worker     }
569*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(multimap_.size(), kNumPairs - 1);
570*61c4878aSAndroid Build Coastguard Worker     multimap_.insert(pairs_[i]);
571*61c4878aSAndroid Build Coastguard Worker   }
572*61c4878aSAndroid Build Coastguard Worker }
573*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Erase_Two_ByKey)574*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Erase_Two_ByKey) {
575*61c4878aSAndroid Build Coastguard Worker   constexpr size_t kHalf = kNumPairs / 2;
576*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kHalf; ++i) {
577*61c4878aSAndroid Build Coastguard Worker     ASSERT_EQ(pairs_[i].key(), pairs_[i + kHalf].key());
578*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(multimap_.size(), kNumPairs);
579*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(multimap_.erase(pairs_[i].key()), 2U);
580*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(multimap_.size(), kNumPairs - 2);
581*61c4878aSAndroid Build Coastguard Worker     auto iter = multimap_.find(pairs_[i].key());
582*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(iter, multimap_.end());
583*61c4878aSAndroid Build Coastguard Worker     multimap_.insert(pairs_[i]);
584*61c4878aSAndroid Build Coastguard Worker     multimap_.insert(pairs_[i + kHalf]);
585*61c4878aSAndroid Build Coastguard Worker   }
586*61c4878aSAndroid Build Coastguard Worker }
587*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Erase_OnlyItem)588*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Erase_OnlyItem) {
589*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
590*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs_[0]);
591*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), 1U);
592*61c4878aSAndroid Build Coastguard Worker 
593*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.erase(pairs_[0].key()), 1U);
594*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), 0U);
595*61c4878aSAndroid Build Coastguard Worker }
596*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Erase_AllOnebyOne)597*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Erase_AllOnebyOne) {
598*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.begin();
599*61c4878aSAndroid Build Coastguard Worker   for (size_t n = kNumPairs; n != 0; --n) {
600*61c4878aSAndroid Build Coastguard Worker     ASSERT_NE(iter, multimap_.end());
601*61c4878aSAndroid Build Coastguard Worker     iter = multimap_.erase(iter);
602*61c4878aSAndroid Build Coastguard Worker   }
603*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap_.end());
604*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), 0U);
605*61c4878aSAndroid Build Coastguard Worker }
606*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Erase_Range)607*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Erase_Range) {
608*61c4878aSAndroid Build Coastguard Worker   auto first = multimap_.begin();
609*61c4878aSAndroid Build Coastguard Worker   auto last = multimap_.end();
610*61c4878aSAndroid Build Coastguard Worker   ++first;
611*61c4878aSAndroid Build Coastguard Worker   --last;
612*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.erase(first, last);
613*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), 2U);
614*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
615*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->key(), 50U);
616*61c4878aSAndroid Build Coastguard Worker }
617*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Erase_MissingItem)618*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Erase_MissingItem) {
619*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.erase(100), 0U);
620*61c4878aSAndroid Build Coastguard Worker }
621*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Erase_Reinsert)622*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Erase_Reinsert) {
623*61c4878aSAndroid Build Coastguard Worker   constexpr size_t kHalf = kNumPairs / 2;
624*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), pairs_.size());
625*61c4878aSAndroid Build Coastguard Worker 
626*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(pairs_[0].key(), pairs_[0 + kHalf].key());
627*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.erase(pairs_[0].key()), 2U);
628*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.find(pairs_[0].key()), multimap_.end());
629*61c4878aSAndroid Build Coastguard Worker 
630*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(pairs_[2].key(), pairs_[2 + kHalf].key());
631*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.erase(pairs_[2].key()), 2U);
632*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.find(pairs_[2].key()), multimap_.end());
633*61c4878aSAndroid Build Coastguard Worker 
634*61c4878aSAndroid Build Coastguard Worker   ASSERT_EQ(pairs_[4].key(), pairs_[4 + kHalf].key());
635*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.erase(pairs_[4].key()), 2U);
636*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.find(pairs_[4].key()), multimap_.end());
637*61c4878aSAndroid Build Coastguard Worker 
638*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), pairs_.size() - 6);
639*61c4878aSAndroid Build Coastguard Worker 
640*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs_[4]);
641*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.find(pairs_[4].key());
642*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(iter, multimap_.end());
643*61c4878aSAndroid Build Coastguard Worker 
644*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs_[0]);
645*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(pairs_[0].key());
646*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(iter, multimap_.end());
647*61c4878aSAndroid Build Coastguard Worker 
648*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs_[2]);
649*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(pairs_[2].key());
650*61c4878aSAndroid Build Coastguard Worker   EXPECT_NE(iter, multimap_.end());
651*61c4878aSAndroid Build Coastguard Worker 
652*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), pairs_.size() - 3);
653*61c4878aSAndroid Build Coastguard Worker }
654*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Erase_Duplicate)655*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Erase_Duplicate) {
656*61c4878aSAndroid Build Coastguard Worker   TestPair pair1(32, "1");
657*61c4878aSAndroid Build Coastguard Worker   TestPair pair2(32, "2");
658*61c4878aSAndroid Build Coastguard Worker   TestPair pair3(32, "3");
659*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pair1);
660*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pair2);
661*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pair3);
662*61c4878aSAndroid Build Coastguard Worker 
663*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.find(32);
664*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
665*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "1");
666*61c4878aSAndroid Build Coastguard Worker 
667*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.erase(iter);
668*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
669*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "2");
670*61c4878aSAndroid Build Coastguard Worker 
671*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.erase(iter);
672*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
673*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "3");
674*61c4878aSAndroid Build Coastguard Worker 
675*61c4878aSAndroid Build Coastguard Worker   multimap_.erase(iter);
676*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.find(32), multimap_.end());
677*61c4878aSAndroid Build Coastguard Worker }
678*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Swap)679*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Swap) {
680*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair, 3> pairs = {{
681*61c4878aSAndroid Build Coastguard Worker       {50, "B"},
682*61c4878aSAndroid Build Coastguard Worker       {40, "D"},
683*61c4878aSAndroid Build Coastguard Worker       {60, "F"},
684*61c4878aSAndroid Build Coastguard Worker   }};
685*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap(pairs.begin(), pairs.end());
686*61c4878aSAndroid Build Coastguard Worker 
687*61c4878aSAndroid Build Coastguard Worker   multimap_.swap(multimap);
688*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), kNumPairs);
689*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap.begin(), multimap.end(), LessThan));
690*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.begin();
691*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "e");
692*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "E");
693*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "c");
694*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "C");
695*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "a");
696*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "A");
697*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "d");
698*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "D");
699*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "b");
700*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "B");
701*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.end());
702*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
703*61c4878aSAndroid Build Coastguard Worker 
704*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), 3U);
705*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
706*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.begin();
707*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "D");
708*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "B");
709*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "F");
710*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap_.end());
711*61c4878aSAndroid Build Coastguard Worker 
712*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
713*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
714*61c4878aSAndroid Build Coastguard Worker }
715*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Swap_Empty)716*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Swap_Empty) {
717*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap;
718*61c4878aSAndroid Build Coastguard Worker 
719*61c4878aSAndroid Build Coastguard Worker   multimap_.swap(multimap);
720*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), kNumPairs);
721*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap.begin(), multimap.end(), LessThan));
722*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.begin();
723*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "e");
724*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "E");
725*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "c");
726*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "C");
727*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "a");
728*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "A");
729*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "d");
730*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "D");
731*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "b");
732*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "B");
733*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.end());
734*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
735*61c4878aSAndroid Build Coastguard Worker 
736*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), 0U);
737*61c4878aSAndroid Build Coastguard Worker }
738*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Merge)739*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Merge) {
740*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair, 3> pairs = {{
741*61c4878aSAndroid Build Coastguard Worker       {5, "f"},
742*61c4878aSAndroid Build Coastguard Worker       {75, "g"},
743*61c4878aSAndroid Build Coastguard Worker       {85, "h"},
744*61c4878aSAndroid Build Coastguard Worker   }};
745*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap(pairs.begin(), pairs.end());
746*61c4878aSAndroid Build Coastguard Worker 
747*61c4878aSAndroid Build Coastguard Worker   multimap_.merge(multimap);
748*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(multimap.empty());
749*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs + 3);
750*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
751*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.begin();
752*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "f");
753*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "e");
754*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "E");
755*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "c");
756*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "C");
757*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "a");
758*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "A");
759*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "d");
760*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "D");
761*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "b");
762*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "B");
763*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "g");
764*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "h");
765*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap_.end());
766*61c4878aSAndroid Build Coastguard Worker 
767*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
768*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
769*61c4878aSAndroid Build Coastguard Worker }
770*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Merge_Empty)771*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Merge_Empty) {
772*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap;
773*61c4878aSAndroid Build Coastguard Worker 
774*61c4878aSAndroid Build Coastguard Worker   multimap_.merge(multimap);
775*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs);
776*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
777*61c4878aSAndroid Build Coastguard Worker 
778*61c4878aSAndroid Build Coastguard Worker   multimap.merge(multimap_);
779*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(multimap_.empty());
780*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.size(), kNumPairs);
781*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap.begin(), multimap.end(), LessThan));
782*61c4878aSAndroid Build Coastguard Worker 
783*61c4878aSAndroid Build Coastguard Worker   multimap.clear();
784*61c4878aSAndroid Build Coastguard Worker }
785*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Merge_WithDuplicates)786*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Merge_WithDuplicates) {
787*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair, 3> pairs = {{
788*61c4878aSAndroid Build Coastguard Worker       {15, "f"},
789*61c4878aSAndroid Build Coastguard Worker       {45, "g"},
790*61c4878aSAndroid Build Coastguard Worker       {55, "h"},
791*61c4878aSAndroid Build Coastguard Worker   }};
792*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap multimap(pairs.begin(), pairs.end());
793*61c4878aSAndroid Build Coastguard Worker 
794*61c4878aSAndroid Build Coastguard Worker   multimap_.merge(multimap);
795*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(multimap.empty());
796*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs + 3);
797*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
798*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.begin();
799*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "e");
800*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "E");
801*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "f");
802*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "c");
803*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "C");
804*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "a");
805*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "A");
806*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "d");
807*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "D");
808*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "g");
809*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "b");
810*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "B");
811*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "h");
812*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap_.end());
813*61c4878aSAndroid Build Coastguard Worker 
814*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
815*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
816*61c4878aSAndroid Build Coastguard Worker }
817*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Merge_Map)818*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Merge_Map) {
819*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair, 3> pairs = {{
820*61c4878aSAndroid Build Coastguard Worker       {15, "f"},
821*61c4878aSAndroid Build Coastguard Worker       {45, "g"},
822*61c4878aSAndroid Build Coastguard Worker       {55, "h"},
823*61c4878aSAndroid Build Coastguard Worker   }};
824*61c4878aSAndroid Build Coastguard Worker   ::pw::IntrusiveMap<size_t, TestPair> map(pairs.begin(), pairs.end());
825*61c4878aSAndroid Build Coastguard Worker 
826*61c4878aSAndroid Build Coastguard Worker   multimap_.merge(map);
827*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(map.empty());
828*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap_.size(), kNumPairs + 3);
829*61c4878aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::is_sorted(multimap_.begin(), multimap_.end(), LessThan));
830*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.begin();
831*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "e");
832*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "E");
833*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "f");
834*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "c");
835*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "C");
836*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "a");
837*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "A");
838*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "d");
839*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "D");
840*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "g");
841*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "b");
842*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "B");
843*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ((iter++)->name(), "h");
844*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap_.end());
845*61c4878aSAndroid Build Coastguard Worker 
846*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
847*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
848*61c4878aSAndroid Build Coastguard Worker }
849*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Count)850*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Count) {
851*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair, 3> pairs = {{
852*61c4878aSAndroid Build Coastguard Worker       {50, "B"},
853*61c4878aSAndroid Build Coastguard Worker       {40, "D"},
854*61c4878aSAndroid Build Coastguard Worker       {60, "F"},
855*61c4878aSAndroid Build Coastguard Worker   }};
856*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs.begin(), pairs.end());
857*61c4878aSAndroid Build Coastguard Worker 
858*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
859*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.count(10), 2U);
860*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.count(20), 2U);
861*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.count(30), 2U);
862*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.count(40), 3U);
863*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.count(50), 3U);
864*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.count(60), 1U);
865*61c4878aSAndroid Build Coastguard Worker 
866*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
867*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
868*61c4878aSAndroid Build Coastguard Worker }
869*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Count_NoSuchKey)870*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Count_NoSuchKey) {
871*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
872*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.count(60), 0U);
873*61c4878aSAndroid Build Coastguard Worker }
874*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Find)875*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Find) {
876*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
877*61c4878aSAndroid Build Coastguard Worker   size_t key = 10;
878*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumPairs; i += 2) {
879*61c4878aSAndroid Build Coastguard Worker     auto iter = multimap.find(key);
880*61c4878aSAndroid Build Coastguard Worker     ASSERT_NE(iter, multimap.end());
881*61c4878aSAndroid Build Coastguard Worker     EXPECT_EQ(iter->key(), key);
882*61c4878aSAndroid Build Coastguard Worker     key += 10;
883*61c4878aSAndroid Build Coastguard Worker   }
884*61c4878aSAndroid Build Coastguard Worker }
885*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Find_NoSuchKey)886*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Find_NoSuchKey) {
887*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
888*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.find(60);
889*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter, multimap.end());
890*61c4878aSAndroid Build Coastguard Worker }
891*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,Find_WithDuplicates)892*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, Find_WithDuplicates) {
893*61c4878aSAndroid Build Coastguard Worker   std::array<TestPair, 3> pairs = {{
894*61c4878aSAndroid Build Coastguard Worker       {50, "B"},
895*61c4878aSAndroid Build Coastguard Worker       {40, "D"},
896*61c4878aSAndroid Build Coastguard Worker       {60, "F"},
897*61c4878aSAndroid Build Coastguard Worker   }};
898*61c4878aSAndroid Build Coastguard Worker   multimap_.insert(pairs.begin(), pairs.end());
899*61c4878aSAndroid Build Coastguard Worker 
900*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap_.find(40);
901*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
902*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->key(), 40U);
903*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ((iter++)->name(), "d");
904*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->key(), 40U);
905*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->name(), "D");
906*61c4878aSAndroid Build Coastguard Worker 
907*61c4878aSAndroid Build Coastguard Worker   iter = multimap_.find(50);
908*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap_.end());
909*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->key(), 50U);
910*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ((iter++)->name(), "b");
911*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->key(), 50U);
912*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(iter->name(), "B");
913*61c4878aSAndroid Build Coastguard Worker 
914*61c4878aSAndroid Build Coastguard Worker   // Explicitly clear the multimap before pairs goes out of scope.
915*61c4878aSAndroid Build Coastguard Worker   multimap_.clear();
916*61c4878aSAndroid Build Coastguard Worker }
917*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,LowerBound)918*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, LowerBound) {
919*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
920*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.lower_bound(10);
921*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
922*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "e");
923*61c4878aSAndroid Build Coastguard Worker 
924*61c4878aSAndroid Build Coastguard Worker   iter = multimap.lower_bound(20);
925*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
926*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "c");
927*61c4878aSAndroid Build Coastguard Worker 
928*61c4878aSAndroid Build Coastguard Worker   iter = multimap.lower_bound(30);
929*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
930*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "a");
931*61c4878aSAndroid Build Coastguard Worker 
932*61c4878aSAndroid Build Coastguard Worker   iter = multimap.lower_bound(40);
933*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
934*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "d");
935*61c4878aSAndroid Build Coastguard Worker 
936*61c4878aSAndroid Build Coastguard Worker   iter = multimap.lower_bound(50);
937*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
938*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "b");
939*61c4878aSAndroid Build Coastguard Worker }
940*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,LowerBound_NoExactKey)941*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, LowerBound_NoExactKey) {
942*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
943*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.lower_bound(5);
944*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
945*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "e");
946*61c4878aSAndroid Build Coastguard Worker 
947*61c4878aSAndroid Build Coastguard Worker   iter = multimap.lower_bound(15);
948*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
949*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "c");
950*61c4878aSAndroid Build Coastguard Worker 
951*61c4878aSAndroid Build Coastguard Worker   iter = multimap.lower_bound(25);
952*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
953*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "a");
954*61c4878aSAndroid Build Coastguard Worker 
955*61c4878aSAndroid Build Coastguard Worker   iter = multimap.lower_bound(35);
956*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
957*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "d");
958*61c4878aSAndroid Build Coastguard Worker 
959*61c4878aSAndroid Build Coastguard Worker   iter = multimap.lower_bound(45);
960*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
961*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "b");
962*61c4878aSAndroid Build Coastguard Worker }
963*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,LowerBound_OutOfRange)964*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, LowerBound_OutOfRange) {
965*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
966*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.lower_bound(55), multimap.end());
967*61c4878aSAndroid Build Coastguard Worker }
968*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,UpperBound)969*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, UpperBound) {
970*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
971*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.upper_bound(15);
972*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
973*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "c");
974*61c4878aSAndroid Build Coastguard Worker 
975*61c4878aSAndroid Build Coastguard Worker   iter = multimap.upper_bound(25);
976*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
977*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "a");
978*61c4878aSAndroid Build Coastguard Worker 
979*61c4878aSAndroid Build Coastguard Worker   iter = multimap.upper_bound(35);
980*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
981*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "d");
982*61c4878aSAndroid Build Coastguard Worker 
983*61c4878aSAndroid Build Coastguard Worker   iter = multimap.upper_bound(45);
984*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
985*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "b");
986*61c4878aSAndroid Build Coastguard Worker 
987*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.upper_bound(55), multimap.end());
988*61c4878aSAndroid Build Coastguard Worker }
989*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,UpperBound_NoExactKey)990*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, UpperBound_NoExactKey) {
991*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
992*61c4878aSAndroid Build Coastguard Worker   auto iter = multimap.upper_bound(5);
993*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
994*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "e");
995*61c4878aSAndroid Build Coastguard Worker 
996*61c4878aSAndroid Build Coastguard Worker   iter = multimap.upper_bound(15);
997*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
998*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "c");
999*61c4878aSAndroid Build Coastguard Worker 
1000*61c4878aSAndroid Build Coastguard Worker   iter = multimap.upper_bound(25);
1001*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
1002*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "a");
1003*61c4878aSAndroid Build Coastguard Worker 
1004*61c4878aSAndroid Build Coastguard Worker   iter = multimap.upper_bound(35);
1005*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
1006*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "d");
1007*61c4878aSAndroid Build Coastguard Worker 
1008*61c4878aSAndroid Build Coastguard Worker   iter = multimap.upper_bound(45);
1009*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(iter, multimap.end());
1010*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(iter->name(), "b");
1011*61c4878aSAndroid Build Coastguard Worker }
1012*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,UpperBound_OutOfRange)1013*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, UpperBound_OutOfRange) {
1014*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
1015*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(multimap.upper_bound(55), multimap.end());
1016*61c4878aSAndroid Build Coastguard Worker }
1017*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,EqualRange)1018*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, EqualRange) {
1019*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
1020*61c4878aSAndroid Build Coastguard Worker 
1021*61c4878aSAndroid Build Coastguard Worker   auto pair = multimap.equal_range(10);
1022*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap::const_iterator lower = pair.first;
1023*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap::const_iterator upper = pair.second;
1024*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1025*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "e");
1026*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(upper, multimap.end());
1027*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(upper->name(), "c");
1028*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::distance(lower, upper), 2);
1029*61c4878aSAndroid Build Coastguard Worker 
1030*61c4878aSAndroid Build Coastguard Worker   std::tie(lower, upper) = multimap.equal_range(20);
1031*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1032*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "c");
1033*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(upper, multimap.end());
1034*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(upper->name(), "a");
1035*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::distance(lower, upper), 2);
1036*61c4878aSAndroid Build Coastguard Worker 
1037*61c4878aSAndroid Build Coastguard Worker   std::tie(lower, upper) = multimap.equal_range(30);
1038*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1039*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "a");
1040*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(upper, multimap.end());
1041*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(upper->name(), "d");
1042*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::distance(lower, upper), 2);
1043*61c4878aSAndroid Build Coastguard Worker 
1044*61c4878aSAndroid Build Coastguard Worker   std::tie(lower, upper) = multimap.equal_range(40);
1045*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1046*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "d");
1047*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(upper, multimap.end());
1048*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(upper->name(), "b");
1049*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::distance(lower, upper), 2);
1050*61c4878aSAndroid Build Coastguard Worker 
1051*61c4878aSAndroid Build Coastguard Worker   std::tie(lower, upper) = multimap.equal_range(50);
1052*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1053*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "b");
1054*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(upper, multimap.end());
1055*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(std::distance(lower, upper), 2);
1056*61c4878aSAndroid Build Coastguard Worker }
1057*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,EqualRange_NoExactKey)1058*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, EqualRange_NoExactKey) {
1059*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
1060*61c4878aSAndroid Build Coastguard Worker 
1061*61c4878aSAndroid Build Coastguard Worker   auto pair = multimap.equal_range(5);
1062*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap::const_iterator lower = pair.first;
1063*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap::const_iterator upper = pair.second;
1064*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1065*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "e");
1066*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(lower, upper);
1067*61c4878aSAndroid Build Coastguard Worker 
1068*61c4878aSAndroid Build Coastguard Worker   std::tie(lower, upper) = multimap.equal_range(15);
1069*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1070*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "c");
1071*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(lower, upper);
1072*61c4878aSAndroid Build Coastguard Worker 
1073*61c4878aSAndroid Build Coastguard Worker   std::tie(lower, upper) = multimap.equal_range(25);
1074*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1075*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "a");
1076*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(lower, upper);
1077*61c4878aSAndroid Build Coastguard Worker 
1078*61c4878aSAndroid Build Coastguard Worker   std::tie(lower, upper) = multimap.equal_range(35);
1079*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1080*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "d");
1081*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(lower, upper);
1082*61c4878aSAndroid Build Coastguard Worker 
1083*61c4878aSAndroid Build Coastguard Worker   std::tie(lower, upper) = multimap.equal_range(45);
1084*61c4878aSAndroid Build Coastguard Worker   ASSERT_NE(lower, multimap.end());
1085*61c4878aSAndroid Build Coastguard Worker   EXPECT_STREQ(lower->name(), "b");
1086*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(lower, upper);
1087*61c4878aSAndroid Build Coastguard Worker }
1088*61c4878aSAndroid Build Coastguard Worker 
TEST_F(IntrusiveMultiMapTest,EqualRange_OutOfRange)1089*61c4878aSAndroid Build Coastguard Worker TEST_F(IntrusiveMultiMapTest, EqualRange_OutOfRange) {
1090*61c4878aSAndroid Build Coastguard Worker   const IntrusiveMultiMap& multimap = multimap_;
1091*61c4878aSAndroid Build Coastguard Worker 
1092*61c4878aSAndroid Build Coastguard Worker   auto pair = multimap.equal_range(60);
1093*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap::const_iterator lower = pair.first;
1094*61c4878aSAndroid Build Coastguard Worker   IntrusiveMultiMap::const_iterator upper = pair.second;
1095*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(lower, multimap.end());
1096*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(upper, multimap.end());
1097*61c4878aSAndroid Build Coastguard Worker }
1098*61c4878aSAndroid Build Coastguard Worker 
1099*61c4878aSAndroid Build Coastguard Worker }  // namespace
1100