15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/id_map.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestObject {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DestructorCounter {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit DestructorCounter(int* counter) : counter_(counter) {}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~DestructorCounter() { ++(*counter_); }
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int* counter_;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, Basic) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<TestObject> map;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(map.IsEmpty());
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, map.size());
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj1;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj2;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 id1 = map.Add(&obj1);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(map.IsEmpty());
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, map.size());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&obj1, map.Lookup(id1));
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 id2 = map.Add(&obj2);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(map.IsEmpty());
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, map.size());
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&obj1, map.Lookup(id1));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&obj2, map.Lookup(id2));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Remove(id1);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(map.IsEmpty());
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, map.size());
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Remove(id2);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(map.IsEmpty());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, map.size());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.AddWithID(&obj1, 1);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.AddWithID(&obj2, 2);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&obj1, map.Lookup(1));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&obj2, map.Lookup(2));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, map.iteration_depth());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, IteratorRemainsValidWhenRemovingCurrentElement) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<TestObject> map;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj1;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj2;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj3;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj1);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj2);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj3);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDMap<TestObject>::const_iterator iter(&map);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, map.iteration_depth());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (!iter.IsAtEnd()) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      map.Remove(iter.GetCurrentKey());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter.Advance();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test that while an iterator is still in scope, we get the map emptiness
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // right (http://crbug.com/35571).
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(map.IsEmpty());
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0U, map.size());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(map.IsEmpty());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, map.size());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, map.iteration_depth());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, IteratorRemainsValidWhenRemovingOtherElements) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<TestObject> map;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCount = 5;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj[kCount];
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCount; i++)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    map.Add(&obj[i]);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // IDMap uses a hash_map, which has no predictable iteration order.
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32 ids_in_iteration_order[kCount];
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const TestObject* objs_in_iteration_order[kCount];
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int counter = 0;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (IDMap<TestObject>::const_iterator iter(&map);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ids_in_iteration_order[counter] = iter.GetCurrentKey();
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    objs_in_iteration_order[counter] = iter.GetCurrentValue();
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    counter++;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  counter = 0;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (IDMap<TestObject>::const_iterator iter(&map);
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, map.iteration_depth());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (counter) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 0:
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(ids_in_iteration_order[0], iter.GetCurrentKey());
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(objs_in_iteration_order[0], iter.GetCurrentValue());
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        map.Remove(ids_in_iteration_order[1]);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 1:
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(ids_in_iteration_order[2], iter.GetCurrentKey());
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(objs_in_iteration_order[2], iter.GetCurrentValue());
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        map.Remove(ids_in_iteration_order[3]);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 2:
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(ids_in_iteration_order[4], iter.GetCurrentKey());
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(objs_in_iteration_order[4], iter.GetCurrentValue());
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        map.Remove(ids_in_iteration_order[0]);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FAIL() << "should not have that many elements";
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counter++;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, map.iteration_depth());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, CopyIterator) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<TestObject> map;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj1;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj2;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj3;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj1);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj2);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj3);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, map.iteration_depth());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDMap<TestObject>::const_iterator iter1(&map);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, map.iteration_depth());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that copying the iterator correctly increments
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // map's iteration depth.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDMap<TestObject>::const_iterator iter2(iter1);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2, map.iteration_depth());
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure after destroying all iterators the map's iteration depth
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returns to initial state.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, map.iteration_depth());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, AssignIterator) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<TestObject> map;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj1;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj2;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj3;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj1);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj2);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map.Add(&obj3);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, map.iteration_depth());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDMap<TestObject>::const_iterator iter1(&map);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, map.iteration_depth());
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDMap<TestObject>::const_iterator iter2(&map);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2, map.iteration_depth());
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that assigning the iterator correctly updates
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // map's iteration depth (-1 for destruction, +1 for assignment).
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2, map.iteration_depth());
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure after destroying all iterators the map's iteration depth
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returns to initial state.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, map.iteration_depth());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, IteratorRemainsValidWhenClearing) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<TestObject> map;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCount = 5;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObject obj[kCount];
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCount; i++)
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    map.Add(&obj[i]);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // IDMap uses a hash_map, which has no predictable iteration order.
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32 ids_in_iteration_order[kCount];
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const TestObject* objs_in_iteration_order[kCount];
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int counter = 0;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (IDMap<TestObject>::const_iterator iter(&map);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ids_in_iteration_order[counter] = iter.GetCurrentKey();
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    objs_in_iteration_order[counter] = iter.GetCurrentValue();
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    counter++;
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  counter = 0;
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (IDMap<TestObject>::const_iterator iter(&map);
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (counter) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 0:
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(ids_in_iteration_order[0], iter.GetCurrentKey());
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(objs_in_iteration_order[0], iter.GetCurrentValue());
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 1:
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(ids_in_iteration_order[1], iter.GetCurrentKey());
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(objs_in_iteration_order[1], iter.GetCurrentValue());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        map.Clear();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(map.IsEmpty());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(0U, map.size());
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FAIL() << "should not have that many elements";
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counter++;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(map.IsEmpty());
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, map.size());
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, OwningPointersDeletesThemOnRemove) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCount = 3;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int external_del_count = 0;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestructorCounter* external_obj[kCount];
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int map_external_ids[kCount];
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int owned_del_count = 0;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestructorCounter* owned_obj[kCount];
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int map_owned_ids[kCount];
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<DestructorCounter> map_external;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCount; ++i) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    external_obj[i] = new DestructorCounter(&external_del_count);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    map_external_ids[i] = map_external.Add(external_obj[i]);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    owned_obj[i] = new DestructorCounter(&owned_del_count);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    map_owned_ids[i] = map_owned.Add(owned_obj[i]);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCount; ++i) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(external_del_count, 0);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(owned_del_count, i);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    map_external.Remove(map_external_ids[i]);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    map_owned.Remove(map_owned_ids[i]);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCount; ++i) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete external_obj[i];
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(external_del_count, kCount);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(owned_del_count, kCount);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, OwningPointersDeletesThemOnClear) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCount = 3;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int external_del_count = 0;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestructorCounter* external_obj[kCount];
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int owned_del_count = 0;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestructorCounter* owned_obj[kCount];
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<DestructorCounter> map_external;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCount; ++i) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    external_obj[i] = new DestructorCounter(&external_del_count);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    map_external.Add(external_obj[i]);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    owned_obj[i] = new DestructorCounter(&owned_del_count);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    map_owned.Add(owned_obj[i]);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(external_del_count, 0);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(owned_del_count, 0);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map_external.Clear();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map_owned.Clear();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(external_del_count, 0);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(owned_del_count, kCount);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCount; ++i) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete external_obj[i];
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(external_del_count, kCount);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(owned_del_count, kCount);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(IDMapTest, OwningPointersDeletesThemOnDestruct) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCount = 3;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int external_del_count = 0;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestructorCounter* external_obj[kCount];
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int owned_del_count = 0;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestructorCounter* owned_obj[kCount];
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDMap<DestructorCounter> map_external;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDMap<DestructorCounter, IDMapOwnPointer> map_owned;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < kCount; ++i) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      external_obj[i] = new DestructorCounter(&external_del_count);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      map_external.Add(external_obj[i]);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      owned_obj[i] = new DestructorCounter(&owned_del_count);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      map_owned.Add(owned_obj[i]);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(external_del_count, 0);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCount; ++i) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete external_obj[i];
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(external_del_count, kCount);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(owned_del_count, kCount);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
356