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