OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 28 matching lines...) Expand all Loading... |
39 | 39 |
40 template<typename T> | 40 template<typename T> |
41 struct VectorDestructor<false, T> | 41 struct VectorDestructor<false, T> |
42 { | 42 { |
43 static void destruct(T*, T*) {} | 43 static void destruct(T*, T*) {} |
44 }; | 44 }; |
45 | 45 |
46 template<typename T> | 46 template<typename T> |
47 struct VectorDestructor<true, T> | 47 struct VectorDestructor<true, T> |
48 { | 48 { |
49 static void destruct(T* begin, T* end) | 49 static void destruct(T* begin, T* end) |
50 { | 50 { |
51 for (T* cur = begin; cur != end; ++cur) | 51 for (T* cur = begin; cur != end; ++cur) |
52 cur->~T(); | 52 cur->~T(); |
53 } | 53 } |
54 }; | 54 }; |
55 | 55 |
56 template <bool needsInitialization, bool canInitializeWithMemset, typename T
> | 56 template <bool needsInitialization, bool canInitializeWithMemset, typename T
> |
57 struct VectorInitializer; | 57 struct VectorInitializer; |
58 | 58 |
59 template<bool ignore, typename T> | 59 template<bool ignore, typename T> |
60 struct VectorInitializer<false, ignore, T> | 60 struct VectorInitializer<false, ignore, T> |
61 { | 61 { |
62 static void initialize(T*, T*) {} | 62 static void initialize(T*, T*) {} |
63 }; | 63 }; |
64 | 64 |
65 template<typename T> | 65 template<typename T> |
66 struct VectorInitializer<true, false, T> | 66 struct VectorInitializer<true, false, T> |
67 { | 67 { |
68 static void initialize(T* begin, T* end) | 68 static void initialize(T* begin, T* end) |
69 { | 69 { |
70 for (T* cur = begin; cur != end; ++cur) | 70 for (T* cur = begin; cur != end; ++cur) |
71 new (NotNull, cur) T; | 71 new (NotNull, cur) T; |
72 } | 72 } |
73 }; | 73 }; |
74 | 74 |
75 template<typename T> | 75 template<typename T> |
76 struct VectorInitializer<true, true, T> | 76 struct VectorInitializer<true, true, T> |
77 { | 77 { |
78 static void initialize(T* begin, T* end) | 78 static void initialize(T* begin, T* end) |
79 { | 79 { |
80 memset(begin, 0, reinterpret_cast<char*>(end) - reinterpret_cast<cha
r*>(begin)); | 80 memset(begin, 0, reinterpret_cast<char*>(end) - reinterpret_cast<cha
r*>(begin)); |
81 } | 81 } |
82 }; | 82 }; |
83 | 83 |
84 template <bool canMoveWithMemcpy, typename T> | 84 template <bool canMoveWithMemcpy, typename T> |
85 struct VectorMover; | 85 struct VectorMover; |
86 | 86 |
87 template<typename T> | 87 template<typename T> |
88 struct VectorMover<false, T> | 88 struct VectorMover<false, T> |
(...skipping 19 matching lines...) Expand all Loading... |
108 new (NotNull, dstEnd) T(*srcEnd); | 108 new (NotNull, dstEnd) T(*srcEnd); |
109 srcEnd->~T(); | 109 srcEnd->~T(); |
110 } | 110 } |
111 } | 111 } |
112 } | 112 } |
113 }; | 113 }; |
114 | 114 |
115 template<typename T> | 115 template<typename T> |
116 struct VectorMover<true, T> | 116 struct VectorMover<true, T> |
117 { | 117 { |
118 static void move(const T* src, const T* srcEnd, T* dst) | 118 static void move(const T* src, const T* srcEnd, T* dst) |
119 { | 119 { |
120 memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret
_cast<const char*>(src)); | 120 memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret
_cast<const char*>(src)); |
121 } | 121 } |
122 static void moveOverlapping(const T* src, const T* srcEnd, T* dst) | 122 static void moveOverlapping(const T* src, const T* srcEnd, T* dst) |
123 { | 123 { |
124 memmove(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpre
t_cast<const char*>(src)); | 124 memmove(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpre
t_cast<const char*>(src)); |
125 } | 125 } |
126 }; | 126 }; |
127 | 127 |
128 template <bool canCopyWithMemcpy, typename T> | 128 template <bool canCopyWithMemcpy, typename T> |
129 struct VectorCopier; | 129 struct VectorCopier; |
130 | 130 |
131 template<typename T> | 131 template<typename T> |
132 struct VectorCopier<false, T> | 132 struct VectorCopier<false, T> |
133 { | 133 { |
134 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) | 134 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) |
135 { | 135 { |
136 while (src != srcEnd) { | 136 while (src != srcEnd) { |
137 new (NotNull, dst) T(*src); | 137 new (NotNull, dst) T(*src); |
138 ++dst; | 138 ++dst; |
139 ++src; | 139 ++src; |
140 } | 140 } |
141 } | 141 } |
142 }; | 142 }; |
143 | 143 |
144 template<typename T> | 144 template<typename T> |
145 struct VectorCopier<true, T> | 145 struct VectorCopier<true, T> |
146 { | 146 { |
147 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) | 147 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) |
148 { | 148 { |
149 memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret
_cast<const char*>(src)); | 149 memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret
_cast<const char*>(src)); |
150 } | 150 } |
151 }; | 151 }; |
152 | 152 |
153 template <bool canFillWithMemset, typename T> | 153 template <bool canFillWithMemset, typename T> |
154 struct VectorFiller; | 154 struct VectorFiller; |
155 | 155 |
156 template<typename T> | 156 template<typename T> |
157 struct VectorFiller<false, T> | 157 struct VectorFiller<false, T> |
158 { | 158 { |
159 static void uninitializedFill(T* dst, T* dstEnd, const T& val) | 159 static void uninitializedFill(T* dst, T* dstEnd, const T& val) |
160 { | 160 { |
161 while (dst != dstEnd) { | 161 while (dst != dstEnd) { |
162 new (NotNull, dst) T(val); | 162 new (NotNull, dst) T(val); |
163 ++dst; | 163 ++dst; |
164 } | 164 } |
165 } | 165 } |
166 }; | 166 }; |
167 | 167 |
168 template<typename T> | 168 template<typename T> |
169 struct VectorFiller<true, T> | 169 struct VectorFiller<true, T> |
170 { | 170 { |
171 static void uninitializedFill(T* dst, T* dstEnd, const T& val) | 171 static void uninitializedFill(T* dst, T* dstEnd, const T& val) |
172 { | 172 { |
173 ASSERT(sizeof(T) == sizeof(char)); | 173 ASSERT(sizeof(T) == sizeof(char)); |
174 #if COMPILER(GCC) && defined(_FORTIFY_SOURCE) | 174 #if COMPILER(GCC) && defined(_FORTIFY_SOURCE) |
175 if (!__builtin_constant_p(dstEnd - dst) || (!(dstEnd - dst))) | 175 if (!__builtin_constant_p(dstEnd - dst) || (!(dstEnd - dst))) |
176 #endif | 176 #endif |
177 memset(dst, val, dstEnd - dst); | 177 memset(dst, val, dstEnd - dst); |
178 } | 178 } |
179 }; | 179 }; |
180 | 180 |
181 template<bool canCompareWithMemcmp, typename T> | 181 template<bool canCompareWithMemcmp, typename T> |
182 struct VectorComparer; | 182 struct VectorComparer; |
183 | 183 |
184 template<typename T> | 184 template<typename T> |
185 struct VectorComparer<false, T> | 185 struct VectorComparer<false, T> |
186 { | 186 { |
187 static bool compare(const T* a, const T* b, size_t size) | 187 static bool compare(const T* a, const T* b, size_t size) |
188 { | 188 { |
189 for (size_t i = 0; i < size; ++i) | 189 for (size_t i = 0; i < size; ++i) |
190 if (!(a[i] == b[i])) | 190 if (!(a[i] == b[i])) |
191 return false; | 191 return false; |
192 return true; | 192 return true; |
193 } | 193 } |
194 }; | 194 }; |
195 | 195 |
196 template<typename T> | 196 template<typename T> |
197 struct VectorComparer<true, T> | 197 struct VectorComparer<true, T> |
198 { | 198 { |
199 static bool compare(const T* a, const T* b, size_t size) | 199 static bool compare(const T* a, const T* b, size_t size) |
200 { | 200 { |
201 return memcmp(a, b, sizeof(T) * size) == 0; | 201 return memcmp(a, b, sizeof(T) * size) == 0; |
202 } | 202 } |
203 }; | 203 }; |
204 | 204 |
205 template<typename T> | 205 template<typename T> |
206 struct VectorTypeOperations | 206 struct VectorTypeOperations |
207 { | 207 { |
208 static void destruct(T* begin, T* end) | 208 static void destruct(T* begin, T* end) |
209 { | 209 { |
210 VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(beg
in, end); | 210 VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(beg
in, end); |
211 } | 211 } |
212 | 212 |
213 static void initialize(T* begin, T* end) | 213 static void initialize(T* begin, T* end) |
214 { | 214 { |
(...skipping 12 matching lines...) Expand all Loading... |
227 | 227 |
228 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) | 228 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) |
229 { | 229 { |
230 VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCo
py(src, srcEnd, dst); | 230 VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCo
py(src, srcEnd, dst); |
231 } | 231 } |
232 | 232 |
233 static void uninitializedFill(T* dst, T* dstEnd, const T& val) | 233 static void uninitializedFill(T* dst, T* dstEnd, const T& val) |
234 { | 234 { |
235 VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFi
ll(dst, dstEnd, val); | 235 VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFi
ll(dst, dstEnd, val); |
236 } | 236 } |
237 | 237 |
238 static bool compare(const T* a, const T* b, size_t size) | 238 static bool compare(const T* a, const T* b, size_t size) |
239 { | 239 { |
240 return VectorComparer<VectorTraits<T>::canCompareWithMemcmp, T>::com
pare(a, b, size); | 240 return VectorComparer<VectorTraits<T>::canCompareWithMemcmp, T>::com
pare(a, b, size); |
241 } | 241 } |
242 }; | 242 }; |
243 | 243 |
244 template<typename T> | 244 template<typename T> |
245 class VectorBufferBase { | 245 class VectorBufferBase { |
246 WTF_MAKE_NONCOPYABLE(VectorBufferBase); | 246 WTF_MAKE_NONCOPYABLE(VectorBufferBase); |
247 public: | 247 public: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 RELEASE_ASSERT(newCapacity <= std::numeric_limits<unsigned>::max() /
sizeof(T)); | 284 RELEASE_ASSERT(newCapacity <= std::numeric_limits<unsigned>::max() /
sizeof(T)); |
285 size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T)); | 285 size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T)); |
286 m_capacity = sizeToAllocate / sizeof(T); | 286 m_capacity = sizeToAllocate / sizeof(T); |
287 m_buffer = static_cast<T*>(fastRealloc(m_buffer, sizeToAllocate)); | 287 m_buffer = static_cast<T*>(fastRealloc(m_buffer, sizeToAllocate)); |
288 } | 288 } |
289 | 289 |
290 void deallocateBuffer(T* bufferToDeallocate) | 290 void deallocateBuffer(T* bufferToDeallocate) |
291 { | 291 { |
292 if (!bufferToDeallocate) | 292 if (!bufferToDeallocate) |
293 return; | 293 return; |
294 | 294 |
295 if (m_buffer == bufferToDeallocate) { | 295 if (m_buffer == bufferToDeallocate) { |
296 m_buffer = 0; | 296 m_buffer = 0; |
297 m_capacity = 0; | 297 m_capacity = 0; |
298 } | 298 } |
299 | 299 |
300 fastFree(bufferToDeallocate); | 300 fastFree(bufferToDeallocate); |
301 } | 301 } |
302 | 302 |
303 T* buffer() { return m_buffer; } | 303 T* buffer() { return m_buffer; } |
304 const T* buffer() const { return m_buffer; } | 304 const T* buffer() const { return m_buffer; } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 // Calling malloc(0) might take a lock and may actually do an | 351 // Calling malloc(0) might take a lock and may actually do an |
352 // allocation on some systems. | 352 // allocation on some systems. |
353 if (capacity) | 353 if (capacity) |
354 allocateBuffer(capacity); | 354 allocateBuffer(capacity); |
355 } | 355 } |
356 | 356 |
357 ~VectorBuffer() | 357 ~VectorBuffer() |
358 { | 358 { |
359 deallocateBuffer(buffer()); | 359 deallocateBuffer(buffer()); |
360 } | 360 } |
361 | 361 |
362 void swap(VectorBuffer<T, 0>& other) | 362 void swap(VectorBuffer<T, 0>& other) |
363 { | 363 { |
364 std::swap(m_buffer, other.m_buffer); | 364 std::swap(m_buffer, other.m_buffer); |
365 std::swap(m_capacity, other.m_capacity); | 365 std::swap(m_capacity, other.m_capacity); |
366 } | 366 } |
367 | 367 |
368 void restoreInlineBufferIfNeeded() { } | 368 void restoreInlineBufferIfNeeded() { } |
369 | 369 |
370 using Base::allocateBuffer; | 370 using Base::allocateBuffer; |
371 using Base::tryAllocateBuffer; | 371 using Base::tryAllocateBuffer; |
372 using Base::shouldReallocateBuffer; | 372 using Base::shouldReallocateBuffer; |
373 using Base::reallocateBuffer; | 373 using Base::reallocateBuffer; |
374 using Base::deallocateBuffer; | 374 using Base::deallocateBuffer; |
375 | 375 |
376 using Base::buffer; | 376 using Base::buffer; |
377 using Base::capacity; | 377 using Base::capacity; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 typedef VectorTypeOperations<T> TypeOperations; | 502 typedef VectorTypeOperations<T> TypeOperations; |
503 | 503 |
504 public: | 504 public: |
505 typedef T ValueType; | 505 typedef T ValueType; |
506 | 506 |
507 typedef T* iterator; | 507 typedef T* iterator; |
508 typedef const T* const_iterator; | 508 typedef const T* const_iterator; |
509 typedef std::reverse_iterator<iterator> reverse_iterator; | 509 typedef std::reverse_iterator<iterator> reverse_iterator; |
510 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 510 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
511 | 511 |
512 Vector() | 512 Vector() |
513 : m_size(0) | 513 : m_size(0) |
514 { | 514 { |
515 } | 515 } |
516 | 516 |
517 explicit Vector(size_t size) | 517 explicit Vector(size_t size) |
518 : Base(size) | 518 : Base(size) |
519 , m_size(size) | 519 , m_size(size) |
520 { | 520 { |
521 if (begin()) | 521 if (begin()) |
522 TypeOperations::initialize(begin(), end()); | 522 TypeOperations::initialize(begin(), end()); |
523 } | 523 } |
524 | 524 |
525 ~Vector() | 525 ~Vector() |
526 { | 526 { |
527 if (m_size) | 527 if (m_size) |
528 shrink(0); | 528 shrink(0); |
529 } | 529 } |
530 | 530 |
531 Vector(const Vector&); | 531 Vector(const Vector&); |
532 template<size_t otherCapacity> | 532 template<size_t otherCapacity> |
533 Vector(const Vector<T, otherCapacity>&); | 533 Vector(const Vector<T, otherCapacity>&); |
534 | 534 |
535 Vector& operator=(const Vector&); | 535 Vector& operator=(const Vector&); |
536 template<size_t otherCapacity> | 536 template<size_t otherCapacity> |
537 Vector& operator=(const Vector<T, otherCapacity>&); | 537 Vector& operator=(const Vector<T, otherCapacity>&); |
538 | 538 |
539 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | 539 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) |
540 Vector(Vector&&); | 540 Vector(Vector&&); |
541 Vector& operator=(Vector&&); | 541 Vector& operator=(Vector&&); |
542 #endif | 542 #endif |
543 | 543 |
544 size_t size() const { return m_size; } | 544 size_t size() const { return m_size; } |
545 size_t capacity() const { return Base::capacity(); } | 545 size_t capacity() const { return Base::capacity(); } |
546 bool isEmpty() const { return !size(); } | 546 bool isEmpty() const { return !size(); } |
547 | 547 |
548 T& at(size_t i) | 548 T& at(size_t i) |
549 { | 549 { |
550 RELEASE_ASSERT(i < size()); | 550 RELEASE_ASSERT(i < size()); |
551 return Base::buffer()[i]; | 551 return Base::buffer()[i]; |
552 } | 552 } |
553 const T& at(size_t i) const | 553 const T& at(size_t i) const |
554 { | 554 { |
555 RELEASE_ASSERT(i < size()); | 555 RELEASE_ASSERT(i < size()); |
556 return Base::buffer()[i]; | 556 return Base::buffer()[i]; |
557 } | 557 } |
558 | 558 |
559 T& operator[](size_t i) { return at(i); } | 559 T& operator[](size_t i) { return at(i); } |
560 const T& operator[](size_t i) const { return at(i); } | 560 const T& operator[](size_t i) const { return at(i); } |
561 | 561 |
562 T* data() { return Base::buffer(); } | 562 T* data() { return Base::buffer(); } |
563 const T* data() const { return Base::buffer(); } | 563 const T* data() const { return Base::buffer(); } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 template<typename U> void insert(size_t position, const U&); | 603 template<typename U> void insert(size_t position, const U&); |
604 template<typename U, size_t c> void insert(size_t position, const Vector
<U, c>&); | 604 template<typename U, size_t c> void insert(size_t position, const Vector
<U, c>&); |
605 | 605 |
606 template<typename U> void prepend(const U*, size_t); | 606 template<typename U> void prepend(const U*, size_t); |
607 template<typename U> void prepend(const U&); | 607 template<typename U> void prepend(const U&); |
608 template<typename U, size_t c> void prepend(const Vector<U, c>&); | 608 template<typename U, size_t c> void prepend(const Vector<U, c>&); |
609 | 609 |
610 void remove(size_t position); | 610 void remove(size_t position); |
611 void remove(size_t position, size_t length); | 611 void remove(size_t position, size_t length); |
612 | 612 |
613 void removeLast() | 613 void removeLast() |
614 { | 614 { |
615 ASSERT(!isEmpty()); | 615 ASSERT(!isEmpty()); |
616 shrink(size() - 1); | 616 shrink(size() - 1); |
617 } | 617 } |
618 | 618 |
619 Vector(size_t size, const T& val) | 619 Vector(size_t size, const T& val) |
620 : Base(size) | 620 : Base(size) |
621 , m_size(size) | 621 , m_size(size) |
622 { | 622 { |
623 if (begin()) | 623 if (begin()) |
624 TypeOperations::uninitializedFill(begin(), end(), val); | 624 TypeOperations::uninitializedFill(begin(), end(), val); |
625 } | 625 } |
626 | 626 |
(...skipping 12 matching lines...) Expand all Loading... |
639 | 639 |
640 void reverse(); | 640 void reverse(); |
641 | 641 |
642 void checkConsistency(); | 642 void checkConsistency(); |
643 | 643 |
644 private: | 644 private: |
645 void expandCapacity(size_t newMinCapacity); | 645 void expandCapacity(size_t newMinCapacity); |
646 const T* expandCapacity(size_t newMinCapacity, const T*); | 646 const T* expandCapacity(size_t newMinCapacity, const T*); |
647 bool tryExpandCapacity(size_t newMinCapacity); | 647 bool tryExpandCapacity(size_t newMinCapacity); |
648 const T* tryExpandCapacity(size_t newMinCapacity, const T*); | 648 const T* tryExpandCapacity(size_t newMinCapacity, const T*); |
649 template<typename U> U* expandCapacity(size_t newMinCapacity, U*); | 649 template<typename U> U* expandCapacity(size_t newMinCapacity, U*); |
650 template<typename U> void appendSlowCase(const U&); | 650 template<typename U> void appendSlowCase(const U&); |
651 | 651 |
652 unsigned m_size; | 652 unsigned m_size; |
653 | 653 |
654 using Base::buffer; | 654 using Base::buffer; |
655 using Base::capacity; | 655 using Base::capacity; |
656 using Base::swap; | 656 using Base::swap; |
657 using Base::allocateBuffer; | 657 using Base::allocateBuffer; |
658 using Base::deallocateBuffer; | 658 using Base::deallocateBuffer; |
659 using Base::tryAllocateBuffer; | 659 using Base::tryAllocateBuffer; |
660 using Base::shouldReallocateBuffer; | 660 using Base::shouldReallocateBuffer; |
661 using Base::reallocateBuffer; | 661 using Base::reallocateBuffer; |
662 using Base::restoreInlineBufferIfNeeded; | 662 using Base::restoreInlineBufferIfNeeded; |
663 using Base::releaseBuffer; | 663 using Base::releaseBuffer; |
664 }; | 664 }; |
665 | 665 |
666 template<typename T, size_t inlineCapacity> | 666 template<typename T, size_t inlineCapacity> |
667 Vector<T, inlineCapacity>::Vector(const Vector& other) | 667 Vector<T, inlineCapacity>::Vector(const Vector& other) |
668 : Base(other.capacity()) | 668 : Base(other.capacity()) |
669 , m_size(other.size()) | 669 , m_size(other.size()) |
670 { | 670 { |
671 if (begin()) | 671 if (begin()) |
672 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin(
)); | 672 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin(
)); |
673 } | 673 } |
674 | 674 |
675 template<typename T, size_t inlineCapacity> | 675 template<typename T, size_t inlineCapacity> |
676 template<size_t otherCapacity> | 676 template<size_t otherCapacity> |
677 Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other) | 677 Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other) |
678 : Base(other.capacity()) | 678 : Base(other.capacity()) |
679 , m_size(other.size()) | 679 , m_size(other.size()) |
680 { | 680 { |
681 if (begin()) | 681 if (begin()) |
682 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin(
)); | 682 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin(
)); |
683 } | 683 } |
684 | 684 |
685 template<typename T, size_t inlineCapacity> | 685 template<typename T, size_t inlineCapacity> |
686 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector
<T, inlineCapacity>& other) | 686 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector
<T, inlineCapacity>& other) |
687 { | 687 { |
688 if (&other == this) | 688 if (&other == this) |
689 return *this; | 689 return *this; |
690 | 690 |
691 if (size() > other.size()) | 691 if (size() > other.size()) |
692 shrink(other.size()); | 692 shrink(other.size()); |
693 else if (other.size() > capacity()) { | 693 else if (other.size() > capacity()) { |
694 clear(); | 694 clear(); |
695 reserveCapacity(other.size()); | 695 reserveCapacity(other.size()); |
696 if (!begin()) | 696 if (!begin()) |
697 return *this; | 697 return *this; |
698 } | 698 } |
699 | 699 |
700 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStu
dio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last | 700 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStu
dio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last |
701 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL | 701 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL |
702 if (!begin()) | 702 if (!begin()) |
703 return *this; | 703 return *this; |
704 #endif | 704 #endif |
705 | 705 |
706 std::copy(other.begin(), other.begin() + size(), begin()); | 706 std::copy(other.begin(), other.begin() + size(), begin()); |
707 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), e
nd()); | 707 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), e
nd()); |
708 m_size = other.size(); | 708 m_size = other.size(); |
709 | 709 |
710 return *this; | 710 return *this; |
711 } | 711 } |
712 | 712 |
713 inline bool typelessPointersAreEqual(const void* a, const void* b) { return
a == b; } | 713 inline bool typelessPointersAreEqual(const void* a, const void* b) { return
a == b; } |
714 | 714 |
715 template<typename T, size_t inlineCapacity> | 715 template<typename T, size_t inlineCapacity> |
716 template<size_t otherCapacity> | 716 template<size_t otherCapacity> |
717 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector
<T, otherCapacity>& other) | 717 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector
<T, otherCapacity>& other) |
718 { | 718 { |
719 // If the inline capacities match, we should call the more specific | 719 // If the inline capacities match, we should call the more specific |
720 // template. If the inline capacities don't match, the two objects | 720 // template. If the inline capacities don't match, the two objects |
721 // shouldn't be allocated the same address. | 721 // shouldn't be allocated the same address. |
722 ASSERT(!typelessPointersAreEqual(&other, this)); | 722 ASSERT(!typelessPointersAreEqual(&other, this)); |
723 | 723 |
724 if (size() > other.size()) | 724 if (size() > other.size()) |
725 shrink(other.size()); | 725 shrink(other.size()); |
726 else if (other.size() > capacity()) { | 726 else if (other.size() > capacity()) { |
727 clear(); | 727 clear(); |
728 reserveCapacity(other.size()); | 728 reserveCapacity(other.size()); |
729 if (!begin()) | 729 if (!begin()) |
730 return *this; | 730 return *this; |
731 } | 731 } |
732 | 732 |
733 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStu
dio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last | 733 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStu
dio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last |
734 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL | 734 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL |
735 if (!begin()) | 735 if (!begin()) |
736 return *this; | 736 return *this; |
737 #endif | 737 #endif |
738 | 738 |
739 std::copy(other.begin(), other.begin() + size(), begin()); | 739 std::copy(other.begin(), other.begin() + size(), begin()); |
740 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), e
nd()); | 740 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), e
nd()); |
741 m_size = other.size(); | 741 m_size = other.size(); |
742 | 742 |
(...skipping 17 matching lines...) Expand all Loading... |
760 return *this; | 760 return *this; |
761 } | 761 } |
762 #endif | 762 #endif |
763 | 763 |
764 template<typename T, size_t inlineCapacity> | 764 template<typename T, size_t inlineCapacity> |
765 template<typename U> | 765 template<typename U> |
766 bool Vector<T, inlineCapacity>::contains(const U& value) const | 766 bool Vector<T, inlineCapacity>::contains(const U& value) const |
767 { | 767 { |
768 return find(value) != notFound; | 768 return find(value) != notFound; |
769 } | 769 } |
770 | 770 |
771 template<typename T, size_t inlineCapacity> | 771 template<typename T, size_t inlineCapacity> |
772 template<typename U> | 772 template<typename U> |
773 size_t Vector<T, inlineCapacity>::find(const U& value) const | 773 size_t Vector<T, inlineCapacity>::find(const U& value) const |
774 { | 774 { |
775 const T* b = begin(); | 775 const T* b = begin(); |
776 const T* e = end(); | 776 const T* e = end(); |
777 for (const T* iter = b; iter < e; ++iter) { | 777 for (const T* iter = b; iter < e; ++iter) { |
778 if (*iter == value) | 778 if (*iter == value) |
779 return iter - b; | 779 return iter - b; |
780 } | 780 } |
(...skipping 18 matching lines...) Expand all Loading... |
799 void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize) | 799 void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize) |
800 { | 800 { |
801 if (size() > newSize) | 801 if (size() > newSize) |
802 shrink(newSize); | 802 shrink(newSize); |
803 else if (newSize > capacity()) { | 803 else if (newSize > capacity()) { |
804 clear(); | 804 clear(); |
805 reserveCapacity(newSize); | 805 reserveCapacity(newSize); |
806 if (!begin()) | 806 if (!begin()) |
807 return; | 807 return; |
808 } | 808 } |
809 | 809 |
810 std::fill(begin(), end(), val); | 810 std::fill(begin(), end(), val); |
811 TypeOperations::uninitializedFill(end(), begin() + newSize, val); | 811 TypeOperations::uninitializedFill(end(), begin() + newSize, val); |
812 m_size = newSize; | 812 m_size = newSize; |
813 } | 813 } |
814 | 814 |
815 template<typename T, size_t inlineCapacity> | 815 template<typename T, size_t inlineCapacity> |
816 template<typename Iterator> | 816 template<typename Iterator> |
817 void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end) | 817 void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end) |
818 { | 818 { |
819 for (Iterator it = start; it != end; ++it) | 819 for (Iterator it = start; it != end; ++it) |
820 append(*it); | 820 append(*it); |
821 } | 821 } |
822 | 822 |
823 template<typename T, size_t inlineCapacity> | 823 template<typename T, size_t inlineCapacity> |
824 void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity) | 824 void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity) |
825 { | 825 { |
826 reserveCapacity(std::max(newMinCapacity, std::max(static_cast<size_t>(16
), capacity() + capacity() / 4 + 1))); | 826 reserveCapacity(std::max(newMinCapacity, std::max(static_cast<size_t>(16
), capacity() + capacity() / 4 + 1))); |
827 } | 827 } |
828 | 828 |
829 template<typename T, size_t inlineCapacity> | 829 template<typename T, size_t inlineCapacity> |
830 const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, co
nst T* ptr) | 830 const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, co
nst T* ptr) |
831 { | 831 { |
832 if (ptr < begin() || ptr >= end()) { | 832 if (ptr < begin() || ptr >= end()) { |
833 expandCapacity(newMinCapacity); | 833 expandCapacity(newMinCapacity); |
834 return ptr; | 834 return ptr; |
835 } | 835 } |
836 size_t index = ptr - begin(); | 836 size_t index = ptr - begin(); |
837 expandCapacity(newMinCapacity); | 837 expandCapacity(newMinCapacity); |
838 return begin() + index; | 838 return begin() + index; |
839 } | 839 } |
840 | 840 |
841 template<typename T, size_t inlineCapacity> | 841 template<typename T, size_t inlineCapacity> |
842 bool Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity) | 842 bool Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity) |
843 { | 843 { |
844 return tryReserveCapacity(std::max(newMinCapacity, std::max(static_cast<
size_t>(16), capacity() + capacity() / 4 + 1))); | 844 return tryReserveCapacity(std::max(newMinCapacity, std::max(static_cast<
size_t>(16), capacity() + capacity() / 4 + 1))); |
845 } | 845 } |
846 | 846 |
847 template<typename T, size_t inlineCapacity> | 847 template<typename T, size_t inlineCapacity> |
848 const T* Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity,
const T* ptr) | 848 const T* Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity,
const T* ptr) |
849 { | 849 { |
850 if (ptr < begin() || ptr >= end()) { | 850 if (ptr < begin() || ptr >= end()) { |
851 if (!tryExpandCapacity(newMinCapacity)) | 851 if (!tryExpandCapacity(newMinCapacity)) |
852 return 0; | 852 return 0; |
853 return ptr; | 853 return ptr; |
854 } | 854 } |
855 size_t index = ptr - begin(); | 855 size_t index = ptr - begin(); |
856 if (!tryExpandCapacity(newMinCapacity)) | 856 if (!tryExpandCapacity(newMinCapacity)) |
(...skipping 12 matching lines...) Expand all Loading... |
869 inline void Vector<T, inlineCapacity>::resize(size_t size) | 869 inline void Vector<T, inlineCapacity>::resize(size_t size) |
870 { | 870 { |
871 if (size <= m_size) | 871 if (size <= m_size) |
872 TypeOperations::destruct(begin() + size, end()); | 872 TypeOperations::destruct(begin() + size, end()); |
873 else { | 873 else { |
874 if (size > capacity()) | 874 if (size > capacity()) |
875 expandCapacity(size); | 875 expandCapacity(size); |
876 if (begin()) | 876 if (begin()) |
877 TypeOperations::initialize(end(), begin() + size); | 877 TypeOperations::initialize(end(), begin() + size); |
878 } | 878 } |
879 | 879 |
880 m_size = size; | 880 m_size = size; |
881 } | 881 } |
882 | 882 |
883 template<typename T, size_t inlineCapacity> | 883 template<typename T, size_t inlineCapacity> |
884 void Vector<T, inlineCapacity>::shrink(size_t size) | 884 void Vector<T, inlineCapacity>::shrink(size_t size) |
885 { | 885 { |
886 ASSERT(size <= m_size); | 886 ASSERT(size <= m_size); |
887 TypeOperations::destruct(begin() + size, end()); | 887 TypeOperations::destruct(begin() + size, end()); |
888 m_size = size; | 888 m_size = size; |
889 } | 889 } |
(...skipping 14 matching lines...) Expand all Loading... |
904 { | 904 { |
905 if (newCapacity <= capacity()) | 905 if (newCapacity <= capacity()) |
906 return; | 906 return; |
907 T* oldBuffer = begin(); | 907 T* oldBuffer = begin(); |
908 T* oldEnd = end(); | 908 T* oldEnd = end(); |
909 Base::allocateBuffer(newCapacity); | 909 Base::allocateBuffer(newCapacity); |
910 if (begin()) | 910 if (begin()) |
911 TypeOperations::move(oldBuffer, oldEnd, begin()); | 911 TypeOperations::move(oldBuffer, oldEnd, begin()); |
912 Base::deallocateBuffer(oldBuffer); | 912 Base::deallocateBuffer(oldBuffer); |
913 } | 913 } |
914 | 914 |
915 template<typename T, size_t inlineCapacity> | 915 template<typename T, size_t inlineCapacity> |
916 bool Vector<T, inlineCapacity>::tryReserveCapacity(size_t newCapacity) | 916 bool Vector<T, inlineCapacity>::tryReserveCapacity(size_t newCapacity) |
917 { | 917 { |
918 if (newCapacity <= capacity()) | 918 if (newCapacity <= capacity()) |
919 return true; | 919 return true; |
920 T* oldBuffer = begin(); | 920 T* oldBuffer = begin(); |
921 T* oldEnd = end(); | 921 T* oldEnd = end(); |
922 if (!Base::tryAllocateBuffer(newCapacity)) | 922 if (!Base::tryAllocateBuffer(newCapacity)) |
923 return false; | 923 return false; |
924 ASSERT(begin()); | 924 ASSERT(begin()); |
925 TypeOperations::move(oldBuffer, oldEnd, begin()); | 925 TypeOperations::move(oldBuffer, oldEnd, begin()); |
926 Base::deallocateBuffer(oldBuffer); | 926 Base::deallocateBuffer(oldBuffer); |
927 return true; | 927 return true; |
928 } | 928 } |
929 | 929 |
930 template<typename T, size_t inlineCapacity> | 930 template<typename T, size_t inlineCapacity> |
931 inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initial
Capacity) | 931 inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initial
Capacity) |
932 { | 932 { |
933 ASSERT(!m_size); | 933 ASSERT(!m_size); |
934 ASSERT(capacity() == inlineCapacity); | 934 ASSERT(capacity() == inlineCapacity); |
935 if (initialCapacity > inlineCapacity) | 935 if (initialCapacity > inlineCapacity) |
936 Base::allocateBuffer(initialCapacity); | 936 Base::allocateBuffer(initialCapacity); |
937 } | 937 } |
938 | 938 |
939 template<typename T, size_t inlineCapacity> | 939 template<typename T, size_t inlineCapacity> |
940 void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity) | 940 void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity) |
941 { | 941 { |
942 if (newCapacity >= capacity()) | 942 if (newCapacity >= capacity()) |
943 return; | 943 return; |
944 | 944 |
945 if (newCapacity < size()) | 945 if (newCapacity < size()) |
946 shrink(newCapacity); | 946 shrink(newCapacity); |
947 | 947 |
948 T* oldBuffer = begin(); | 948 T* oldBuffer = begin(); |
949 if (newCapacity > 0) { | 949 if (newCapacity > 0) { |
950 if (Base::shouldReallocateBuffer(newCapacity)) { | 950 if (Base::shouldReallocateBuffer(newCapacity)) { |
951 Base::reallocateBuffer(newCapacity); | 951 Base::reallocateBuffer(newCapacity); |
952 return; | 952 return; |
953 } | 953 } |
954 | 954 |
955 T* oldEnd = end(); | 955 T* oldEnd = end(); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 if (!begin()) | 1064 if (!begin()) |
1065 return; | 1065 return; |
1066 } | 1066 } |
1067 RELEASE_ASSERT(newSize >= m_size); | 1067 RELEASE_ASSERT(newSize >= m_size); |
1068 T* spot = begin() + position; | 1068 T* spot = begin() + position; |
1069 TypeOperations::moveOverlapping(spot, end(), spot + dataSize); | 1069 TypeOperations::moveOverlapping(spot, end(), spot + dataSize); |
1070 for (size_t i = 0; i < dataSize; ++i) | 1070 for (size_t i = 0; i < dataSize; ++i) |
1071 new (NotNull, &spot[i]) T(data[i]); | 1071 new (NotNull, &spot[i]) T(data[i]); |
1072 m_size = newSize; | 1072 m_size = newSize; |
1073 } | 1073 } |
1074 | 1074 |
1075 template<typename T, size_t inlineCapacity> template<typename U> | 1075 template<typename T, size_t inlineCapacity> template<typename U> |
1076 inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val) | 1076 inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val) |
1077 { | 1077 { |
1078 RELEASE_ASSERT(position <= size()); | 1078 RELEASE_ASSERT(position <= size()); |
1079 const U* data = &val; | 1079 const U* data = &val; |
1080 if (size() == capacity()) { | 1080 if (size() == capacity()) { |
1081 data = expandCapacity(size() + 1, data); | 1081 data = expandCapacity(size() + 1, data); |
1082 if (!begin()) | 1082 if (!begin()) |
1083 return; | 1083 return; |
1084 } | 1084 } |
1085 T* spot = begin() + position; | 1085 T* spot = begin() + position; |
1086 TypeOperations::moveOverlapping(spot, end(), spot + 1); | 1086 TypeOperations::moveOverlapping(spot, end(), spot + 1); |
1087 new (NotNull, spot) T(*data); | 1087 new (NotNull, spot) T(*data); |
1088 ++m_size; | 1088 ++m_size; |
1089 } | 1089 } |
1090 | 1090 |
1091 template<typename T, size_t inlineCapacity> template<typename U, size_t c> | 1091 template<typename T, size_t inlineCapacity> template<typename U, size_t c> |
1092 inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<
U, c>& val) | 1092 inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<
U, c>& val) |
1093 { | 1093 { |
1094 insert(position, val.begin(), val.size()); | 1094 insert(position, val.begin(), val.size()); |
1095 } | 1095 } |
1096 | 1096 |
1097 template<typename T, size_t inlineCapacity> template<typename U> | 1097 template<typename T, size_t inlineCapacity> template<typename U> |
1098 void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize) | 1098 void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize) |
1099 { | 1099 { |
1100 insert(0, data, dataSize); | 1100 insert(0, data, dataSize); |
1101 } | 1101 } |
1102 | 1102 |
1103 template<typename T, size_t inlineCapacity> template<typename U> | 1103 template<typename T, size_t inlineCapacity> template<typename U> |
1104 inline void Vector<T, inlineCapacity>::prepend(const U& val) | 1104 inline void Vector<T, inlineCapacity>::prepend(const U& val) |
1105 { | 1105 { |
1106 insert(0, val); | 1106 insert(0, val); |
1107 } | 1107 } |
1108 | 1108 |
1109 template<typename T, size_t inlineCapacity> template<typename U, size_t c> | 1109 template<typename T, size_t inlineCapacity> template<typename U, size_t c> |
1110 inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val) | 1110 inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val) |
1111 { | 1111 { |
1112 insert(0, val.begin(), val.size()); | 1112 insert(0, val.begin(), val.size()); |
1113 } | 1113 } |
1114 | 1114 |
1115 template<typename T, size_t inlineCapacity> | 1115 template<typename T, size_t inlineCapacity> |
1116 inline void Vector<T, inlineCapacity>::remove(size_t position) | 1116 inline void Vector<T, inlineCapacity>::remove(size_t position) |
1117 { | 1117 { |
1118 RELEASE_ASSERT(position < size()); | 1118 RELEASE_ASSERT(position < size()); |
1119 T* spot = begin() + position; | 1119 T* spot = begin() + position; |
1120 spot->~T(); | 1120 spot->~T(); |
1121 TypeOperations::moveOverlapping(spot + 1, end(), spot); | 1121 TypeOperations::moveOverlapping(spot + 1, end(), spot); |
1122 --m_size; | 1122 --m_size; |
1123 } | 1123 } |
1124 | 1124 |
1125 template<typename T, size_t inlineCapacity> | 1125 template<typename T, size_t inlineCapacity> |
1126 inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length
) | 1126 inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length
) |
1127 { | 1127 { |
1128 ASSERT_WITH_SECURITY_IMPLICATION(position <= size()); | 1128 ASSERT_WITH_SECURITY_IMPLICATION(position <= size()); |
1129 RELEASE_ASSERT(position + length <= size()); | 1129 RELEASE_ASSERT(position + length <= size()); |
1130 T* beginSpot = begin() + position; | 1130 T* beginSpot = begin() + position; |
1131 T* endSpot = beginSpot + length; | 1131 T* endSpot = beginSpot + length; |
1132 TypeOperations::destruct(beginSpot, endSpot); | 1132 TypeOperations::destruct(beginSpot, endSpot); |
1133 TypeOperations::moveOverlapping(endSpot, end(), beginSpot); | 1133 TypeOperations::moveOverlapping(endSpot, end(), beginSpot); |
1134 m_size -= length; | 1134 m_size -= length; |
1135 } | 1135 } |
1136 | 1136 |
1137 template<typename T, size_t inlineCapacity> | 1137 template<typename T, size_t inlineCapacity> |
1138 inline void Vector<T, inlineCapacity>::reverse() | 1138 inline void Vector<T, inlineCapacity>::reverse() |
1139 { | 1139 { |
1140 for (size_t i = 0; i < m_size / 2; ++i) | 1140 for (size_t i = 0; i < m_size / 2; ++i) |
1141 std::swap(at(i), at(m_size - 1 - i)); | 1141 std::swap(at(i), at(m_size - 1 - i)); |
1142 } | 1142 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, i
nlineCapacity>& b) | 1185 inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, i
nlineCapacity>& b) |
1186 { | 1186 { |
1187 return !(a == b); | 1187 return !(a == b); |
1188 } | 1188 } |
1189 | 1189 |
1190 } // namespace WTF | 1190 } // namespace WTF |
1191 | 1191 |
1192 using WTF::Vector; | 1192 using WTF::Vector; |
1193 | 1193 |
1194 #endif // WTF_Vector_h | 1194 #endif // WTF_Vector_h |
OLD | NEW |