xref: /aosp_15_r20/external/libchrome/base/containers/id_map_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/containers/id_map.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
12*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
13*635a8641SAndroid Build Coastguard Worker 
14*635a8641SAndroid Build Coastguard Worker namespace base {
15*635a8641SAndroid Build Coastguard Worker 
16*635a8641SAndroid Build Coastguard Worker namespace {
17*635a8641SAndroid Build Coastguard Worker 
18*635a8641SAndroid Build Coastguard Worker class TestObject {
19*635a8641SAndroid Build Coastguard Worker };
20*635a8641SAndroid Build Coastguard Worker 
21*635a8641SAndroid Build Coastguard Worker class DestructorCounter {
22*635a8641SAndroid Build Coastguard Worker  public:
DestructorCounter(int * counter)23*635a8641SAndroid Build Coastguard Worker   explicit DestructorCounter(int* counter) : counter_(counter) {}
~DestructorCounter()24*635a8641SAndroid Build Coastguard Worker   ~DestructorCounter() { ++(*counter_); }
25*635a8641SAndroid Build Coastguard Worker 
26*635a8641SAndroid Build Coastguard Worker  private:
27*635a8641SAndroid Build Coastguard Worker   int* counter_;
28*635a8641SAndroid Build Coastguard Worker };
29*635a8641SAndroid Build Coastguard Worker 
30*635a8641SAndroid Build Coastguard Worker }  // namespace
31*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,Basic)32*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, Basic) {
33*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*> map;
34*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(map.IsEmpty());
35*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0U, map.size());
36*635a8641SAndroid Build Coastguard Worker 
37*635a8641SAndroid Build Coastguard Worker   TestObject obj1;
38*635a8641SAndroid Build Coastguard Worker   TestObject obj2;
39*635a8641SAndroid Build Coastguard Worker 
40*635a8641SAndroid Build Coastguard Worker   int32_t id1 = map.Add(&obj1);
41*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(map.IsEmpty());
42*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(1U, map.size());
43*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj1, map.Lookup(id1));
44*635a8641SAndroid Build Coastguard Worker 
45*635a8641SAndroid Build Coastguard Worker   int32_t id2 = map.Add(&obj2);
46*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(map.IsEmpty());
47*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(2U, map.size());
48*635a8641SAndroid Build Coastguard Worker 
49*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj1, map.Lookup(id1));
50*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj2, map.Lookup(id2));
51*635a8641SAndroid Build Coastguard Worker 
52*635a8641SAndroid Build Coastguard Worker   map.Remove(id1);
53*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(map.IsEmpty());
54*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(1U, map.size());
55*635a8641SAndroid Build Coastguard Worker 
56*635a8641SAndroid Build Coastguard Worker   map.Remove(id2);
57*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(map.IsEmpty());
58*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0U, map.size());
59*635a8641SAndroid Build Coastguard Worker 
60*635a8641SAndroid Build Coastguard Worker   map.AddWithID(&obj1, 1);
61*635a8641SAndroid Build Coastguard Worker   map.AddWithID(&obj2, 2);
62*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj1, map.Lookup(1));
63*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj2, map.Lookup(2));
64*635a8641SAndroid Build Coastguard Worker 
65*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj2, map.Replace(2, &obj1));
66*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj1, map.Lookup(2));
67*635a8641SAndroid Build Coastguard Worker 
68*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, map.iteration_depth());
69*635a8641SAndroid Build Coastguard Worker }
70*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,IteratorRemainsValidWhenRemovingCurrentElement)71*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, IteratorRemainsValidWhenRemovingCurrentElement) {
72*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*> map;
73*635a8641SAndroid Build Coastguard Worker 
74*635a8641SAndroid Build Coastguard Worker   TestObject obj1;
75*635a8641SAndroid Build Coastguard Worker   TestObject obj2;
76*635a8641SAndroid Build Coastguard Worker   TestObject obj3;
77*635a8641SAndroid Build Coastguard Worker 
78*635a8641SAndroid Build Coastguard Worker   map.Add(&obj1);
79*635a8641SAndroid Build Coastguard Worker   map.Add(&obj2);
80*635a8641SAndroid Build Coastguard Worker   map.Add(&obj3);
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker   {
83*635a8641SAndroid Build Coastguard Worker     IDMap<TestObject*>::const_iterator iter(&map);
84*635a8641SAndroid Build Coastguard Worker 
85*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(1, map.iteration_depth());
86*635a8641SAndroid Build Coastguard Worker 
87*635a8641SAndroid Build Coastguard Worker     while (!iter.IsAtEnd()) {
88*635a8641SAndroid Build Coastguard Worker       map.Remove(iter.GetCurrentKey());
89*635a8641SAndroid Build Coastguard Worker       iter.Advance();
90*635a8641SAndroid Build Coastguard Worker     }
91*635a8641SAndroid Build Coastguard Worker 
92*635a8641SAndroid Build Coastguard Worker     // Test that while an iterator is still in scope, we get the map emptiness
93*635a8641SAndroid Build Coastguard Worker     // right (http://crbug.com/35571).
94*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(map.IsEmpty());
95*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(0U, map.size());
96*635a8641SAndroid Build Coastguard Worker   }
97*635a8641SAndroid Build Coastguard Worker 
98*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(map.IsEmpty());
99*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0U, map.size());
100*635a8641SAndroid Build Coastguard Worker 
101*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, map.iteration_depth());
102*635a8641SAndroid Build Coastguard Worker }
103*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,IteratorRemainsValidWhenRemovingOtherElements)104*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, IteratorRemainsValidWhenRemovingOtherElements) {
105*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*> map;
106*635a8641SAndroid Build Coastguard Worker 
107*635a8641SAndroid Build Coastguard Worker   const int kCount = 5;
108*635a8641SAndroid Build Coastguard Worker   TestObject obj[kCount];
109*635a8641SAndroid Build Coastguard Worker 
110*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kCount; i++)
111*635a8641SAndroid Build Coastguard Worker     map.Add(&obj[i]);
112*635a8641SAndroid Build Coastguard Worker 
113*635a8641SAndroid Build Coastguard Worker   // IDMap has no predictable iteration order.
114*635a8641SAndroid Build Coastguard Worker   int32_t ids_in_iteration_order[kCount];
115*635a8641SAndroid Build Coastguard Worker   const TestObject* objs_in_iteration_order[kCount];
116*635a8641SAndroid Build Coastguard Worker   int counter = 0;
117*635a8641SAndroid Build Coastguard Worker   for (IDMap<TestObject*>::const_iterator iter(&map); !iter.IsAtEnd();
118*635a8641SAndroid Build Coastguard Worker        iter.Advance()) {
119*635a8641SAndroid Build Coastguard Worker     ids_in_iteration_order[counter] = iter.GetCurrentKey();
120*635a8641SAndroid Build Coastguard Worker     objs_in_iteration_order[counter] = iter.GetCurrentValue();
121*635a8641SAndroid Build Coastguard Worker     counter++;
122*635a8641SAndroid Build Coastguard Worker   }
123*635a8641SAndroid Build Coastguard Worker 
124*635a8641SAndroid Build Coastguard Worker   counter = 0;
125*635a8641SAndroid Build Coastguard Worker   for (IDMap<TestObject*>::const_iterator iter(&map); !iter.IsAtEnd();
126*635a8641SAndroid Build Coastguard Worker        iter.Advance()) {
127*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(1, map.iteration_depth());
128*635a8641SAndroid Build Coastguard Worker 
129*635a8641SAndroid Build Coastguard Worker     switch (counter) {
130*635a8641SAndroid Build Coastguard Worker       case 0:
131*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(ids_in_iteration_order[0], iter.GetCurrentKey());
132*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(objs_in_iteration_order[0], iter.GetCurrentValue());
133*635a8641SAndroid Build Coastguard Worker         map.Remove(ids_in_iteration_order[1]);
134*635a8641SAndroid Build Coastguard Worker         break;
135*635a8641SAndroid Build Coastguard Worker       case 1:
136*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(ids_in_iteration_order[2], iter.GetCurrentKey());
137*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(objs_in_iteration_order[2], iter.GetCurrentValue());
138*635a8641SAndroid Build Coastguard Worker         map.Remove(ids_in_iteration_order[3]);
139*635a8641SAndroid Build Coastguard Worker         break;
140*635a8641SAndroid Build Coastguard Worker       case 2:
141*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(ids_in_iteration_order[4], iter.GetCurrentKey());
142*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(objs_in_iteration_order[4], iter.GetCurrentValue());
143*635a8641SAndroid Build Coastguard Worker         map.Remove(ids_in_iteration_order[0]);
144*635a8641SAndroid Build Coastguard Worker         break;
145*635a8641SAndroid Build Coastguard Worker       default:
146*635a8641SAndroid Build Coastguard Worker         FAIL() << "should not have that many elements";
147*635a8641SAndroid Build Coastguard Worker         break;
148*635a8641SAndroid Build Coastguard Worker     }
149*635a8641SAndroid Build Coastguard Worker 
150*635a8641SAndroid Build Coastguard Worker     counter++;
151*635a8641SAndroid Build Coastguard Worker   }
152*635a8641SAndroid Build Coastguard Worker 
153*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, map.iteration_depth());
154*635a8641SAndroid Build Coastguard Worker }
155*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,CopyIterator)156*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, CopyIterator) {
157*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*> map;
158*635a8641SAndroid Build Coastguard Worker 
159*635a8641SAndroid Build Coastguard Worker   TestObject obj1;
160*635a8641SAndroid Build Coastguard Worker   TestObject obj2;
161*635a8641SAndroid Build Coastguard Worker   TestObject obj3;
162*635a8641SAndroid Build Coastguard Worker 
163*635a8641SAndroid Build Coastguard Worker   map.Add(&obj1);
164*635a8641SAndroid Build Coastguard Worker   map.Add(&obj2);
165*635a8641SAndroid Build Coastguard Worker   map.Add(&obj3);
166*635a8641SAndroid Build Coastguard Worker 
167*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, map.iteration_depth());
168*635a8641SAndroid Build Coastguard Worker 
169*635a8641SAndroid Build Coastguard Worker   {
170*635a8641SAndroid Build Coastguard Worker     IDMap<TestObject*>::const_iterator iter1(&map);
171*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(1, map.iteration_depth());
172*635a8641SAndroid Build Coastguard Worker 
173*635a8641SAndroid Build Coastguard Worker     // Make sure that copying the iterator correctly increments
174*635a8641SAndroid Build Coastguard Worker     // map's iteration depth.
175*635a8641SAndroid Build Coastguard Worker     IDMap<TestObject*>::const_iterator iter2(iter1);
176*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(2, map.iteration_depth());
177*635a8641SAndroid Build Coastguard Worker   }
178*635a8641SAndroid Build Coastguard Worker 
179*635a8641SAndroid Build Coastguard Worker   // Make sure after destroying all iterators the map's iteration depth
180*635a8641SAndroid Build Coastguard Worker   // returns to initial state.
181*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, map.iteration_depth());
182*635a8641SAndroid Build Coastguard Worker }
183*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,AssignIterator)184*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, AssignIterator) {
185*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*> map;
186*635a8641SAndroid Build Coastguard Worker 
187*635a8641SAndroid Build Coastguard Worker   TestObject obj1;
188*635a8641SAndroid Build Coastguard Worker   TestObject obj2;
189*635a8641SAndroid Build Coastguard Worker   TestObject obj3;
190*635a8641SAndroid Build Coastguard Worker 
191*635a8641SAndroid Build Coastguard Worker   map.Add(&obj1);
192*635a8641SAndroid Build Coastguard Worker   map.Add(&obj2);
193*635a8641SAndroid Build Coastguard Worker   map.Add(&obj3);
194*635a8641SAndroid Build Coastguard Worker 
195*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, map.iteration_depth());
196*635a8641SAndroid Build Coastguard Worker 
197*635a8641SAndroid Build Coastguard Worker   {
198*635a8641SAndroid Build Coastguard Worker     IDMap<TestObject*>::const_iterator iter1(&map);
199*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(1, map.iteration_depth());
200*635a8641SAndroid Build Coastguard Worker 
201*635a8641SAndroid Build Coastguard Worker     IDMap<TestObject*>::const_iterator iter2(&map);
202*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(2, map.iteration_depth());
203*635a8641SAndroid Build Coastguard Worker 
204*635a8641SAndroid Build Coastguard Worker     // Make sure that assigning the iterator correctly updates
205*635a8641SAndroid Build Coastguard Worker     // map's iteration depth (-1 for destruction, +1 for assignment).
206*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(2, map.iteration_depth());
207*635a8641SAndroid Build Coastguard Worker   }
208*635a8641SAndroid Build Coastguard Worker 
209*635a8641SAndroid Build Coastguard Worker   // Make sure after destroying all iterators the map's iteration depth
210*635a8641SAndroid Build Coastguard Worker   // returns to initial state.
211*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, map.iteration_depth());
212*635a8641SAndroid Build Coastguard Worker }
213*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,IteratorRemainsValidWhenClearing)214*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, IteratorRemainsValidWhenClearing) {
215*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*> map;
216*635a8641SAndroid Build Coastguard Worker 
217*635a8641SAndroid Build Coastguard Worker   const int kCount = 5;
218*635a8641SAndroid Build Coastguard Worker   TestObject obj[kCount];
219*635a8641SAndroid Build Coastguard Worker 
220*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kCount; i++)
221*635a8641SAndroid Build Coastguard Worker     map.Add(&obj[i]);
222*635a8641SAndroid Build Coastguard Worker 
223*635a8641SAndroid Build Coastguard Worker   // IDMap has no predictable iteration order.
224*635a8641SAndroid Build Coastguard Worker   int32_t ids_in_iteration_order[kCount];
225*635a8641SAndroid Build Coastguard Worker   const TestObject* objs_in_iteration_order[kCount];
226*635a8641SAndroid Build Coastguard Worker   int counter = 0;
227*635a8641SAndroid Build Coastguard Worker   for (IDMap<TestObject*>::const_iterator iter(&map); !iter.IsAtEnd();
228*635a8641SAndroid Build Coastguard Worker        iter.Advance()) {
229*635a8641SAndroid Build Coastguard Worker     ids_in_iteration_order[counter] = iter.GetCurrentKey();
230*635a8641SAndroid Build Coastguard Worker     objs_in_iteration_order[counter] = iter.GetCurrentValue();
231*635a8641SAndroid Build Coastguard Worker     counter++;
232*635a8641SAndroid Build Coastguard Worker   }
233*635a8641SAndroid Build Coastguard Worker 
234*635a8641SAndroid Build Coastguard Worker   counter = 0;
235*635a8641SAndroid Build Coastguard Worker   for (IDMap<TestObject*>::const_iterator iter(&map); !iter.IsAtEnd();
236*635a8641SAndroid Build Coastguard Worker        iter.Advance()) {
237*635a8641SAndroid Build Coastguard Worker     switch (counter) {
238*635a8641SAndroid Build Coastguard Worker       case 0:
239*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(ids_in_iteration_order[0], iter.GetCurrentKey());
240*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(objs_in_iteration_order[0], iter.GetCurrentValue());
241*635a8641SAndroid Build Coastguard Worker         break;
242*635a8641SAndroid Build Coastguard Worker       case 1:
243*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(ids_in_iteration_order[1], iter.GetCurrentKey());
244*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(objs_in_iteration_order[1], iter.GetCurrentValue());
245*635a8641SAndroid Build Coastguard Worker         map.Clear();
246*635a8641SAndroid Build Coastguard Worker         EXPECT_TRUE(map.IsEmpty());
247*635a8641SAndroid Build Coastguard Worker         EXPECT_EQ(0U, map.size());
248*635a8641SAndroid Build Coastguard Worker         break;
249*635a8641SAndroid Build Coastguard Worker       default:
250*635a8641SAndroid Build Coastguard Worker         FAIL() << "should not have that many elements";
251*635a8641SAndroid Build Coastguard Worker         break;
252*635a8641SAndroid Build Coastguard Worker     }
253*635a8641SAndroid Build Coastguard Worker     counter++;
254*635a8641SAndroid Build Coastguard Worker   }
255*635a8641SAndroid Build Coastguard Worker 
256*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(map.IsEmpty());
257*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0U, map.size());
258*635a8641SAndroid Build Coastguard Worker }
259*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,OwningPointersDeletesThemOnRemove)260*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, OwningPointersDeletesThemOnRemove) {
261*635a8641SAndroid Build Coastguard Worker   const int kCount = 3;
262*635a8641SAndroid Build Coastguard Worker 
263*635a8641SAndroid Build Coastguard Worker   int external_del_count = 0;
264*635a8641SAndroid Build Coastguard Worker   DestructorCounter* external_obj[kCount];
265*635a8641SAndroid Build Coastguard Worker   int map_external_ids[kCount];
266*635a8641SAndroid Build Coastguard Worker 
267*635a8641SAndroid Build Coastguard Worker   int owned_del_count = 0;
268*635a8641SAndroid Build Coastguard Worker   int map_owned_ids[kCount];
269*635a8641SAndroid Build Coastguard Worker 
270*635a8641SAndroid Build Coastguard Worker   IDMap<DestructorCounter*> map_external;
271*635a8641SAndroid Build Coastguard Worker   IDMap<std::unique_ptr<DestructorCounter>> map_owned;
272*635a8641SAndroid Build Coastguard Worker 
273*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kCount; ++i) {
274*635a8641SAndroid Build Coastguard Worker     external_obj[i] = new DestructorCounter(&external_del_count);
275*635a8641SAndroid Build Coastguard Worker     map_external_ids[i] = map_external.Add(external_obj[i]);
276*635a8641SAndroid Build Coastguard Worker 
277*635a8641SAndroid Build Coastguard Worker     map_owned_ids[i] =
278*635a8641SAndroid Build Coastguard Worker         map_owned.Add(std::make_unique<DestructorCounter>(&owned_del_count));
279*635a8641SAndroid Build Coastguard Worker   }
280*635a8641SAndroid Build Coastguard Worker 
281*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kCount; ++i) {
282*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(external_del_count, 0);
283*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(owned_del_count, i);
284*635a8641SAndroid Build Coastguard Worker 
285*635a8641SAndroid Build Coastguard Worker     map_external.Remove(map_external_ids[i]);
286*635a8641SAndroid Build Coastguard Worker     map_owned.Remove(map_owned_ids[i]);
287*635a8641SAndroid Build Coastguard Worker   }
288*635a8641SAndroid Build Coastguard Worker 
289*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kCount; ++i) {
290*635a8641SAndroid Build Coastguard Worker     delete external_obj[i];
291*635a8641SAndroid Build Coastguard Worker   }
292*635a8641SAndroid Build Coastguard Worker 
293*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(external_del_count, kCount);
294*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(owned_del_count, kCount);
295*635a8641SAndroid Build Coastguard Worker }
296*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,OwningPointersDeletesThemOnClear)297*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, OwningPointersDeletesThemOnClear) {
298*635a8641SAndroid Build Coastguard Worker   const int kCount = 3;
299*635a8641SAndroid Build Coastguard Worker 
300*635a8641SAndroid Build Coastguard Worker   int external_del_count = 0;
301*635a8641SAndroid Build Coastguard Worker   DestructorCounter* external_obj[kCount];
302*635a8641SAndroid Build Coastguard Worker 
303*635a8641SAndroid Build Coastguard Worker   int owned_del_count = 0;
304*635a8641SAndroid Build Coastguard Worker 
305*635a8641SAndroid Build Coastguard Worker   IDMap<DestructorCounter*> map_external;
306*635a8641SAndroid Build Coastguard Worker   IDMap<std::unique_ptr<DestructorCounter>> map_owned;
307*635a8641SAndroid Build Coastguard Worker 
308*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kCount; ++i) {
309*635a8641SAndroid Build Coastguard Worker     external_obj[i] = new DestructorCounter(&external_del_count);
310*635a8641SAndroid Build Coastguard Worker     map_external.Add(external_obj[i]);
311*635a8641SAndroid Build Coastguard Worker 
312*635a8641SAndroid Build Coastguard Worker     map_owned.Add(std::make_unique<DestructorCounter>(&owned_del_count));
313*635a8641SAndroid Build Coastguard Worker   }
314*635a8641SAndroid Build Coastguard Worker 
315*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(external_del_count, 0);
316*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(owned_del_count, 0);
317*635a8641SAndroid Build Coastguard Worker 
318*635a8641SAndroid Build Coastguard Worker   map_external.Clear();
319*635a8641SAndroid Build Coastguard Worker   map_owned.Clear();
320*635a8641SAndroid Build Coastguard Worker 
321*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(external_del_count, 0);
322*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(owned_del_count, kCount);
323*635a8641SAndroid Build Coastguard Worker 
324*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kCount; ++i) {
325*635a8641SAndroid Build Coastguard Worker     delete external_obj[i];
326*635a8641SAndroid Build Coastguard Worker   }
327*635a8641SAndroid Build Coastguard Worker 
328*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(external_del_count, kCount);
329*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(owned_del_count, kCount);
330*635a8641SAndroid Build Coastguard Worker }
331*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,OwningPointersDeletesThemOnDestruct)332*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, OwningPointersDeletesThemOnDestruct) {
333*635a8641SAndroid Build Coastguard Worker   const int kCount = 3;
334*635a8641SAndroid Build Coastguard Worker 
335*635a8641SAndroid Build Coastguard Worker   int external_del_count = 0;
336*635a8641SAndroid Build Coastguard Worker   DestructorCounter* external_obj[kCount];
337*635a8641SAndroid Build Coastguard Worker 
338*635a8641SAndroid Build Coastguard Worker   int owned_del_count = 0;
339*635a8641SAndroid Build Coastguard Worker 
340*635a8641SAndroid Build Coastguard Worker   {
341*635a8641SAndroid Build Coastguard Worker     IDMap<DestructorCounter*> map_external;
342*635a8641SAndroid Build Coastguard Worker     IDMap<std::unique_ptr<DestructorCounter>> map_owned;
343*635a8641SAndroid Build Coastguard Worker 
344*635a8641SAndroid Build Coastguard Worker     for (int i = 0; i < kCount; ++i) {
345*635a8641SAndroid Build Coastguard Worker       external_obj[i] = new DestructorCounter(&external_del_count);
346*635a8641SAndroid Build Coastguard Worker       map_external.Add(external_obj[i]);
347*635a8641SAndroid Build Coastguard Worker 
348*635a8641SAndroid Build Coastguard Worker       map_owned.Add(std::make_unique<DestructorCounter>(&owned_del_count));
349*635a8641SAndroid Build Coastguard Worker     }
350*635a8641SAndroid Build Coastguard Worker   }
351*635a8641SAndroid Build Coastguard Worker 
352*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(external_del_count, 0);
353*635a8641SAndroid Build Coastguard Worker 
354*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kCount; ++i) {
355*635a8641SAndroid Build Coastguard Worker     delete external_obj[i];
356*635a8641SAndroid Build Coastguard Worker   }
357*635a8641SAndroid Build Coastguard Worker 
358*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(external_del_count, kCount);
359*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(owned_del_count, kCount);
360*635a8641SAndroid Build Coastguard Worker }
361*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,Int64KeyType)362*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, Int64KeyType) {
363*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*, int64_t> map;
364*635a8641SAndroid Build Coastguard Worker   TestObject obj1;
365*635a8641SAndroid Build Coastguard Worker   const int64_t kId1 = 999999999999999999;
366*635a8641SAndroid Build Coastguard Worker 
367*635a8641SAndroid Build Coastguard Worker   map.AddWithID(&obj1, kId1);
368*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj1, map.Lookup(kId1));
369*635a8641SAndroid Build Coastguard Worker 
370*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*, int64_t>::const_iterator iter(&map);
371*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(iter.IsAtEnd());
372*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kId1, iter.GetCurrentKey());
373*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(&obj1, iter.GetCurrentValue());
374*635a8641SAndroid Build Coastguard Worker   iter.Advance();
375*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(iter.IsAtEnd());
376*635a8641SAndroid Build Coastguard Worker 
377*635a8641SAndroid Build Coastguard Worker   map.Remove(kId1);
378*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(map.IsEmpty());
379*635a8641SAndroid Build Coastguard Worker }
380*635a8641SAndroid Build Coastguard Worker 
TEST(IDMapTest,RemovedValueHandling)381*635a8641SAndroid Build Coastguard Worker TEST(IDMapTest, RemovedValueHandling) {
382*635a8641SAndroid Build Coastguard Worker   TestObject obj;
383*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*> map;
384*635a8641SAndroid Build Coastguard Worker   int key = map.Add(&obj);
385*635a8641SAndroid Build Coastguard Worker 
386*635a8641SAndroid Build Coastguard Worker   IDMap<TestObject*>::iterator itr(&map);
387*635a8641SAndroid Build Coastguard Worker   map.Clear();
388*635a8641SAndroid Build Coastguard Worker   EXPECT_DCHECK_DEATH(map.Remove(key));
389*635a8641SAndroid Build Coastguard Worker   EXPECT_DCHECK_DEATH(map.Replace(key, &obj));
390*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(map.Lookup(key));
391*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(itr.IsAtEnd());
392*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(itr.GetCurrentValue());
393*635a8641SAndroid Build Coastguard Worker 
394*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(map.IsEmpty());
395*635a8641SAndroid Build Coastguard Worker   map.AddWithID(&obj, key);
396*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(1u, map.size());
397*635a8641SAndroid Build Coastguard Worker }
398*635a8641SAndroid Build Coastguard Worker 
399*635a8641SAndroid Build Coastguard Worker }  // namespace base
400