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 removeFirstHelper<ListHashSet<int, 1> >(); |
| 70 } |
| 71 |
| 72 TEST(WTF, LinkedHashSetRemoveFirst) |
| 73 { |
| 74 removeFirstHelper<LinkedHashSet<int> >(); |
| 75 } |
| 76 |
| 77 template<typename Set> |
| 78 void appendOrMoveToLastNewItems() |
| 79 { |
| 80 Set list; |
| 81 typename Set::AddResult result = list.appendOrMoveToLast(1); |
| 82 EXPECT_TRUE(result.isNewEntry); |
| 83 result = list.add(2); |
| 84 EXPECT_TRUE(result.isNewEntry); |
| 85 result = list.appendOrMoveToLast(3); |
| 86 EXPECT_TRUE(result.isNewEntry); |
| 87 |
| 88 EXPECT_EQ(list.size(), 3UL); |
| 89 |
| 90 // The list should be in order 1, 2, 3. |
| 91 typename Set::iterator iterator = list.begin(); |
| 92 EXPECT_EQ(1, *iterator); |
| 93 ++iterator; |
| 94 EXPECT_EQ(2, *iterator); |
| 95 ++iterator; |
| 96 EXPECT_EQ(3, *iterator); |
| 97 ++iterator; |
53 } | 98 } |
54 | 99 |
55 TEST(WTF, ListHashSetAppendOrMoveToLastNewItems) | 100 TEST(WTF, ListHashSetAppendOrMoveToLastNewItems) |
56 { | 101 { |
57 ListHashSet<int> list; | 102 appendOrMoveToLastNewItems<ListHashSet<int> >(); |
58 ListHashSet<int>::AddResult result = list.appendOrMoveToLast(1); | 103 appendOrMoveToLastNewItems<ListHashSet<int, 1> >(); |
59 ASSERT_TRUE(result.isNewEntry); | 104 } |
60 result = list.add(2); | 105 |
61 ASSERT_TRUE(result.isNewEntry); | 106 TEST(WTF, LinkedHashSetAppendOrMoveToLastNewItems) |
62 result = list.appendOrMoveToLast(3); | 107 { |
63 ASSERT_TRUE(result.isNewEntry); | 108 appendOrMoveToLastNewItems<LinkedHashSet<int> >(); |
64 | 109 } |
65 ASSERT_EQ(list.size(), 3UL); | 110 |
66 | 111 template<typename Set> |
67 // The list should be in order 1, 2, 3. | 112 void appendOrMoveToLastWithDuplicates() |
68 ListHashSet<int>::iterator iterator = list.begin(); | 113 { |
69 ASSERT_EQ(1, *iterator); | 114 Set list; |
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 | 115 |
81 // Add a single element twice. | 116 // Add a single element twice. |
82 ListHashSet<int>::AddResult result = list.add(1); | 117 typename Set::AddResult result = list.add(1); |
83 ASSERT_TRUE(result.isNewEntry); | 118 EXPECT_TRUE(result.isNewEntry); |
84 result = list.appendOrMoveToLast(1); | 119 result = list.appendOrMoveToLast(1); |
85 ASSERT_FALSE(result.isNewEntry); | 120 EXPECT_FALSE(result.isNewEntry); |
86 ASSERT_EQ(1UL, list.size()); | 121 EXPECT_EQ(1UL, list.size()); |
87 | 122 |
88 list.add(2); | 123 list.add(2); |
89 list.add(3); | 124 list.add(3); |
90 ASSERT_EQ(3UL, list.size()); | 125 EXPECT_EQ(3UL, list.size()); |
91 | 126 |
92 // Appending 2 move it to the end. | 127 // Appending 2 move it to the end. |
93 ASSERT_EQ(3, list.last()); | 128 EXPECT_EQ(3, list.last()); |
94 result = list.appendOrMoveToLast(2); | 129 result = list.appendOrMoveToLast(2); |
95 ASSERT_FALSE(result.isNewEntry); | 130 EXPECT_FALSE(result.isNewEntry); |
96 ASSERT_EQ(2, list.last()); | 131 EXPECT_EQ(2, list.last()); |
97 | 132 |
98 // Inverse the list by moving each element to end end. | 133 // Inverse the list by moving each element to end end. |
99 result = list.appendOrMoveToLast(3); | 134 result = list.appendOrMoveToLast(3); |
100 ASSERT_FALSE(result.isNewEntry); | 135 EXPECT_FALSE(result.isNewEntry); |
101 result = list.appendOrMoveToLast(2); | 136 result = list.appendOrMoveToLast(2); |
102 ASSERT_FALSE(result.isNewEntry); | 137 EXPECT_FALSE(result.isNewEntry); |
103 result = list.appendOrMoveToLast(1); | 138 result = list.appendOrMoveToLast(1); |
104 ASSERT_FALSE(result.isNewEntry); | 139 EXPECT_FALSE(result.isNewEntry); |
105 ASSERT_EQ(3UL, list.size()); | 140 EXPECT_EQ(3UL, list.size()); |
106 | 141 |
107 ListHashSet<int>::iterator iterator = list.begin(); | 142 typename Set::iterator iterator = list.begin(); |
108 ASSERT_EQ(3, *iterator); | 143 EXPECT_EQ(3, *iterator); |
109 ++iterator; | 144 ++iterator; |
110 ASSERT_EQ(2, *iterator); | 145 EXPECT_EQ(2, *iterator); |
111 ++iterator; | 146 ++iterator; |
112 ASSERT_EQ(1, *iterator); | 147 EXPECT_EQ(1, *iterator); |
113 ++iterator; | 148 ++iterator; |
114 } | 149 } |
115 | 150 |
116 TEST(WTF, ListHashSetPrependOrMoveToLastNewItems) | 151 TEST(WTF, ListHashSetAppendOrMoveToLastWithDuplicates) |
117 { | 152 { |
118 ListHashSet<int> list; | 153 appendOrMoveToLastWithDuplicates<ListHashSet<int> >(); |
119 ListHashSet<int>::AddResult result = list.prependOrMoveToFirst(1); | 154 appendOrMoveToLastWithDuplicates<ListHashSet<int, 1> >(); |
120 ASSERT_TRUE(result.isNewEntry); | 155 } |
| 156 |
| 157 TEST(WTF, LinkedHashSetAppendOrMoveToLastWithDuplicates) |
| 158 { |
| 159 appendOrMoveToLastWithDuplicates<LinkedHashSet<int> >(); |
| 160 } |
| 161 |
| 162 template<typename Set> |
| 163 void prependOrMoveToFirstNewItems() |
| 164 { |
| 165 Set list; |
| 166 typename Set::AddResult result = list.prependOrMoveToFirst(1); |
| 167 EXPECT_TRUE(result.isNewEntry); |
121 result = list.add(2); | 168 result = list.add(2); |
122 ASSERT_TRUE(result.isNewEntry); | 169 EXPECT_TRUE(result.isNewEntry); |
123 result = list.prependOrMoveToFirst(3); | 170 result = list.prependOrMoveToFirst(3); |
124 ASSERT_TRUE(result.isNewEntry); | 171 EXPECT_TRUE(result.isNewEntry); |
125 | 172 |
126 ASSERT_EQ(list.size(), 3UL); | 173 EXPECT_EQ(list.size(), 3UL); |
127 | 174 |
128 // The list should be in order 3, 1, 2. | 175 // The list should be in order 3, 1, 2. |
129 ListHashSet<int>::iterator iterator = list.begin(); | 176 typename Set::iterator iterator = list.begin(); |
130 ASSERT_EQ(3, *iterator); | 177 EXPECT_EQ(3, *iterator); |
131 ++iterator; | 178 ++iterator; |
132 ASSERT_EQ(1, *iterator); | 179 EXPECT_EQ(1, *iterator); |
133 ++iterator; | 180 ++iterator; |
134 ASSERT_EQ(2, *iterator); | 181 EXPECT_EQ(2, *iterator); |
135 ++iterator; | 182 ++iterator; |
136 } | 183 } |
137 | 184 |
138 TEST(WTF, ListHashSetPrependOrMoveToLastWithDuplicates) | 185 TEST(WTF, ListHashSetPrependOrMoveToFirstNewItems) |
139 { | 186 { |
140 ListHashSet<int> list; | 187 prependOrMoveToFirstNewItems<ListHashSet<int> >(); |
| 188 prependOrMoveToFirstNewItems<ListHashSet<int, 1> >(); |
| 189 } |
| 190 |
| 191 TEST(WTF, LinkedHashSetPrependOrMoveToFirstNewItems) |
| 192 { |
| 193 prependOrMoveToFirstNewItems<LinkedHashSet<int> >(); |
| 194 } |
| 195 |
| 196 template<typename Set> |
| 197 void prependOrMoveToLastWithDuplicates() |
| 198 { |
| 199 Set list; |
141 | 200 |
142 // Add a single element twice. | 201 // Add a single element twice. |
143 ListHashSet<int>::AddResult result = list.add(1); | 202 typename Set::AddResult result = list.add(1); |
144 ASSERT_TRUE(result.isNewEntry); | 203 EXPECT_TRUE(result.isNewEntry); |
145 result = list.prependOrMoveToFirst(1); | 204 result = list.prependOrMoveToFirst(1); |
146 ASSERT_FALSE(result.isNewEntry); | 205 EXPECT_FALSE(result.isNewEntry); |
147 ASSERT_EQ(1UL, list.size()); | 206 EXPECT_EQ(1UL, list.size()); |
148 | 207 |
149 list.add(2); | 208 list.add(2); |
150 list.add(3); | 209 list.add(3); |
151 ASSERT_EQ(3UL, list.size()); | 210 EXPECT_EQ(3UL, list.size()); |
152 | 211 |
153 // Prepending 2 move it to the beginning. | 212 // Prepending 2 move it to the beginning. |
154 ASSERT_EQ(1, list.first()); | 213 EXPECT_EQ(1, list.first()); |
155 result = list.prependOrMoveToFirst(2); | 214 result = list.prependOrMoveToFirst(2); |
156 ASSERT_FALSE(result.isNewEntry); | 215 EXPECT_FALSE(result.isNewEntry); |
157 ASSERT_EQ(2, list.first()); | 216 EXPECT_EQ(2, list.first()); |
158 | 217 |
159 // Inverse the list by moving each element to the first position. | 218 // Inverse the list by moving each element to the first position. |
160 result = list.prependOrMoveToFirst(1); | 219 result = list.prependOrMoveToFirst(1); |
161 ASSERT_FALSE(result.isNewEntry); | 220 EXPECT_FALSE(result.isNewEntry); |
162 result = list.prependOrMoveToFirst(2); | 221 result = list.prependOrMoveToFirst(2); |
163 ASSERT_FALSE(result.isNewEntry); | 222 EXPECT_FALSE(result.isNewEntry); |
164 result = list.prependOrMoveToFirst(3); | 223 result = list.prependOrMoveToFirst(3); |
165 ASSERT_FALSE(result.isNewEntry); | 224 EXPECT_FALSE(result.isNewEntry); |
166 ASSERT_EQ(3UL, list.size()); | 225 EXPECT_EQ(3UL, list.size()); |
167 | 226 |
168 ListHashSet<int>::iterator iterator = list.begin(); | 227 typename Set::iterator iterator = list.begin(); |
169 ASSERT_EQ(3, *iterator); | 228 EXPECT_EQ(3, *iterator); |
170 ++iterator; | 229 ++iterator; |
171 ASSERT_EQ(2, *iterator); | 230 EXPECT_EQ(2, *iterator); |
172 ++iterator; | 231 ++iterator; |
173 ASSERT_EQ(1, *iterator); | 232 EXPECT_EQ(1, *iterator); |
174 ++iterator; | 233 ++iterator; |
| 234 } |
| 235 |
| 236 TEST(WTF, ListHashSetPrependOrMoveToLastWithDuplicates) |
| 237 { |
| 238 prependOrMoveToLastWithDuplicates<ListHashSet<int> >(); |
| 239 prependOrMoveToLastWithDuplicates<ListHashSet<int, 1> >(); |
| 240 } |
| 241 |
| 242 TEST(WTF, LinkedHashSetPrependOrMoveToLastWithDuplicates) |
| 243 { |
| 244 prependOrMoveToLastWithDuplicates<LinkedHashSet<int> >(); |
175 } | 245 } |
176 | 246 |
177 class DummyRefCounted: public WTF::RefCounted<DummyRefCounted> { | 247 class DummyRefCounted: public WTF::RefCounted<DummyRefCounted> { |
178 public: | 248 public: |
179 DummyRefCounted(bool& isDeleted) : m_isDeleted(isDeleted) { m_isDeleted = fa
lse; } | 249 DummyRefCounted(bool& isDeleted) : m_isDeleted(isDeleted) { m_isDeleted = fa
lse; } |
180 ~DummyRefCounted() { m_isDeleted = true; } | 250 ~DummyRefCounted() { m_isDeleted = true; } |
181 void ref() | 251 void ref() |
182 { | 252 { |
183 WTF::RefCounted<DummyRefCounted>::ref(); | 253 WTF::RefCounted<DummyRefCounted>::ref(); |
184 ++m_refInvokesCount; | 254 ++m_refInvokesCount; |
185 } | 255 } |
186 | 256 |
187 static int m_refInvokesCount; | 257 static int m_refInvokesCount; |
188 | 258 |
189 private: | 259 private: |
190 bool& m_isDeleted; | 260 bool& m_isDeleted; |
191 }; | 261 }; |
192 | 262 |
193 int DummyRefCounted::m_refInvokesCount = 0; | 263 int DummyRefCounted::m_refInvokesCount = 0; |
194 | 264 |
| 265 template<typename Set> |
| 266 void withRefPtr() |
| 267 { |
| 268 bool isDeleted; |
| 269 DummyRefCounted::m_refInvokesCount = 0; |
| 270 RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted)); |
| 271 EXPECT_EQ(0, DummyRefCounted::m_refInvokesCount); |
| 272 |
| 273 Set set; |
| 274 set.add(ptr); |
| 275 // Referenced only once (to store a copy in the container). |
| 276 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 277 EXPECT_EQ(ptr, set.first()); |
| 278 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 279 |
| 280 DummyRefCounted* rawPtr = ptr.get(); |
| 281 |
| 282 EXPECT_TRUE(set.contains(ptr)); |
| 283 EXPECT_TRUE(set.contains(rawPtr)); |
| 284 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 285 |
| 286 ptr.clear(); |
| 287 EXPECT_FALSE(isDeleted); |
| 288 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 289 |
| 290 set.remove(rawPtr); |
| 291 EXPECT_TRUE(isDeleted); |
| 292 |
| 293 EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount); |
| 294 } |
| 295 |
195 TEST(WTF, ListHashSetWithRefPtr) | 296 TEST(WTF, ListHashSetWithRefPtr) |
196 { | 297 { |
197 bool isDeleted; | 298 withRefPtr<ListHashSet<RefPtr<DummyRefCounted> > >(); |
| 299 withRefPtr<ListHashSet<RefPtr<DummyRefCounted>, 1> >(); |
| 300 } |
| 301 |
| 302 TEST(WTF, LinkedHashSetWithRefPtr) |
| 303 { |
| 304 withRefPtr<LinkedHashSet<RefPtr<DummyRefCounted> > >(); |
| 305 } |
| 306 |
| 307 template<typename Set, typename SetRef, typename Iterator> |
| 308 void findHelper() |
| 309 { |
| 310 Set set; |
| 311 set.add(-1); |
| 312 set.add(0); |
| 313 set.add(1); |
| 314 set.add(2); |
| 315 set.add(3); |
| 316 |
| 317 SetRef ref = set; |
| 318 Iterator it = ref.find(2); |
| 319 EXPECT_EQ(2, *it); |
| 320 ++it; |
| 321 EXPECT_EQ(3, *it); |
| 322 --it; |
| 323 --it; |
| 324 EXPECT_EQ(1, *it); |
| 325 } |
| 326 |
| 327 TEST(WTF, ListHashSetFind) |
| 328 { |
| 329 findHelper<ListHashSet<int>, const ListHashSet<int>&, ListHashSet<int>::cons
t_iterator>(); |
| 330 findHelper<ListHashSet<int>, ListHashSet<int>&, ListHashSet<int>::iterator>(
); |
| 331 findHelper<ListHashSet<int, 1>, const ListHashSet<int, 1>&, ListHashSet<int,
1>::const_iterator>(); |
| 332 findHelper<ListHashSet<int, 1>, ListHashSet<int, 1>&, ListHashSet<int, 1>::i
terator>(); |
| 333 } |
| 334 |
| 335 TEST(WTF, LinkedHashSetFind) |
| 336 { |
| 337 findHelper<LinkedHashSet<int>, const LinkedHashSet<int>&, LinkedHashSet<int>
::const_iterator>(); |
| 338 findHelper<LinkedHashSet<int>, LinkedHashSet<int>&, LinkedHashSet<int>::iter
ator>(); |
| 339 } |
| 340 |
| 341 template<typename Set> |
| 342 void insertBeforeHelper(bool canModifyWhileIterating) |
| 343 { |
| 344 Set set; |
| 345 set.add(-1); |
| 346 set.add(0); |
| 347 set.add(2); |
| 348 set.add(3); |
| 349 |
| 350 typename Set::iterator it = set.find(2); |
| 351 EXPECT_EQ(2, *it); |
| 352 set.insertBefore(it, 1); |
| 353 if (!canModifyWhileIterating) |
| 354 it = set.find(2); |
| 355 ++it; |
| 356 EXPECT_EQ(3, *it); |
| 357 EXPECT_EQ(5u, set.size()); |
| 358 --it; |
| 359 --it; |
| 360 EXPECT_EQ(1, *it); |
| 361 if (canModifyWhileIterating) { |
| 362 set.remove(-1); |
| 363 set.remove(0); |
| 364 set.remove(2); |
| 365 set.remove(3); |
| 366 EXPECT_EQ(1u, set.size()); |
| 367 EXPECT_EQ(1, *it); |
| 368 ++it; |
| 369 EXPECT_EQ(it, set.end()); |
| 370 --it; |
| 371 EXPECT_EQ(1, *it); |
| 372 set.insertBefore(it, -1); |
| 373 set.insertBefore(it, 0); |
| 374 set.add(2); |
| 375 set.add(3); |
| 376 } |
| 377 set.insertBefore(2, 42); |
| 378 set.insertBefore(-1, 103); |
| 379 EXPECT_EQ(103, set.first()); |
| 380 if (!canModifyWhileIterating) |
| 381 it = set.find(1); |
| 382 ++it; |
| 383 EXPECT_EQ(42, *it); |
| 384 EXPECT_EQ(7u, set.size()); |
| 385 } |
| 386 |
| 387 TEST(WTF, ListHashSetInsertBefore) |
| 388 { |
| 389 insertBeforeHelper<ListHashSet<int> >(true); |
| 390 insertBeforeHelper<ListHashSet<int, 1> >(true); |
| 391 } |
| 392 |
| 393 TEST(WTF, LinkedHashSetInsertBefore) |
| 394 { |
| 395 insertBeforeHelper<LinkedHashSet<int> >(false); |
| 396 } |
| 397 |
| 398 template<typename Set> |
| 399 void addReturnIterator(bool canModifyWhileIterating) |
| 400 { |
| 401 Set set; |
| 402 set.add(-1); |
| 403 set.add(0); |
| 404 set.add(1); |
| 405 set.add(2); |
| 406 |
| 407 typename Set::iterator it = set.addReturnIterator(3); |
| 408 EXPECT_EQ(3, *it); |
| 409 --it; |
| 410 EXPECT_EQ(2, *it); |
| 411 EXPECT_EQ(5u, set.size()); |
| 412 --it; |
| 413 EXPECT_EQ(1, *it); |
| 414 --it; |
| 415 EXPECT_EQ(0, *it); |
| 416 it = set.addReturnIterator(4); |
| 417 if (canModifyWhileIterating) { |
| 418 set.remove(3); |
| 419 set.remove(2); |
| 420 set.remove(1); |
| 421 set.remove(0); |
| 422 set.remove(-1); |
| 423 EXPECT_EQ(1u, set.size()); |
| 424 } |
| 425 EXPECT_EQ(4, *it); |
| 426 ++it; |
| 427 EXPECT_EQ(it, set.end()); |
| 428 --it; |
| 429 EXPECT_EQ(4, *it); |
| 430 if (canModifyWhileIterating) { |
| 431 set.insertBefore(it, -1); |
| 432 set.insertBefore(it, 0); |
| 433 set.insertBefore(it, 1); |
| 434 set.insertBefore(it, 2); |
| 435 set.insertBefore(it, 3); |
| 436 } |
| 437 EXPECT_EQ(6u, set.size()); |
| 438 it = set.addReturnIterator(5); |
| 439 EXPECT_EQ(7u, set.size()); |
| 440 set.remove(it); |
| 441 EXPECT_EQ(6u, set.size()); |
| 442 EXPECT_EQ(4, set.last()); |
| 443 } |
| 444 |
| 445 TEST(WTF, ListHashSetAddReturnIterator) |
| 446 { |
| 447 addReturnIterator<ListHashSet<int> >(true); |
| 448 addReturnIterator<ListHashSet<int, 1> >(true); |
| 449 } |
| 450 |
| 451 TEST(WTF, LinkedHashSetAddReturnIterator) |
| 452 { |
| 453 addReturnIterator<LinkedHashSet<int> >(false); |
| 454 } |
| 455 |
| 456 template<typename Set> |
| 457 void excerciseValuePeekInType() |
| 458 { |
| 459 Set set; |
| 460 bool isDeleted = false; |
| 461 bool isDeleted2 = false; |
| 462 |
198 RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted)); | 463 RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted)); |
199 ASSERT_EQ(0, DummyRefCounted::m_refInvokesCount); | 464 RefPtr<DummyRefCounted> ptr2 = adoptRef(new DummyRefCounted(isDeleted2)); |
200 | 465 |
201 ListHashSet<RefPtr<DummyRefCounted> > list; | 466 typename Set::AddResult addResult = set.add(ptr); |
202 list.add(ptr); | 467 EXPECT_TRUE(addResult.isNewEntry); |
203 // Referenced only once (to store a copy in the container). | 468 set.find(ptr); |
204 ASSERT_EQ(1, DummyRefCounted::m_refInvokesCount); | 469 const Set& constSet(set); |
205 ASSERT_EQ(ptr, list.first()); | 470 constSet.find(ptr); |
206 | 471 EXPECT_TRUE(set.contains(ptr)); |
207 DummyRefCounted* rawPtr = ptr.get(); | 472 typename Set::iterator it = set.addReturnIterator(ptr); |
208 | 473 set.appendOrMoveToLast(ptr); |
209 ASSERT_TRUE(list.contains(ptr)); | 474 set.prependOrMoveToFirst(ptr); |
210 ASSERT_TRUE(list.contains(rawPtr)); | 475 set.insertBefore(ptr, ptr); |
211 | 476 set.insertBefore(it, ptr); |
| 477 EXPECT_EQ(1u, set.size()); |
| 478 set.add(ptr2); |
| 479 ptr2.clear(); |
| 480 set.remove(ptr); |
| 481 |
| 482 EXPECT_FALSE(isDeleted); |
212 ptr.clear(); | 483 ptr.clear(); |
213 ASSERT_FALSE(isDeleted); | 484 EXPECT_TRUE(isDeleted); |
214 | 485 |
215 list.remove(rawPtr); | 486 EXPECT_FALSE(isDeleted2); |
216 ASSERT_TRUE(isDeleted); | 487 set.removeFirst(); |
217 | 488 EXPECT_TRUE(isDeleted2); |
218 ASSERT_EQ(1, DummyRefCounted::m_refInvokesCount); | 489 |
| 490 EXPECT_EQ(0u, set.size()); |
| 491 } |
| 492 |
| 493 TEST(WTF, ListHashSetExcerciseValuePeekInType) |
| 494 { |
| 495 excerciseValuePeekInType<ListHashSet<RefPtr<DummyRefCounted> > >(); |
| 496 excerciseValuePeekInType<ListHashSet<RefPtr<DummyRefCounted>, 1> >(); |
| 497 } |
| 498 |
| 499 TEST(WTF, LinkedHashSetExcerciseValuePeekInType) |
| 500 { |
| 501 excerciseValuePeekInType<LinkedHashSet<RefPtr<DummyRefCounted> > >(); |
| 502 } |
| 503 |
| 504 struct Simple { |
| 505 Simple(int value) : m_value(value) { }; |
| 506 int m_value; |
| 507 }; |
| 508 |
| 509 struct Complicated { |
| 510 Complicated(int value) : m_simple(value) |
| 511 { |
| 512 s_objectsConstructed++; |
| 513 } |
| 514 |
| 515 Complicated(const Complicated& other) : m_simple(other.m_simple) |
| 516 { |
| 517 s_objectsConstructed++; |
| 518 } |
| 519 |
| 520 Simple m_simple; |
| 521 static int s_objectsConstructed; |
| 522 |
| 523 private: |
| 524 Complicated(); |
| 525 }; |
| 526 |
| 527 int Complicated::s_objectsConstructed = 0; |
| 528 |
| 529 struct ComplicatedHashFunctions { |
| 530 static unsigned hash(const Complicated& key) { return key.m_simple.m_value;
} |
| 531 static bool equal(const Complicated& a, const Complicated& b) { return a.m_s
imple.m_value == b.m_simple.m_value; } |
| 532 }; |
| 533 struct ComplexityTranslator { |
| 534 static unsigned hash(const Simple& key) { return key.m_value; } |
| 535 static bool equal(const Complicated& a, const Simple& b) { return a.m_simple
.m_value == b.m_value; } |
| 536 }; |
| 537 |
| 538 template<typename Set> |
| 539 void translatorTest() |
| 540 { |
| 541 Set set; |
| 542 set.add(Complicated(42)); |
| 543 int baseLine = Complicated::s_objectsConstructed; |
| 544 |
| 545 typename Set::iterator it = set.template find<ComplexityTranslator>(Simple(4
2)); |
| 546 EXPECT_NE(it, set.end()); |
| 547 EXPECT_EQ(baseLine, Complicated::s_objectsConstructed); |
| 548 |
| 549 it = set.template find<ComplexityTranslator>(Simple(103)); |
| 550 EXPECT_EQ(it, set.end()); |
| 551 EXPECT_EQ(baseLine, Complicated::s_objectsConstructed); |
| 552 |
| 553 const Set& constSet(set); |
| 554 |
| 555 typename Set::const_iterator constIterator = constSet.template find<Complexi
tyTranslator>(Simple(42)); |
| 556 EXPECT_NE(constIterator, constSet.end()); |
| 557 EXPECT_EQ(baseLine, Complicated::s_objectsConstructed); |
| 558 |
| 559 constIterator = constSet.template find<ComplexityTranslator>(Simple(103)); |
| 560 EXPECT_EQ(constIterator, constSet.end()); |
| 561 EXPECT_EQ(baseLine, Complicated::s_objectsConstructed); |
| 562 } |
| 563 |
| 564 TEST(WTF, ListHashSetComplexityTranslator) |
| 565 { |
| 566 translatorTest<ListHashSet<Complicated, 256, ComplicatedHashFunctions> >(); |
| 567 translatorTest<ListHashSet<Complicated, 1, ComplicatedHashFunctions> >(); |
| 568 } |
| 569 |
| 570 TEST(WTF, LinkedHashSetComplexityTranslator) |
| 571 { |
| 572 translatorTest<LinkedHashSet<Complicated, ComplicatedHashFunctions> >(); |
219 } | 573 } |
220 | 574 |
221 } // namespace | 575 } // namespace |
OLD | NEW |