1 /* 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 * 19 */ 20 21 #ifndef WTF_Vector_h 22 #define WTF_Vector_h 23 24 #include "FastAllocBase.h" 25 #include "Noncopyable.h" 26 #include "NotFound.h" 27 #include "VectorTraits.h" 28 #include <limits> 29 #include <utility> 30 31 #if PLATFORM(QT) 32 #include <QDataStream> 33 #endif 34 35 namespace WTF { 36 37 using std::min; 38 using std::max; 39 40 // WTF_ALIGN_OF / WTF_ALIGNED 41 #if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(WINSCW) 42 #define WTF_ALIGN_OF(type) __alignof__(type) 43 #define WTF_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((__aligned__(n))) 44 #elif COMPILER(MSVC) 45 #define WTF_ALIGN_OF(type) __alignof(type) 46 #define WTF_ALIGNED(variable_type, variable, n) __declspec(align(n)) variable_type variable 47 #else 48 #error WTF_ALIGN macros need alignment control. 49 #endif 50 51 #if COMPILER(GCC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303) 52 typedef char __attribute__((__may_alias__)) AlignedBufferChar; 53 #else 54 typedef char AlignedBufferChar; 55 #endif 56 57 template <size_t size, size_t alignment> struct AlignedBuffer; 58 template <size_t size> struct AlignedBuffer<size, 1> { AlignedBufferChar buffer[size]; }; 59 template <size_t size> struct AlignedBuffer<size, 2> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2); }; 60 template <size_t size> struct AlignedBuffer<size, 4> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4); }; 61 template <size_t size> struct AlignedBuffer<size, 8> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8); }; 62 template <size_t size> struct AlignedBuffer<size, 16> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); }; 63 template <size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); }; 64 template <size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); }; 65 66 template <bool needsDestruction, typename T> 67 class VectorDestructor; 68 69 template<typename T> 70 struct VectorDestructor<false, T> 71 { 72 static void destruct(T*, T*) {} 73 }; 74 75 template<typename T> 76 struct VectorDestructor<true, T> 77 { 78 static void destruct(T* begin, T* end) 79 { 80 for (T* cur = begin; cur != end; ++cur) 81 cur->~T(); 82 } 83 }; 84 85 template <bool needsInitialization, bool canInitializeWithMemset, typename T> 86 class VectorInitializer; 87 88 template<bool ignore, typename T> 89 struct VectorInitializer<false, ignore, T> 90 { 91 static void initialize(T*, T*) {} 92 }; 93 94 template<typename T> 95 struct VectorInitializer<true, false, T> 96 { 97 static void initialize(T* begin, T* end) 98 { 99 for (T* cur = begin; cur != end; ++cur) 100 new (cur) T; 101 } 102 }; 103 104 template<typename T> 105 struct VectorInitializer<true, true, T> 106 { 107 static void initialize(T* begin, T* end) 108 { 109 memset(begin, 0, reinterpret_cast<char*>(end) - reinterpret_cast<char*>(begin)); 110 } 111 }; 112 113 template <bool canMoveWithMemcpy, typename T> 114 class VectorMover; 115 116 template<typename T> 117 struct VectorMover<false, T> 118 { 119 static void move(const T* src, const T* srcEnd, T* dst) 120 { 121 while (src != srcEnd) { 122 new (dst) T(*src); 123 src->~T(); 124 ++dst; 125 ++src; 126 } 127 } 128 static void moveOverlapping(const T* src, const T* srcEnd, T* dst) 129 { 130 if (src > dst) 131 move(src, srcEnd, dst); 132 else { 133 T* dstEnd = dst + (srcEnd - src); 134 while (src != srcEnd) { 135 --srcEnd; 136 --dstEnd; 137 new (dstEnd) T(*srcEnd); 138 srcEnd->~T(); 139 } 140 } 141 } 142 }; 143 144 template<typename T> 145 struct VectorMover<true, T> 146 { 147 static void move(const T* src, const T* srcEnd, T* dst) 148 { 149 memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src)); 150 } 151 static void moveOverlapping(const T* src, const T* srcEnd, T* dst) 152 { 153 memmove(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src)); 154 } 155 }; 156 157 template <bool canCopyWithMemcpy, typename T> 158 class VectorCopier; 159 160 template<typename T> 161 struct VectorCopier<false, T> 162 { 163 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) 164 { 165 while (src != srcEnd) { 166 new (dst) T(*src); 167 ++dst; 168 ++src; 169 } 170 } 171 }; 172 173 template<typename T> 174 struct VectorCopier<true, T> 175 { 176 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) 177 { 178 memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src)); 179 } 180 }; 181 182 template <bool canFillWithMemset, typename T> 183 class VectorFiller; 184 185 template<typename T> 186 struct VectorFiller<false, T> 187 { 188 static void uninitializedFill(T* dst, T* dstEnd, const T& val) 189 { 190 while (dst != dstEnd) { 191 new (dst) T(val); 192 ++dst; 193 } 194 } 195 }; 196 197 template<typename T> 198 struct VectorFiller<true, T> 199 { 200 static void uninitializedFill(T* dst, T* dstEnd, const T& val) 201 { 202 ASSERT(sizeof(T) == sizeof(char)); 203 memset(dst, val, dstEnd - dst); 204 } 205 }; 206 207 template<bool canCompareWithMemcmp, typename T> 208 class VectorComparer; 209 210 template<typename T> 211 struct VectorComparer<false, T> 212 { 213 static bool compare(const T* a, const T* b, size_t size) 214 { 215 for (size_t i = 0; i < size; ++i) 216 if (a[i] != b[i]) 217 return false; 218 return true; 219 } 220 }; 221 222 template<typename T> 223 struct VectorComparer<true, T> 224 { 225 static bool compare(const T* a, const T* b, size_t size) 226 { 227 return memcmp(a, b, sizeof(T) * size) == 0; 228 } 229 }; 230 231 template<typename T> 232 struct VectorTypeOperations 233 { 234 static void destruct(T* begin, T* end) 235 { 236 VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, end); 237 } 238 239 static void initialize(T* begin, T* end) 240 { 241 VectorInitializer<VectorTraits<T>::needsInitialization, VectorTraits<T>::canInitializeWithMemset, T>::initialize(begin, end); 242 } 243 244 static void move(const T* src, const T* srcEnd, T* dst) 245 { 246 VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::move(src, srcEnd, dst); 247 } 248 249 static void moveOverlapping(const T* src, const T* srcEnd, T* dst) 250 { 251 VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::moveOverlapping(src, srcEnd, dst); 252 } 253 254 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) 255 { 256 VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(src, srcEnd, dst); 257 } 258 259 static void uninitializedFill(T* dst, T* dstEnd, const T& val) 260 { 261 VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFill(dst, dstEnd, val); 262 } 263 264 static bool compare(const T* a, const T* b, size_t size) 265 { 266 return VectorComparer<VectorTraits<T>::canCompareWithMemcmp, T>::compare(a, b, size); 267 } 268 }; 269 270 template<typename T> 271 class VectorBufferBase : public Noncopyable { 272 public: 273 void allocateBuffer(size_t newCapacity) 274 { 275 m_capacity = newCapacity; 276 if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T)) 277 CRASH(); 278 m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T))); 279 } 280 281 void deallocateBuffer(T* bufferToDeallocate) 282 { 283 if (m_buffer == bufferToDeallocate) { 284 m_buffer = 0; 285 m_capacity = 0; 286 } 287 fastFree(bufferToDeallocate); 288 } 289 290 T* buffer() { return m_buffer; } 291 const T* buffer() const { return m_buffer; } 292 T** bufferSlot() { return &m_buffer; } 293 size_t capacity() const { return m_capacity; } 294 295 T* releaseBuffer() 296 { 297 T* buffer = m_buffer; 298 m_buffer = 0; 299 m_capacity = 0; 300 return buffer; 301 } 302 303 protected: 304 VectorBufferBase() 305 : m_buffer(0) 306 , m_capacity(0) 307 { 308 } 309 310 VectorBufferBase(T* buffer, size_t capacity) 311 : m_buffer(buffer) 312 , m_capacity(capacity) 313 { 314 } 315 316 ~VectorBufferBase() 317 { 318 // FIXME: It would be nice to find a way to ASSERT that m_buffer hasn't leaked here. 319 } 320 321 T* m_buffer; 322 size_t m_capacity; 323 }; 324 325 template<typename T, size_t inlineCapacity> 326 class VectorBuffer; 327 328 template<typename T> 329 class VectorBuffer<T, 0> : private VectorBufferBase<T> { 330 private: 331 typedef VectorBufferBase<T> Base; 332 public: 333 VectorBuffer() 334 { 335 } 336 337 VectorBuffer(size_t capacity) 338 { 339 allocateBuffer(capacity); 340 } 341 342 ~VectorBuffer() 343 { 344 deallocateBuffer(buffer()); 345 } 346 347 void swap(VectorBuffer<T, 0>& other) 348 { 349 std::swap(m_buffer, other.m_buffer); 350 std::swap(m_capacity, other.m_capacity); 351 } 352 353 void restoreInlineBufferIfNeeded() { } 354 355 using Base::allocateBuffer; 356 using Base::deallocateBuffer; 357 358 using Base::buffer; 359 using Base::bufferSlot; 360 using Base::capacity; 361 362 using Base::releaseBuffer; 363 private: 364 using Base::m_buffer; 365 using Base::m_capacity; 366 }; 367 368 template<typename T, size_t inlineCapacity> 369 class VectorBuffer : private VectorBufferBase<T> { 370 private: 371 typedef VectorBufferBase<T> Base; 372 public: 373 VectorBuffer() 374 : Base(inlineBuffer(), inlineCapacity) 375 { 376 } 377 378 VectorBuffer(size_t capacity) 379 : Base(inlineBuffer(), inlineCapacity) 380 { 381 if (capacity > inlineCapacity) 382 Base::allocateBuffer(capacity); 383 } 384 385 ~VectorBuffer() 386 { 387 deallocateBuffer(buffer()); 388 } 389 390 void allocateBuffer(size_t newCapacity) 391 { 392 if (newCapacity > inlineCapacity) 393 Base::allocateBuffer(newCapacity); 394 else { 395 m_buffer = inlineBuffer(); 396 m_capacity = inlineCapacity; 397 } 398 } 399 400 void deallocateBuffer(T* bufferToDeallocate) 401 { 402 if (bufferToDeallocate == inlineBuffer()) 403 return; 404 Base::deallocateBuffer(bufferToDeallocate); 405 } 406 407 void restoreInlineBufferIfNeeded() 408 { 409 if (m_buffer) 410 return; 411 m_buffer = inlineBuffer(); 412 m_capacity = inlineCapacity; 413 } 414 415 using Base::buffer; 416 using Base::bufferSlot; 417 using Base::capacity; 418 419 T* releaseBuffer() 420 { 421 if (buffer() == inlineBuffer()) 422 return 0; 423 return Base::releaseBuffer(); 424 } 425 426 private: 427 using Base::m_buffer; 428 using Base::m_capacity; 429 430 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); 431 T* inlineBuffer() { return reinterpret_cast<T*>(m_inlineBuffer.buffer); } 432 433 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; 434 }; 435 436 template<typename T, size_t inlineCapacity = 0> 437 class Vector : public FastAllocBase { 438 private: 439 typedef VectorBuffer<T, inlineCapacity> Buffer; 440 typedef VectorTypeOperations<T> TypeOperations; 441 442 public: 443 typedef T ValueType; 444 445 typedef T* iterator; 446 typedef const T* const_iterator; 447 448 Vector() 449 : m_size(0) 450 { 451 } 452 453 explicit Vector(size_t size) 454 : m_size(size) 455 , m_buffer(size) 456 { 457 if (begin()) 458 TypeOperations::initialize(begin(), end()); 459 } 460 461 ~Vector() 462 { 463 if (m_size) shrink(0); 464 } 465 466 Vector(const Vector&); 467 template<size_t otherCapacity> 468 Vector(const Vector<T, otherCapacity>&); 469 470 Vector& operator=(const Vector&); 471 template<size_t otherCapacity> 472 Vector& operator=(const Vector<T, otherCapacity>&); 473 474 size_t size() const { return m_size; } 475 size_t capacity() const { return m_buffer.capacity(); } 476 bool isEmpty() const { return !size(); } 477 478 T& at(size_t i) 479 { 480 ASSERT(i < size()); 481 return m_buffer.buffer()[i]; 482 } 483 const T& at(size_t i) const 484 { 485 ASSERT(i < size()); 486 return m_buffer.buffer()[i]; 487 } 488 489 T& operator[](size_t i) { return at(i); } 490 const T& operator[](size_t i) const { return at(i); } 491 492 T* data() { return m_buffer.buffer(); } 493 const T* data() const { return m_buffer.buffer(); } 494 T** dataSlot() { return m_buffer.bufferSlot(); } 495 496 iterator begin() { return data(); } 497 iterator end() { return begin() + m_size; } 498 const_iterator begin() const { return data(); } 499 const_iterator end() const { return begin() + m_size; } 500 501 T& first() { return at(0); } 502 const T& first() const { return at(0); } 503 T& last() { return at(size() - 1); } 504 const T& last() const { return at(size() - 1); } 505 506 template<typename U> size_t find(const U&) const; 507 508 void shrink(size_t size); 509 void grow(size_t size); 510 void resize(size_t size); 511 void reserveCapacity(size_t newCapacity); 512 void reserveInitialCapacity(size_t initialCapacity); 513 void shrinkCapacity(size_t newCapacity); 514 void shrinkToFit() { shrinkCapacity(size()); } 515 516 void clear() { shrinkCapacity(0); } 517 518 template<typename U> void append(const U*, size_t); 519 template<typename U> void append(const U&); 520 template<typename U> void uncheckedAppend(const U& val); 521 template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&); 522 523 template<typename U> void insert(size_t position, const U*, size_t); 524 template<typename U> void insert(size_t position, const U&); 525 template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&); 526 527 template<typename U> void prepend(const U*, size_t); 528 template<typename U> void prepend(const U&); 529 template<typename U, size_t c> void prepend(const Vector<U, c>&); 530 531 void remove(size_t position); 532 void remove(size_t position, size_t length); 533 534 void removeLast() 535 { 536 ASSERT(!isEmpty()); 537 shrink(size() - 1); 538 } 539 540 Vector(size_t size, const T& val) 541 : m_size(size) 542 , m_buffer(size) 543 { 544 if (begin()) 545 TypeOperations::uninitializedFill(begin(), end(), val); 546 } 547 548 void fill(const T&, size_t); 549 void fill(const T& val) { fill(val, size()); } 550 551 template<typename Iterator> void appendRange(Iterator start, Iterator end); 552 553 T* releaseBuffer(); 554 555 void swap(Vector<T, inlineCapacity>& other) 556 { 557 std::swap(m_size, other.m_size); 558 m_buffer.swap(other.m_buffer); 559 } 560 561 private: 562 void expandCapacity(size_t newMinCapacity); 563 const T* expandCapacity(size_t newMinCapacity, const T*); 564 template<typename U> U* expandCapacity(size_t newMinCapacity, U*); 565 566 size_t m_size; 567 Buffer m_buffer; 568 }; 569 570 #if PLATFORM(QT) 571 template<typename T> 572 QDataStream& operator<<(QDataStream& stream, const Vector<T>& data) 573 { 574 stream << qint64(data.size()); 575 foreach (const T& i, data) 576 stream << i; 577 return stream; 578 } 579 580 template<typename T> 581 QDataStream& operator>>(QDataStream& stream, Vector<T>& data) 582 { 583 data.clear(); 584 qint64 count; 585 T item; 586 stream >> count; 587 data.reserveCapacity(count); 588 for (qint64 i = 0; i < count; ++i) { 589 stream >> item; 590 data.append(item); 591 } 592 return stream; 593 } 594 #endif 595 596 template<typename T, size_t inlineCapacity> 597 Vector<T, inlineCapacity>::Vector(const Vector& other) 598 : m_size(other.size()) 599 , m_buffer(other.capacity()) 600 { 601 if (begin()) 602 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); 603 } 604 605 template<typename T, size_t inlineCapacity> 606 template<size_t otherCapacity> 607 Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other) 608 : m_size(other.size()) 609 , m_buffer(other.capacity()) 610 { 611 if (begin()) 612 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); 613 } 614 615 template<typename T, size_t inlineCapacity> 616 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other) 617 { 618 if (&other == this) 619 return *this; 620 621 if (size() > other.size()) 622 shrink(other.size()); 623 else if (other.size() > capacity()) { 624 clear(); 625 reserveCapacity(other.size()); 626 if (!begin()) 627 return *this; 628 } 629 630 std::copy(other.begin(), other.begin() + size(), begin()); 631 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end()); 632 m_size = other.size(); 633 634 return *this; 635 } 636 637 template<typename T, size_t inlineCapacity> 638 template<size_t otherCapacity> 639 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other) 640 { 641 if (&other == this) 642 return *this; 643 644 if (size() > other.size()) 645 shrink(other.size()); 646 else if (other.size() > capacity()) { 647 clear(); 648 reserveCapacity(other.size()); 649 if (!begin()) 650 return *this; 651 } 652 653 std::copy(other.begin(), other.begin() + size(), begin()); 654 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end()); 655 m_size = other.size(); 656 657 return *this; 658 } 659 660 template<typename T, size_t inlineCapacity> 661 template<typename U> 662 size_t Vector<T, inlineCapacity>::find(const U& value) const 663 { 664 for (size_t i = 0; i < size(); ++i) { 665 if (at(i) == value) 666 return i; 667 } 668 return notFound; 669 } 670 671 template<typename T, size_t inlineCapacity> 672 void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize) 673 { 674 if (size() > newSize) 675 shrink(newSize); 676 else if (newSize > capacity()) { 677 clear(); 678 reserveCapacity(newSize); 679 if (!begin()) 680 return; 681 } 682 683 std::fill(begin(), end(), val); 684 TypeOperations::uninitializedFill(end(), begin() + newSize, val); 685 m_size = newSize; 686 } 687 688 template<typename T, size_t inlineCapacity> 689 template<typename Iterator> 690 void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end) 691 { 692 for (Iterator it = start; it != end; ++it) 693 append(*it); 694 } 695 696 template<typename T, size_t inlineCapacity> 697 void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity) 698 { 699 reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1))); 700 } 701 702 template<typename T, size_t inlineCapacity> 703 const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr) 704 { 705 if (ptr < begin() || ptr >= end()) { 706 expandCapacity(newMinCapacity); 707 return ptr; 708 } 709 size_t index = ptr - begin(); 710 expandCapacity(newMinCapacity); 711 return begin() + index; 712 } 713 714 template<typename T, size_t inlineCapacity> template<typename U> 715 inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr) 716 { 717 expandCapacity(newMinCapacity); 718 return ptr; 719 } 720 721 template<typename T, size_t inlineCapacity> 722 inline void Vector<T, inlineCapacity>::resize(size_t size) 723 { 724 if (size <= m_size) 725 TypeOperations::destruct(begin() + size, end()); 726 else { 727 if (size > capacity()) 728 expandCapacity(size); 729 if (begin()) 730 TypeOperations::initialize(end(), begin() + size); 731 } 732 733 m_size = size; 734 } 735 736 template<typename T, size_t inlineCapacity> 737 void Vector<T, inlineCapacity>::shrink(size_t size) 738 { 739 ASSERT(size <= m_size); 740 TypeOperations::destruct(begin() + size, end()); 741 m_size = size; 742 } 743 744 template<typename T, size_t inlineCapacity> 745 void Vector<T, inlineCapacity>::grow(size_t size) 746 { 747 ASSERT(size >= m_size); 748 if (size > capacity()) 749 expandCapacity(size); 750 if (begin()) 751 TypeOperations::initialize(end(), begin() + size); 752 m_size = size; 753 } 754 755 template<typename T, size_t inlineCapacity> 756 void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity) 757 { 758 if (newCapacity <= capacity()) 759 return; 760 T* oldBuffer = begin(); 761 T* oldEnd = end(); 762 m_buffer.allocateBuffer(newCapacity); 763 if (begin()) 764 TypeOperations::move(oldBuffer, oldEnd, begin()); 765 m_buffer.deallocateBuffer(oldBuffer); 766 } 767 768 template<typename T, size_t inlineCapacity> 769 inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity) 770 { 771 ASSERT(!m_size); 772 ASSERT(capacity() == inlineCapacity); 773 if (initialCapacity > inlineCapacity) 774 m_buffer.allocateBuffer(initialCapacity); 775 } 776 777 template<typename T, size_t inlineCapacity> 778 void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity) 779 { 780 if (newCapacity >= capacity()) 781 return; 782 783 if (newCapacity < size()) 784 shrink(newCapacity); 785 786 T* oldBuffer = begin(); 787 if (newCapacity > 0) { 788 T* oldEnd = end(); 789 m_buffer.allocateBuffer(newCapacity); 790 if (begin() != oldBuffer) 791 TypeOperations::move(oldBuffer, oldEnd, begin()); 792 } 793 794 m_buffer.deallocateBuffer(oldBuffer); 795 m_buffer.restoreInlineBufferIfNeeded(); 796 } 797 798 // Templatizing these is better than just letting the conversion happen implicitly, 799 // because for instance it allows a PassRefPtr to be appended to a RefPtr vector 800 // without refcount thrash. 801 802 template<typename T, size_t inlineCapacity> template<typename U> 803 void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize) 804 { 805 size_t newSize = m_size + dataSize; 806 if (newSize > capacity()) { 807 data = expandCapacity(newSize, data); 808 if (!begin()) 809 return; 810 } 811 if (newSize < m_size) 812 CRASH(); 813 T* dest = end(); 814 for (size_t i = 0; i < dataSize; ++i) 815 new (&dest[i]) T(data[i]); 816 m_size = newSize; 817 } 818 819 template<typename T, size_t inlineCapacity> template<typename U> 820 ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val) 821 { 822 const U* ptr = &val; 823 if (size() == capacity()) { 824 ptr = expandCapacity(size() + 1, ptr); 825 if (!begin()) 826 return; 827 } 828 829 #if COMPILER(MSVC7) 830 // FIXME: MSVC7 generates compilation errors when trying to assign 831 // a pointer to a Vector of its base class (i.e. can't downcast). So far 832 // I've been unable to determine any logical reason for this, so I can 833 // only assume it is a bug with the compiler. Casting is a bad solution, 834 // however, because it subverts implicit conversions, so a better 835 // one is needed. 836 new (end()) T(static_cast<T>(*ptr)); 837 #else 838 new (end()) T(*ptr); 839 #endif 840 ++m_size; 841 } 842 843 // This version of append saves a branch in the case where you know that the 844 // vector's capacity is large enough for the append to succeed. 845 846 template<typename T, size_t inlineCapacity> template<typename U> 847 inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val) 848 { 849 ASSERT(size() < capacity()); 850 const U* ptr = &val; 851 new (end()) T(*ptr); 852 ++m_size; 853 } 854 855 // This method should not be called append, a better name would be appendElements. 856 // It could also be eliminated entirely, and call sites could just use 857 // appendRange(val.begin(), val.end()). 858 template<typename T, size_t inlineCapacity> template<size_t otherCapacity> 859 inline void Vector<T, inlineCapacity>::append(const Vector<T, otherCapacity>& val) 860 { 861 append(val.begin(), val.size()); 862 } 863 864 template<typename T, size_t inlineCapacity> template<typename U> 865 void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize) 866 { 867 ASSERT(position <= size()); 868 size_t newSize = m_size + dataSize; 869 if (newSize > capacity()) { 870 data = expandCapacity(newSize, data); 871 if (!begin()) 872 return; 873 } 874 if (newSize < m_size) 875 CRASH(); 876 T* spot = begin() + position; 877 TypeOperations::moveOverlapping(spot, end(), spot + dataSize); 878 for (size_t i = 0; i < dataSize; ++i) 879 new (&spot[i]) T(data[i]); 880 m_size = newSize; 881 } 882 883 template<typename T, size_t inlineCapacity> template<typename U> 884 inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val) 885 { 886 ASSERT(position <= size()); 887 const U* data = &val; 888 if (size() == capacity()) { 889 data = expandCapacity(size() + 1, data); 890 if (!begin()) 891 return; 892 } 893 T* spot = begin() + position; 894 TypeOperations::moveOverlapping(spot, end(), spot + 1); 895 new (spot) T(*data); 896 ++m_size; 897 } 898 899 template<typename T, size_t inlineCapacity> template<typename U, size_t c> 900 inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val) 901 { 902 insert(position, val.begin(), val.size()); 903 } 904 905 template<typename T, size_t inlineCapacity> template<typename U> 906 void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize) 907 { 908 insert(0, data, dataSize); 909 } 910 911 template<typename T, size_t inlineCapacity> template<typename U> 912 inline void Vector<T, inlineCapacity>::prepend(const U& val) 913 { 914 insert(0, val); 915 } 916 917 template<typename T, size_t inlineCapacity> template<typename U, size_t c> 918 inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val) 919 { 920 insert(0, val.begin(), val.size()); 921 } 922 923 template<typename T, size_t inlineCapacity> 924 inline void Vector<T, inlineCapacity>::remove(size_t position) 925 { 926 ASSERT(position < size()); 927 T* spot = begin() + position; 928 spot->~T(); 929 TypeOperations::moveOverlapping(spot + 1, end(), spot); 930 --m_size; 931 } 932 933 template<typename T, size_t inlineCapacity> 934 inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length) 935 { 936 ASSERT(position < size()); 937 ASSERT(position + length <= size()); 938 T* beginSpot = begin() + position; 939 T* endSpot = beginSpot + length; 940 TypeOperations::destruct(beginSpot, endSpot); 941 TypeOperations::moveOverlapping(endSpot, end(), beginSpot); 942 m_size -= length; 943 } 944 945 template<typename T, size_t inlineCapacity> 946 inline T* Vector<T, inlineCapacity>::releaseBuffer() 947 { 948 T* buffer = m_buffer.releaseBuffer(); 949 if (inlineCapacity && !buffer && m_size) { 950 // If the vector had some data, but no buffer to release, 951 // that means it was using the inline buffer. In that case, 952 // we create a brand new buffer so the caller always gets one. 953 size_t bytes = m_size * sizeof(T); 954 buffer = static_cast<T*>(fastMalloc(bytes)); 955 memcpy(buffer, data(), bytes); 956 } 957 m_size = 0; 958 return buffer; 959 } 960 961 template<typename T, size_t inlineCapacity> 962 void deleteAllValues(const Vector<T, inlineCapacity>& collection) 963 { 964 typedef typename Vector<T, inlineCapacity>::const_iterator iterator; 965 iterator end = collection.end(); 966 for (iterator it = collection.begin(); it != end; ++it) 967 delete *it; 968 } 969 970 template<typename T, size_t inlineCapacity> 971 inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b) 972 { 973 a.swap(b); 974 } 975 976 template<typename T, size_t inlineCapacity> 977 bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b) 978 { 979 if (a.size() != b.size()) 980 return false; 981 982 return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size()); 983 } 984 985 template<typename T, size_t inlineCapacity> 986 inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b) 987 { 988 return !(a == b); 989 } 990 991 992 } // namespace WTF 993 994 using WTF::Vector; 995 996 #endif // WTF_Vector_h 997