1 /* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 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, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 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 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 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 28 #include "wtf/Deque.h" 29 30 #include "wtf/HashSet.h" 31 #include "wtf/OwnPtr.h" 32 #include "wtf/PassOwnPtr.h" 33 #include <gtest/gtest.h> 34 35 namespace { 36 37 TEST(DequeTest, Basic) 38 { 39 Deque<int> intDeque; 40 EXPECT_TRUE(intDeque.isEmpty()); 41 EXPECT_EQ(0ul, intDeque.size()); 42 } 43 44 void checkNumberSequence(Deque<int>& deque, int from, int to, bool increment) 45 { 46 Deque<int>::iterator it = increment ? deque.begin() : deque.end(); 47 size_t index = increment ? 0 : deque.size(); 48 int step = from < to ? 1 : -1; 49 for (int i = from; i != to + step; i += step) { 50 if (!increment) { 51 --it; 52 --index; 53 } 54 55 EXPECT_EQ(i, *it); 56 EXPECT_EQ(i, deque[index]); 57 58 if (increment) { 59 ++it; 60 ++index; 61 } 62 } 63 EXPECT_EQ(increment ? deque.end() : deque.begin(), it); 64 EXPECT_EQ(increment ? deque.size() : 0, index); 65 } 66 67 void checkNumberSequenceReverse(Deque<int>& deque, int from, int to, bool increment) 68 { 69 Deque<int>::reverse_iterator it = increment ? deque.rbegin() : deque.rend(); 70 size_t index = increment ? 0 : deque.size(); 71 int step = from < to ? 1 : -1; 72 for (int i = from; i != to + step; i += step) { 73 if (!increment) { 74 --it; 75 --index; 76 } 77 78 EXPECT_EQ(i, *it); 79 EXPECT_EQ(i, deque.at(deque.size() - 1 - index)); 80 81 if (increment) { 82 ++it; 83 ++index; 84 } 85 } 86 EXPECT_EQ(increment ? deque.rend() : deque.rbegin(), it); 87 EXPECT_EQ(increment ? deque.size() : 0, index); 88 } 89 90 TEST(DequeTest, Reverse) 91 { 92 Deque<int> intDeque; 93 intDeque.append(10); 94 intDeque.append(11); 95 intDeque.append(12); 96 intDeque.append(13); 97 98 checkNumberSequence(intDeque, 10, 13, true); 99 checkNumberSequence(intDeque, 13, 10, false); 100 checkNumberSequenceReverse(intDeque, 13, 10, true); 101 checkNumberSequenceReverse(intDeque, 10, 13, false); 102 103 intDeque.append(14); 104 intDeque.append(15); 105 EXPECT_EQ(10, intDeque.takeFirst()); 106 EXPECT_EQ(15, intDeque.takeLast()); 107 checkNumberSequence(intDeque, 11, 14, true); 108 checkNumberSequence(intDeque, 14, 11, false); 109 checkNumberSequenceReverse(intDeque, 14, 11, true); 110 checkNumberSequenceReverse(intDeque, 11, 14, false); 111 112 for (int i = 15; i < 200; ++i) 113 intDeque.append(i); 114 checkNumberSequence(intDeque, 11, 199, true); 115 checkNumberSequence(intDeque, 199, 11, false); 116 checkNumberSequenceReverse(intDeque, 199, 11, true); 117 checkNumberSequenceReverse(intDeque, 11, 199, false); 118 119 for (int i = 0; i < 180; ++i) { 120 EXPECT_EQ(i + 11, intDeque[0]); 121 EXPECT_EQ(i + 11, intDeque.takeFirst()); 122 } 123 checkNumberSequence(intDeque, 191, 199, true); 124 checkNumberSequence(intDeque, 199, 191, false); 125 checkNumberSequenceReverse(intDeque, 199, 191, true); 126 checkNumberSequenceReverse(intDeque, 191, 199, false); 127 128 Deque<int> intDeque2; 129 swap(intDeque, intDeque2); 130 131 checkNumberSequence(intDeque2, 191, 199, true); 132 checkNumberSequence(intDeque2, 199, 191, false); 133 checkNumberSequenceReverse(intDeque2, 199, 191, true); 134 checkNumberSequenceReverse(intDeque2, 191, 199, false); 135 136 intDeque.swap(intDeque2); 137 138 checkNumberSequence(intDeque, 191, 199, true); 139 checkNumberSequence(intDeque, 199, 191, false); 140 checkNumberSequenceReverse(intDeque, 199, 191, true); 141 checkNumberSequenceReverse(intDeque, 191, 199, false); 142 143 intDeque.swap(intDeque2); 144 145 checkNumberSequence(intDeque2, 191, 199, true); 146 checkNumberSequence(intDeque2, 199, 191, false); 147 checkNumberSequenceReverse(intDeque2, 199, 191, true); 148 checkNumberSequenceReverse(intDeque2, 191, 199, false); 149 } 150 151 class DestructCounter { 152 public: 153 explicit DestructCounter(int i, int* destructNumber) 154 : m_i(i) 155 , m_destructNumber(destructNumber) 156 { } 157 158 ~DestructCounter() { ++(*m_destructNumber); } 159 int get() const { return m_i; } 160 161 private: 162 int m_i; 163 int* m_destructNumber; 164 }; 165 166 typedef WTF::Deque<OwnPtr<DestructCounter> > OwnPtrDeque; 167 168 TEST(DequeTest, OwnPtr) 169 { 170 int destructNumber = 0; 171 OwnPtrDeque deque; 172 deque.append(adoptPtr(new DestructCounter(0, &destructNumber))); 173 deque.append(adoptPtr(new DestructCounter(1, &destructNumber))); 174 EXPECT_EQ(2u, deque.size()); 175 176 OwnPtr<DestructCounter>& counter0 = deque.first(); 177 EXPECT_EQ(0, counter0->get()); 178 int counter1 = deque.last()->get(); 179 EXPECT_EQ(1, counter1); 180 EXPECT_EQ(0, destructNumber); 181 182 size_t index = 0; 183 for (OwnPtrDeque::iterator iter = deque.begin(); iter != deque.end(); ++iter) { 184 OwnPtr<DestructCounter>& refCounter = *iter; 185 EXPECT_EQ(index, static_cast<size_t>(refCounter->get())); 186 EXPECT_EQ(index, static_cast<size_t>((*refCounter).get())); 187 index++; 188 } 189 EXPECT_EQ(0, destructNumber); 190 191 OwnPtrDeque::iterator it = deque.begin(); 192 for (index = 0; index < deque.size(); ++index) { 193 OwnPtr<DestructCounter>& refCounter = *it; 194 EXPECT_EQ(index, static_cast<size_t>(refCounter->get())); 195 index++; 196 ++it; 197 } 198 EXPECT_EQ(0, destructNumber); 199 200 EXPECT_EQ(0, deque.first()->get()); 201 deque.removeFirst(); 202 EXPECT_EQ(1, deque.first()->get()); 203 EXPECT_EQ(1u, deque.size()); 204 EXPECT_EQ(1, destructNumber); 205 206 OwnPtr<DestructCounter> ownCounter1 = deque.first().release(); 207 deque.removeFirst(); 208 EXPECT_EQ(counter1, ownCounter1->get()); 209 EXPECT_EQ(0u, deque.size()); 210 EXPECT_EQ(1, destructNumber); 211 212 ownCounter1.clear(); 213 EXPECT_EQ(2, destructNumber); 214 215 size_t count = 1025; 216 destructNumber = 0; 217 for (size_t i = 0; i < count; ++i) 218 deque.prepend(adoptPtr(new DestructCounter(i, &destructNumber))); 219 220 // Deque relocation must not destruct OwnPtr element. 221 EXPECT_EQ(0, destructNumber); 222 EXPECT_EQ(count, deque.size()); 223 224 OwnPtrDeque copyDeque; 225 deque.swap(copyDeque); 226 EXPECT_EQ(0, destructNumber); 227 EXPECT_EQ(count, copyDeque.size()); 228 EXPECT_EQ(0u, deque.size()); 229 230 copyDeque.clear(); 231 EXPECT_EQ(count, static_cast<size_t>(destructNumber)); 232 } 233 234 // WrappedInt class will fail if it was memmoved or memcpyed. 235 static HashSet<void*> constructedWrappedInts; 236 class WrappedInt { 237 public: 238 WrappedInt(int i = 0) 239 : m_originalThisPtr(this) 240 , m_i(i) 241 { 242 constructedWrappedInts.add(this); 243 } 244 245 WrappedInt(const WrappedInt& other) 246 : m_originalThisPtr(this) 247 , m_i(other.m_i) 248 { 249 constructedWrappedInts.add(this); 250 } 251 252 WrappedInt& operator=(const WrappedInt& other) 253 { 254 m_i = other.m_i; 255 return *this; 256 } 257 258 ~WrappedInt() 259 { 260 EXPECT_EQ(m_originalThisPtr, this); 261 EXPECT_TRUE(constructedWrappedInts.contains(this)); 262 constructedWrappedInts.remove(this); 263 } 264 265 int get() const { return m_i; } 266 267 private: 268 void* m_originalThisPtr; 269 int m_i; 270 }; 271 272 TEST(DequeTest, SwapWithoutInlineCapacity) 273 { 274 Deque<WrappedInt> dequeA; 275 dequeA.append(WrappedInt(1)); 276 Deque<WrappedInt> dequeB; 277 dequeB.append(WrappedInt(2)); 278 279 ASSERT_EQ(dequeA.size(), dequeB.size()); 280 dequeA.swap(dequeB); 281 282 ASSERT_EQ(1u, dequeA.size()); 283 EXPECT_EQ(2, dequeA.first().get()); 284 ASSERT_EQ(1u, dequeB.size()); 285 EXPECT_EQ(1, dequeB.first().get()); 286 287 dequeA.append(WrappedInt(3)); 288 289 ASSERT_GT(dequeA.size(), dequeB.size()); 290 dequeA.swap(dequeB); 291 292 ASSERT_EQ(1u, dequeA.size()); 293 EXPECT_EQ(1, dequeA.first().get()); 294 ASSERT_EQ(2u, dequeB.size()); 295 EXPECT_EQ(2, dequeB.first().get()); 296 297 ASSERT_LT(dequeA.size(), dequeB.size()); 298 dequeA.swap(dequeB); 299 300 ASSERT_EQ(2u, dequeA.size()); 301 EXPECT_EQ(2, dequeA.first().get()); 302 ASSERT_EQ(1u, dequeB.size()); 303 EXPECT_EQ(1, dequeB.first().get()); 304 305 dequeA.append(WrappedInt(4)); 306 dequeA.swap(dequeB); 307 308 ASSERT_EQ(1u, dequeA.size()); 309 EXPECT_EQ(1, dequeA.first().get()); 310 ASSERT_EQ(3u, dequeB.size()); 311 EXPECT_EQ(2, dequeB.first().get()); 312 313 dequeB.swap(dequeA); 314 } 315 316 } // namespace 317