| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/containers/scoped_ptr_map.h" | |
| 6 | |
| 7 #include <functional> | |
| 8 #include <map> | |
| 9 #include <utility> | |
| 10 | |
| 11 #include "base/bind.h" | |
| 12 #include "base/callback.h" | |
| 13 #include "base/memory/scoped_ptr.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 | |
| 16 namespace base { | |
| 17 namespace { | |
| 18 | |
| 19 namespace namespace_with_ignore_result { | |
| 20 | |
| 21 class Value {}; | |
| 22 | |
| 23 template <typename T> | |
| 24 void ignore_result(const T&) {} | |
| 25 | |
| 26 } // namespace namespace_with_ignore_result | |
| 27 | |
| 28 // A ScopedDestroyer sets a Boolean to true upon destruction. | |
| 29 class ScopedDestroyer { | |
| 30 public: | |
| 31 ScopedDestroyer(bool* destroyed) : destroyed_(destroyed) { | |
| 32 *destroyed_ = false; | |
| 33 } | |
| 34 | |
| 35 ~ScopedDestroyer() { *destroyed_ = true; } | |
| 36 | |
| 37 private: | |
| 38 bool* destroyed_; | |
| 39 }; | |
| 40 | |
| 41 TEST(ScopedPtrMapTest, Insert) { | |
| 42 bool destroyed1 = false; | |
| 43 bool destroyed2 = false; | |
| 44 { | |
| 45 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 46 | |
| 47 // Insert to new key. | |
| 48 ScopedDestroyer* elem1 = new ScopedDestroyer(&destroyed1); | |
| 49 EXPECT_FALSE(destroyed1); | |
| 50 EXPECT_TRUE(scoped_map.insert(0, make_scoped_ptr(elem1)).second); | |
| 51 EXPECT_EQ(elem1, scoped_map.find(0)->second); | |
| 52 EXPECT_FALSE(destroyed1); | |
| 53 | |
| 54 // Insert to existing key. | |
| 55 ScopedDestroyer* elem2 = new ScopedDestroyer(&destroyed2); | |
| 56 EXPECT_FALSE(destroyed2); | |
| 57 EXPECT_FALSE(scoped_map.insert(0, make_scoped_ptr(elem2)).second); | |
| 58 EXPECT_EQ(elem1, scoped_map.find(0)->second); | |
| 59 | |
| 60 EXPECT_FALSE(destroyed1); | |
| 61 EXPECT_TRUE(destroyed2); | |
| 62 } | |
| 63 EXPECT_TRUE(destroyed1); | |
| 64 } | |
| 65 | |
| 66 TEST(ScopedPtrMapTest, Set) { | |
| 67 bool destroyed1 = false; | |
| 68 bool destroyed2 = false; | |
| 69 { | |
| 70 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 71 | |
| 72 // Set a new key. | |
| 73 ScopedDestroyer* elem1 = new ScopedDestroyer(&destroyed1); | |
| 74 EXPECT_FALSE(destroyed1); | |
| 75 scoped_map.set(0, make_scoped_ptr(elem1)); | |
| 76 EXPECT_EQ(elem1, scoped_map.find(0)->second); | |
| 77 EXPECT_FALSE(destroyed1); | |
| 78 | |
| 79 // Set to replace an existing key. | |
| 80 ScopedDestroyer* elem2 = new ScopedDestroyer(&destroyed2); | |
| 81 EXPECT_FALSE(destroyed2); | |
| 82 scoped_map.set(0, make_scoped_ptr(elem2)); | |
| 83 EXPECT_EQ(elem2, scoped_map.find(0)->second); | |
| 84 | |
| 85 EXPECT_TRUE(destroyed1); | |
| 86 EXPECT_FALSE(destroyed2); | |
| 87 } | |
| 88 EXPECT_TRUE(destroyed1); | |
| 89 EXPECT_TRUE(destroyed2); | |
| 90 } | |
| 91 | |
| 92 TEST(ScopedPtrMapTest, EraseIterator) { | |
| 93 bool destroyed = false; | |
| 94 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 95 scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); | |
| 96 EXPECT_FALSE(destroyed); | |
| 97 scoped_map.erase(scoped_map.find(0)); | |
| 98 EXPECT_TRUE(destroyed); | |
| 99 EXPECT_TRUE(scoped_map.empty()); | |
| 100 } | |
| 101 | |
| 102 TEST(ScopedPtrMapTest, EraseKey) { | |
| 103 bool destroyed = false; | |
| 104 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 105 scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); | |
| 106 EXPECT_FALSE(destroyed); | |
| 107 EXPECT_EQ(1u, scoped_map.erase(0)); | |
| 108 EXPECT_TRUE(destroyed); | |
| 109 EXPECT_TRUE(scoped_map.empty()); | |
| 110 | |
| 111 // Test erase of a non-existent key. | |
| 112 EXPECT_EQ(0u, scoped_map.erase(7)); | |
| 113 } | |
| 114 | |
| 115 TEST(ScopedPtrMapTest, EraseRange) { | |
| 116 bool destroyed1 = false; | |
| 117 bool destroyed2 = false; | |
| 118 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 119 | |
| 120 scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed1))); | |
| 121 EXPECT_FALSE(destroyed1); | |
| 122 | |
| 123 scoped_map.insert(1, make_scoped_ptr(new ScopedDestroyer(&destroyed2))); | |
| 124 EXPECT_FALSE(destroyed2); | |
| 125 | |
| 126 scoped_map.erase(scoped_map.find(0), scoped_map.end()); | |
| 127 EXPECT_TRUE(destroyed1); | |
| 128 EXPECT_TRUE(destroyed2); | |
| 129 EXPECT_TRUE(scoped_map.empty()); | |
| 130 } | |
| 131 | |
| 132 TEST(ScopedPtrMapTest, TakeAndErase) { | |
| 133 bool destroyed = false; | |
| 134 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 135 ScopedDestroyer* elem = new ScopedDestroyer(&destroyed); | |
| 136 scoped_map.insert(0, make_scoped_ptr(elem)); | |
| 137 EXPECT_EQ(elem, scoped_map.find(0)->second); | |
| 138 EXPECT_FALSE(destroyed); | |
| 139 scoped_ptr<ScopedDestroyer> object = scoped_map.take_and_erase(0); | |
| 140 EXPECT_EQ(elem, object.get()); | |
| 141 EXPECT_FALSE(destroyed); | |
| 142 EXPECT_TRUE(scoped_map.empty()); | |
| 143 object.reset(); | |
| 144 EXPECT_TRUE(destroyed); | |
| 145 } | |
| 146 | |
| 147 TEST(ScopedPtrMapTest, Clear) { | |
| 148 bool destroyed = false; | |
| 149 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 150 scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); | |
| 151 EXPECT_FALSE(destroyed); | |
| 152 scoped_map.clear(); | |
| 153 EXPECT_TRUE(destroyed); | |
| 154 EXPECT_TRUE(scoped_map.empty()); | |
| 155 } | |
| 156 | |
| 157 TEST(ScopedPtrMapTest, Compare) { | |
| 158 // Construct a ScopedPtrMap with a custom comparison function. | |
| 159 ScopedPtrMap<int, scoped_ptr<int>, std::greater<int>> scoped_map1; | |
| 160 scoped_map1.insert(0, make_scoped_ptr(new int(0))); | |
| 161 scoped_map1.insert(1, make_scoped_ptr(new int(0))); | |
| 162 | |
| 163 auto it = scoped_map1.begin(); | |
| 164 EXPECT_EQ(1, it->first); | |
| 165 ++it; | |
| 166 EXPECT_EQ(0, it->first); | |
| 167 | |
| 168 // Test the move constructor. | |
| 169 ScopedPtrMap<int, scoped_ptr<int>, std::greater<int>> scoped_map2( | |
| 170 std::move(scoped_map1)); | |
| 171 EXPECT_EQ(2u, scoped_map2.size()); | |
| 172 EXPECT_TRUE(scoped_map1.empty()); | |
| 173 | |
| 174 // Test move assignment. | |
| 175 scoped_map1 = std::move(scoped_map2); | |
| 176 EXPECT_EQ(2u, scoped_map1.size()); | |
| 177 EXPECT_TRUE(scoped_map2.empty()); | |
| 178 | |
| 179 // Test swap. | |
| 180 scoped_map2.swap(scoped_map1); | |
| 181 EXPECT_EQ(2u, scoped_map2.size()); | |
| 182 EXPECT_TRUE(scoped_map1.empty()); | |
| 183 } | |
| 184 | |
| 185 TEST(ScopedPtrMapTest, Scope) { | |
| 186 bool destroyed = false; | |
| 187 { | |
| 188 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 189 scoped_map.insert(0, make_scoped_ptr(new ScopedDestroyer(&destroyed))); | |
| 190 EXPECT_FALSE(destroyed); | |
| 191 } | |
| 192 EXPECT_TRUE(destroyed); | |
| 193 } | |
| 194 | |
| 195 TEST(ScopedPtrMapTest, MoveConstruct) { | |
| 196 bool destroyed = false; | |
| 197 { | |
| 198 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 199 ScopedDestroyer* elem = new ScopedDestroyer(&destroyed); | |
| 200 scoped_map.insert(0, make_scoped_ptr(elem)); | |
| 201 EXPECT_EQ(elem, scoped_map.find(0)->second); | |
| 202 EXPECT_FALSE(destroyed); | |
| 203 EXPECT_FALSE(scoped_map.empty()); | |
| 204 | |
| 205 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map_copy( | |
| 206 std::move(scoped_map)); | |
| 207 EXPECT_TRUE(scoped_map.empty()); | |
| 208 EXPECT_FALSE(scoped_map_copy.empty()); | |
| 209 EXPECT_EQ(elem, scoped_map_copy.find(0)->second); | |
| 210 EXPECT_FALSE(destroyed); | |
| 211 } | |
| 212 EXPECT_TRUE(destroyed); | |
| 213 } | |
| 214 | |
| 215 TEST(ScopedPtrMapTest, MoveAssign) { | |
| 216 bool destroyed = false; | |
| 217 { | |
| 218 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map; | |
| 219 ScopedDestroyer* elem = new ScopedDestroyer(&destroyed); | |
| 220 scoped_map.insert(0, make_scoped_ptr(elem)); | |
| 221 EXPECT_EQ(elem, scoped_map.find(0)->second); | |
| 222 EXPECT_FALSE(destroyed); | |
| 223 EXPECT_FALSE(scoped_map.empty()); | |
| 224 | |
| 225 ScopedPtrMap<int, scoped_ptr<ScopedDestroyer>> scoped_map_assign; | |
| 226 scoped_map_assign = std::move(scoped_map); | |
| 227 EXPECT_TRUE(scoped_map.empty()); | |
| 228 EXPECT_FALSE(scoped_map_assign.empty()); | |
| 229 EXPECT_EQ(elem, scoped_map_assign.find(0)->second); | |
| 230 EXPECT_FALSE(destroyed); | |
| 231 } | |
| 232 EXPECT_TRUE(destroyed); | |
| 233 } | |
| 234 | |
| 235 // Test that using a value type from a namespace containing an ignore_result | |
| 236 // function compiles correctly. | |
| 237 TEST(ScopedPtrMapTest, IgnoreResultCompile) { | |
| 238 ScopedPtrMap<int, scoped_ptr<namespace_with_ignore_result::Value>> scoped_map; | |
| 239 scoped_map.insert(1, | |
| 240 make_scoped_ptr(new namespace_with_ignore_result::Value)); | |
| 241 } | |
| 242 | |
| 243 } // namespace | |
| 244 } // namespace base | |
| OLD | NEW |