| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 23 * THE POSSIBILITY OF SUCH DAMAGE. | 23 * THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 | 27 |
| 28 #include "wtf/LinkedHashSet.h" |
| 28 #include "wtf/ListHashSet.h" | 29 #include "wtf/ListHashSet.h" |
| 29 #include "wtf/PassRefPtr.h" | 30 #include "wtf/PassRefPtr.h" |
| 30 #include "wtf/RefCounted.h" | 31 #include "wtf/RefCounted.h" |
| 31 #include "wtf/RefPtr.h" | 32 #include "wtf/RefPtr.h" |
| 32 #include <gtest/gtest.h> | 33 #include <gtest/gtest.h> |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 36 TEST(WTF, ListHashSetRemoveFirst) | 37 template<typename Set> |
| 37 { | 38 void removeFirstHelper() |
| 38 ListHashSet<int> list; | 39 { |
| 40 Set list; |
| 41 list.add(-1); |
| 42 list.add(0); |
| 39 list.add(1); | 43 list.add(1); |
| 40 list.add(2); | 44 list.add(2); |
| 41 list.add(3); | 45 list.add(3); |
| 42 | 46 |
| 43 ASSERT_EQ(1, list.first()); | 47 EXPECT_EQ(-1, list.first()); |
| 44 | 48 EXPECT_EQ(3, list.last()); |
| 45 list.removeFirst(); | 49 |
| 46 ASSERT_EQ(2, list.first()); | 50 list.removeFirst(); |
| 47 | 51 EXPECT_EQ(0, list.first()); |
| 48 list.removeFirst(); | 52 |
| 49 ASSERT_EQ(3, list.first()); | 53 list.removeLast(); |
| 50 | 54 EXPECT_EQ(2, list.last()); |
| 51 list.removeFirst(); | 55 |
| 52 ASSERT_TRUE(list.isEmpty()); | 56 list.removeFirst(); |
| 57 EXPECT_EQ(1, list.first()); |
| 58 |
| 59 list.removeFirst(); |
| 60 EXPECT_EQ(2, list.first()); |
| 61 |
| 62 list.removeFirst(); |
| 63 EXPECT_TRUE(list.isEmpty()); |
| 64 } |
| 65 |
| 66 TEST(WTF, ListHashSetRemoveFirst) |
| 67 { |
| 68 removeFirstHelper<ListHashSet<int> >(); |
| 69 } |
| 70 |
| 71 TEST(WTF, LinkedHashSetRemoveFirst) |
| 72 { |
| 73 removeFirstHelper<LinkedHashSet<int> >(); |
| 74 } |
| 75 |
| 76 template<typename Set> |
| 77 void appendOrMoveToLastNewItems() |
| 78 { |
| 79 Set list; |
| 80 typename Set::AddResult result = list.appendOrMoveToLast(1); |
| 81 EXPECT_TRUE(result.isNewEntry); |
| 82 result = list.add(2); |
| 83 EXPECT_TRUE(result.isNewEntry); |
| 84 result = list.appendOrMoveToLast(3); |
| 85 EXPECT_TRUE(result.isNewEntry); |
| 86 |
| 87 EXPECT_EQ(list.size(), 3UL); |
| 88 |
| 89 // The list should be in order 1, 2, 3. |
| 90 typename Set::iterator iterator = list.begin(); |
| 91 EXPECT_EQ(1, *iterator); |
| 92 ++iterator; |
| 93 EXPECT_EQ(2, *iterator); |
| 94 ++iterator; |
| 95 EXPECT_EQ(3, *iterator); |
| 96 ++iterator; |
| 53 } | 97 } |
| 54 | 98 |
| 55 TEST(WTF, ListHashSetAppendOrMoveToLastNewItems) | 99 TEST(WTF, ListHashSetAppendOrMoveToLastNewItems) |
| 56 { | 100 { |
| 57 ListHashSet<int> list; | 101 appendOrMoveToLastNewItems<ListHashSet<int> >(); |
| 58 ListHashSet<int>::AddResult result = list.appendOrMoveToLast(1); | 102 } |
| 59 ASSERT_TRUE(result.isNewEntry); | 103 |
| 60 result = list.add(2); | 104 TEST(WTF, LinkedHashSetAppendOrMoveToLastNewItems) |
| 61 ASSERT_TRUE(result.isNewEntry); | 105 { |
| 62 result = list.appendOrMoveToLast(3); | 106 appendOrMoveToLastNewItems<LinkedHashSet<int> >(); |
| 63 ASSERT_TRUE(result.isNewEntry); | 107 } |
| 64 | 108 |
| 65 ASSERT_EQ(list.size(), 3UL); | 109 template<typename Set> |
| 66 | 110 void appendOrMoveToLastWithDuplicates() |
| 67 // The list should be in order 1, 2, 3. | 111 { |
| 68 ListHashSet<int>::iterator iterator = list.begin(); | 112 Set list; |
| 69 ASSERT_EQ(1, *iterator); | |
| 70 ++iterator; | |
| 71 ASSERT_EQ(2, *iterator); | |
| 72 ++iterator; | |
| 73 ASSERT_EQ(3, *iterator); | |
| 74 ++iterator; | |
| 75 } | |
| 76 | |
| 77 TEST(WTF, ListHashSetAppendOrMoveToLastWithDuplicates) | |
| 78 { | |
| 79 ListHashSet<int> list; | |
| 80 | 113 |
| 81 // Add a single element twice. | 114 // Add a single element twice. |
| 82 ListHashSet<int>::AddResult result = list.add(1); | 115 typename Set::AddResult result = list.add(1); |
| 83 ASSERT_TRUE(result.isNewEntry); | 116 EXPECT_TRUE(result.isNewEntry); |
| 84 result = list.appendOrMoveToLast(1); | 117 result = list.appendOrMoveToLast(1); |
| 85 ASSERT_FALSE(result.isNewEntry); | 118 EXPECT_FALSE(result.isNewEntry); |
| 86 ASSERT_EQ(1UL, list.size()); | 119 EXPECT_EQ(1UL, list.size()); |
| 87 | 120 |
| 88 list.add(2); | 121 list.add(2); |
| 89 list.add(3); | 122 list.add(3); |
| 90 ASSERT_EQ(3UL, list.size()); | 123 EXPECT_EQ(3UL, list.size()); |
| 91 | 124 |
| 92 // Appending 2 move it to the end. | 125 // Appending 2 move it to the end. |
| 93 ASSERT_EQ(3, list.last()); | 126 EXPECT_EQ(3, list.last()); |
| 94 result = list.appendOrMoveToLast(2); | 127 result = list.appendOrMoveToLast(2); |
| 95 ASSERT_FALSE(result.isNewEntry); | 128 EXPECT_FALSE(result.isNewEntry); |
| 96 ASSERT_EQ(2, list.last()); | 129 EXPECT_EQ(2, list.last()); |
| 97 | 130 |
| 98 // Inverse the list by moving each element to end end. | 131 // Inverse the list by moving each element to end end. |
| 99 result = list.appendOrMoveToLast(3); | 132 result = list.appendOrMoveToLast(3); |
| 100 ASSERT_FALSE(result.isNewEntry); | 133 EXPECT_FALSE(result.isNewEntry); |
| 101 result = list.appendOrMoveToLast(2); | 134 result = list.appendOrMoveToLast(2); |
| 102 ASSERT_FALSE(result.isNewEntry); | 135 EXPECT_FALSE(result.isNewEntry); |
| 103 result = list.appendOrMoveToLast(1); | 136 result = list.appendOrMoveToLast(1); |
| 104 ASSERT_FALSE(result.isNewEntry); | 137 EXPECT_FALSE(result.isNewEntry); |
| 105 ASSERT_EQ(3UL, list.size()); | 138 EXPECT_EQ(3UL, list.size()); |
| 106 | 139 |
| 107 ListHashSet<int>::iterator iterator = list.begin(); | 140 typename Set::iterator iterator = list.begin(); |
| 108 ASSERT_EQ(3, *iterator); | 141 EXPECT_EQ(3, *iterator); |
| 109 ++iterator; | 142 ++iterator; |
| 110 ASSERT_EQ(2, *iterator); | 143 EXPECT_EQ(2, *iterator); |
| 111 ++iterator; | 144 ++iterator; |
| 112 ASSERT_EQ(1, *iterator); | 145 EXPECT_EQ(1, *iterator); |
| 113 ++iterator; | 146 ++iterator; |
| 114 } | 147 } |
| 115 | 148 |
| 116 TEST(WTF, ListHashSetPrependOrMoveToLastNewItems) | 149 TEST(WTF, ListHashSetAppendOrMoveToLastWithDuplicates) |
| 117 { | 150 { |
| 118 ListHashSet<int> list; | 151 appendOrMoveToLastWithDuplicates<ListHashSet<int> >(); |
| 119 ListHashSet<int>::AddResult result = list.prependOrMoveToFirst(1); | 152 } |
| 120 ASSERT_TRUE(result.isNewEntry); | 153 |
| 154 TEST(WTF, LinkedHashSetAppendOrMoveToLastWithDuplicates) |
| 155 { |
| 156 appendOrMoveToLastWithDuplicates<LinkedHashSet<int> >(); |
| 157 } |
| 158 |
| 159 template<typename Set> |
| 160 void prependOrMoveToFirstNewItems() |
| 161 { |
| 162 Set list; |
| 163 typename Set::AddResult result = list.prependOrMoveToFirst(1); |
| 164 EXPECT_TRUE(result.isNewEntry); |
| 121 result = list.add(2); | 165 result = list.add(2); |
| 122 ASSERT_TRUE(result.isNewEntry); | 166 EXPECT_TRUE(result.isNewEntry); |
| 123 result = list.prependOrMoveToFirst(3); | 167 result = list.prependOrMoveToFirst(3); |
| 124 ASSERT_TRUE(result.isNewEntry); | 168 EXPECT_TRUE(result.isNewEntry); |
| 125 | 169 |
| 126 ASSERT_EQ(list.size(), 3UL); | 170 EXPECT_EQ(list.size(), 3UL); |
| 127 | 171 |
| 128 // The list should be in order 3, 1, 2. | 172 // The list should be in order 3, 1, 2. |
| 129 ListHashSet<int>::iterator iterator = list.begin(); | 173 typename Set::iterator iterator = list.begin(); |
| 130 ASSERT_EQ(3, *iterator); | 174 EXPECT_EQ(3, *iterator); |
| 131 ++iterator; | 175 ++iterator; |
| 132 ASSERT_EQ(1, *iterator); | 176 EXPECT_EQ(1, *iterator); |
| 133 ++iterator; | 177 ++iterator; |
| 134 ASSERT_EQ(2, *iterator); | 178 EXPECT_EQ(2, *iterator); |
| 135 ++iterator; | 179 ++iterator; |
| 136 } | 180 } |
| 137 | 181 |
| 138 TEST(WTF, ListHashSetPrependOrMoveToLastWithDuplicates) | 182 TEST(WTF, ListHashSetPrependOrMoveToFirstNewItems) |
| 139 { | 183 { |
| 140 ListHashSet<int> list; | 184 prependOrMoveToFirstNewItems<ListHashSet<int> >(); |
| 185 } |
| 186 |
| 187 TEST(WTF, LinkedHashSetPrependOrMoveToFirstNewItems) |
| 188 { |
| 189 prependOrMoveToFirstNewItems<LinkedHashSet<int> >(); |
| 190 } |
| 191 |
| 192 template<typename Set> |
| 193 void prependOrMoveToLastWithDuplicates() |
| 194 { |
| 195 Set list; |
| 141 | 196 |
| 142 // Add a single element twice. | 197 // Add a single element twice. |
| 143 ListHashSet<int>::AddResult result = list.add(1); | 198 typename Set::AddResult result = list.add(1); |
| 144 ASSERT_TRUE(result.isNewEntry); | 199 EXPECT_TRUE(result.isNewEntry); |
| 145 result = list.prependOrMoveToFirst(1); | 200 result = list.prependOrMoveToFirst(1); |
| 146 ASSERT_FALSE(result.isNewEntry); | 201 EXPECT_FALSE(result.isNewEntry); |
| 147 ASSERT_EQ(1UL, list.size()); | 202 EXPECT_EQ(1UL, list.size()); |
| 148 | 203 |
| 149 list.add(2); | 204 list.add(2); |
| 150 list.add(3); | 205 list.add(3); |
| 151 ASSERT_EQ(3UL, list.size()); | 206 EXPECT_EQ(3UL, list.size()); |
| 152 | 207 |
| 153 // Prepending 2 move it to the beginning. | 208 // Prepending 2 move it to the beginning. |
| 154 ASSERT_EQ(1, list.first()); | 209 EXPECT_EQ(1, list.first()); |
| 155 result = list.prependOrMoveToFirst(2); | 210 result = list.prependOrMoveToFirst(2); |
| 156 ASSERT_FALSE(result.isNewEntry); | 211 EXPECT_FALSE(result.isNewEntry); |
| 157 ASSERT_EQ(2, list.first()); | 212 EXPECT_EQ(2, list.first()); |
| 158 | 213 |
| 159 // Inverse the list by moving each element to the first position. | 214 // Inverse the list by moving each element to the first position. |
| 160 result = list.prependOrMoveToFirst(1); | 215 result = list.prependOrMoveToFirst(1); |
| 161 ASSERT_FALSE(result.isNewEntry); | 216 EXPECT_FALSE(result.isNewEntry); |
| 162 result = list.prependOrMoveToFirst(2); | 217 result = list.prependOrMoveToFirst(2); |
| 163 ASSERT_FALSE(result.isNewEntry); | 218 EXPECT_FALSE(result.isNewEntry); |
| 164 result = list.prependOrMoveToFirst(3); | 219 result = list.prependOrMoveToFirst(3); |
| 165 ASSERT_FALSE(result.isNewEntry); | 220 EXPECT_FALSE(result.isNewEntry); |
| 166 ASSERT_EQ(3UL, list.size()); | 221 EXPECT_EQ(3UL, list.size()); |
| 167 | 222 |
| 168 ListHashSet<int>::iterator iterator = list.begin(); | 223 typename Set::iterator iterator = list.begin(); |
| 169 ASSERT_EQ(3, *iterator); | 224 EXPECT_EQ(3, *iterator); |
| 170 ++iterator; | 225 ++iterator; |
| 171 ASSERT_EQ(2, *iterator); | 226 EXPECT_EQ(2, *iterator); |
| 172 ++iterator; | 227 ++iterator; |
| 173 ASSERT_EQ(1, *iterator); | 228 EXPECT_EQ(1, *iterator); |
| 174 ++iterator; | 229 ++iterator; |
| 230 } |
| 231 |
| 232 TEST(WTF, ListHashSetPrependOrMoveToLastWithDuplicates) |
| 233 { |
| 234 prependOrMoveToLastWithDuplicates<ListHashSet<int> >(); |
| 235 } |
| 236 |
| 237 TEST(WTF, LinkedHashSetPrependOrMoveToLastWithDuplicates) |
| 238 { |
| 239 prependOrMoveToLastWithDuplicates<LinkedHashSet<int> >(); |
| 175 } | 240 } |
| 176 | 241 |
| 177 class DummyRefCounted: public WTF::RefCounted<DummyRefCounted> { | 242 class DummyRefCounted: public WTF::RefCounted<DummyRefCounted> { |
| 178 public: | 243 public: |
| 179 DummyRefCounted(bool& isDeleted) : m_isDeleted(isDeleted) { m_isDeleted = fa
lse; } | 244 DummyRefCounted(bool& isDeleted) : m_isDeleted(isDeleted) { m_isDeleted = fa
lse; } |
| 180 ~DummyRefCounted() { m_isDeleted = true; } | 245 ~DummyRefCounted() { m_isDeleted = true; } |
| 181 void ref() | 246 void ref() |
| 182 { | 247 { |
| 183 WTF::RefCounted<DummyRefCounted>::ref(); | 248 WTF::RefCounted<DummyRefCounted>::ref(); |
| 184 ++m_refInvokesCount; | 249 ++m_refInvokesCount; |
| 185 } | 250 } |
| 186 | 251 |
| 187 static int m_refInvokesCount; | 252 static int m_refInvokesCount; |
| 188 | 253 |
| 189 private: | 254 private: |
| 190 bool& m_isDeleted; | 255 bool& m_isDeleted; |
| 191 }; | 256 }; |
| 192 | 257 |
| 193 int DummyRefCounted::m_refInvokesCount = 0; | 258 int DummyRefCounted::m_refInvokesCount = 0; |
| 194 | 259 |
| 260 template<typename Set> |
| 261 void withRefPtr() |
| 262 { |
| 263 bool isDeleted; |
| 264 DummyRefCounted::m_refInvokesCount = 0; |
| 265 RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted)); |
| 266 EXPECT_EQ(0, DummyRefCounted::m_refInvokesCount); |
| 267 |
| 268 Set set; |
| 269 set.add(ptr); |
| 270 // Referenced only once (to store a copy in the container). |
| 271 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 272 EXPECT_EQ(ptr, set.first()); |
| 273 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 274 |
| 275 DummyRefCounted* rawPtr = ptr.get(); |
| 276 |
| 277 EXPECT_TRUE(set.contains(ptr)); |
| 278 EXPECT_TRUE(set.contains(rawPtr)); |
| 279 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 280 |
| 281 ptr.clear(); |
| 282 EXPECT_FALSE(isDeleted); |
| 283 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 284 |
| 285 set.remove(rawPtr); |
| 286 EXPECT_TRUE(isDeleted); |
| 287 |
| 288 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 289 } |
| 290 |
| 195 TEST(WTF, ListHashSetWithRefPtr) | 291 TEST(WTF, ListHashSetWithRefPtr) |
| 196 { | 292 { |
| 197 bool isDeleted; | 293 withRefPtr<ListHashSet<RefPtr<DummyRefCounted> > >(); |
| 294 } |
| 295 |
| 296 TEST(WTF, LinkedHashSetWithRefPtr) |
| 297 { |
| 298 withRefPtr<LinkedHashSet<RefPtr<DummyRefCounted> > >(); |
| 299 } |
| 300 |
| 301 template<typename Set, typename SetRef, typename Iterator> |
| 302 void findHelper() |
| 303 { |
| 304 Set set; |
| 305 set.add(-1); |
| 306 set.add(0); |
| 307 set.add(1); |
| 308 set.add(2); |
| 309 set.add(3); |
| 310 |
| 311 SetRef ref = set; |
| 312 Iterator it = ref.find(2); |
| 313 EXPECT_EQ(2, *it); |
| 314 ++it; |
| 315 EXPECT_EQ(3, *it); |
| 316 --it; |
| 317 --it; |
| 318 EXPECT_EQ(1, *it); |
| 319 } |
| 320 |
| 321 TEST(WTF, ListHashSetFind) |
| 322 { |
| 323 findHelper<ListHashSet<int>, const ListHashSet<int>&, ListHashSet<int>::cons
t_iterator>(); |
| 324 findHelper<ListHashSet<int>, ListHashSet<int>&, ListHashSet<int>::iterator>(
); |
| 325 } |
| 326 |
| 327 TEST(WTF, LinkedHashSetFind) |
| 328 { |
| 329 findHelper<LinkedHashSet<int>, const LinkedHashSet<int>&, LinkedHashSet<int>
::const_iterator>(); |
| 330 findHelper<LinkedHashSet<int>, LinkedHashSet<int>&, LinkedHashSet<int>::iter
ator>(); |
| 331 } |
| 332 |
| 333 template<typename Set> |
| 334 void insertBeforeHelper(bool canModifyWhileIterating) |
| 335 { |
| 336 Set set; |
| 337 set.add(-1); |
| 338 set.add(0); |
| 339 set.add(2); |
| 340 set.add(3); |
| 341 |
| 342 typename Set::iterator it = set.find(2); |
| 343 EXPECT_EQ(2, *it); |
| 344 set.insertBefore(it, 1); |
| 345 if (!canModifyWhileIterating) |
| 346 it = set.find(2); |
| 347 ++it; |
| 348 EXPECT_EQ(3, *it); |
| 349 EXPECT_EQ(5u, set.size()); |
| 350 --it; |
| 351 --it; |
| 352 EXPECT_EQ(1, *it); |
| 353 if (canModifyWhileIterating) { |
| 354 set.remove(-1); |
| 355 set.remove(0); |
| 356 set.remove(2); |
| 357 set.remove(3); |
| 358 EXPECT_EQ(1u, set.size()); |
| 359 EXPECT_EQ(1, *it); |
| 360 ++it; |
| 361 EXPECT_EQ(it, set.end()); |
| 362 --it; |
| 363 EXPECT_EQ(1, *it); |
| 364 set.insertBefore(it, -1); |
| 365 set.insertBefore(it, 0); |
| 366 set.add(2); |
| 367 set.add(3); |
| 368 } |
| 369 set.insertBefore(2, 42); |
| 370 set.insertBefore(-1, 103); |
| 371 EXPECT_EQ(103, set.first()); |
| 372 if (!canModifyWhileIterating) |
| 373 it = set.find(1); |
| 374 ++it; |
| 375 EXPECT_EQ(42, *it); |
| 376 EXPECT_EQ(7u, set.size()); |
| 377 } |
| 378 |
| 379 TEST(WTF, ListHashSetInsertBefore) |
| 380 { |
| 381 insertBeforeHelper<ListHashSet<int> >(true); |
| 382 } |
| 383 |
| 384 TEST(WTF, LinkedHashSetInsertBefore) |
| 385 { |
| 386 insertBeforeHelper<LinkedHashSet<int> >(false); |
| 387 } |
| 388 |
| 389 template<typename Set> |
| 390 void addReturnIterator(bool canModifyWhileIterating) |
| 391 { |
| 392 Set set; |
| 393 set.add(-1); |
| 394 set.add(0); |
| 395 set.add(1); |
| 396 set.add(2); |
| 397 |
| 398 typename Set::iterator it = set.addReturnIterator(3); |
| 399 EXPECT_EQ(3, *it); |
| 400 --it; |
| 401 EXPECT_EQ(2, *it); |
| 402 EXPECT_EQ(5u, set.size()); |
| 403 --it; |
| 404 EXPECT_EQ(1, *it); |
| 405 --it; |
| 406 EXPECT_EQ(0, *it); |
| 407 it = set.addReturnIterator(4); |
| 408 if (canModifyWhileIterating) { |
| 409 set.remove(3); |
| 410 set.remove(2); |
| 411 set.remove(1); |
| 412 set.remove(0); |
| 413 set.remove(-1); |
| 414 EXPECT_EQ(1u, set.size()); |
| 415 } |
| 416 EXPECT_EQ(4, *it); |
| 417 ++it; |
| 418 EXPECT_EQ(it, set.end()); |
| 419 --it; |
| 420 EXPECT_EQ(4, *it); |
| 421 if (canModifyWhileIterating) { |
| 422 set.insertBefore(it, -1); |
| 423 set.insertBefore(it, 0); |
| 424 set.insertBefore(it, 1); |
| 425 set.insertBefore(it, 2); |
| 426 set.insertBefore(it, 3); |
| 427 } |
| 428 EXPECT_EQ(6u, set.size()); |
| 429 it = set.addReturnIterator(5); |
| 430 EXPECT_EQ(7u, set.size()); |
| 431 set.remove(it); |
| 432 EXPECT_EQ(6u, set.size()); |
| 433 EXPECT_EQ(4, set.last()); |
| 434 } |
| 435 |
| 436 TEST(WTF, ListHashSetAddReturnIterator) |
| 437 { |
| 438 addReturnIterator<ListHashSet<int> >(true); |
| 439 } |
| 440 |
| 441 TEST(WTF, LinkedHashSetAddReturnIterator) |
| 442 { |
| 443 addReturnIterator<LinkedHashSet<int> >(false); |
| 444 } |
| 445 |
| 446 template<typename Set> |
| 447 void excerciseValuePeekInType() |
| 448 { |
| 449 Set set; |
| 450 bool isDeleted = false; |
| 451 bool isDeleted2 = false; |
| 452 |
| 198 RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted)); | 453 RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted)); |
| 199 ASSERT_EQ(0, DummyRefCounted::m_refInvokesCount); | 454 RefPtr<DummyRefCounted> ptr2 = adoptRef(new DummyRefCounted(isDeleted2)); |
| 200 | 455 |
| 201 ListHashSet<RefPtr<DummyRefCounted> > list; | 456 typename Set::AddResult addResult = set.add(ptr); |
| 202 list.add(ptr); | 457 EXPECT_TRUE(addResult.isNewEntry); |
| 203 // Referenced only once (to store a copy in the container). | 458 set.find(ptr); |
| 204 ASSERT_EQ(1, DummyRefCounted::m_refInvokesCount); | 459 const Set& constSet(set); |
| 205 ASSERT_EQ(ptr, list.first()); | 460 constSet.find(ptr); |
| 206 | 461 EXPECT_TRUE(set.contains(ptr)); |
| 207 DummyRefCounted* rawPtr = ptr.get(); | 462 typename Set::iterator it = set.addReturnIterator(ptr); |
| 208 | 463 set.appendOrMoveToLast(ptr); |
| 209 ASSERT_TRUE(list.contains(ptr)); | 464 set.prependOrMoveToFirst(ptr); |
| 210 ASSERT_TRUE(list.contains(rawPtr)); | 465 set.insertBefore(ptr, ptr); |
| 211 | 466 set.insertBefore(it, ptr); |
| 467 EXPECT_EQ(1u, set.size()); |
| 468 set.add(ptr2); |
| 469 ptr2.clear(); |
| 470 set.remove(ptr); |
| 471 |
| 472 EXPECT_FALSE(isDeleted); |
| 212 ptr.clear(); | 473 ptr.clear(); |
| 213 ASSERT_FALSE(isDeleted); | 474 EXPECT_TRUE(isDeleted); |
| 214 | 475 |
| 215 list.remove(rawPtr); | 476 EXPECT_FALSE(isDeleted2); |
| 216 ASSERT_TRUE(isDeleted); | 477 set.removeFirst(); |
| 217 | 478 EXPECT_TRUE(isDeleted2); |
| 218 ASSERT_EQ(1, DummyRefCounted::m_refInvokesCount); | 479 |
| 480 EXPECT_EQ(0u, set.size()); |
| 481 } |
| 482 |
| 483 TEST(WTF, ListHashSetExcerciseValuePeekInType) |
| 484 { |
| 485 excerciseValuePeekInType<ListHashSet<RefPtr<DummyRefCounted> > >(); |
| 486 } |
| 487 |
| 488 TEST(WTF, LinkedHashSetExcerciseValuePeekInType) |
| 489 { |
| 490 excerciseValuePeekInType<LinkedHashSet<RefPtr<DummyRefCounted> > >(); |
| 219 } | 491 } |
| 220 | 492 |
| 221 } // namespace | 493 } // namespace |
| OLD | NEW |