Home | History | Annotate | Download | only in wtf
      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 "StdLibExtras.h"
     28 #include "ValueCheck.h"
     29 #include "VectorTraits.h"
     30 #include <limits>
     31 #include <utility>
     32 #include <wtf/Alignment.h>
     33 
     34 #if PLATFORM(QT)
     35 #include <QDataStream>
     36 #endif
     37 
     38 namespace WTF {
     39 
     40     using std::min;
     41     using std::max;
     42 
     43     #if COMPILER(GCC) && !COMPILER(INTEL) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
     44         typedef char __attribute__((__may_alias__)) AlignedBufferChar;
     45     #else
     46         typedef char AlignedBufferChar;
     47     #endif
     48 
     49     template <size_t size, size_t alignment> struct AlignedBuffer;
     50     template <size_t size> struct AlignedBuffer<size, 1> { AlignedBufferChar buffer[size]; };
     51     template <size_t size> struct AlignedBuffer<size, 2> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2);  };
     52     template <size_t size> struct AlignedBuffer<size, 4> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4);  };
     53     template <size_t size> struct AlignedBuffer<size, 8> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8);  };
     54     template <size_t size> struct AlignedBuffer<size, 16> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); };
     55     template <size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); };
     56     template <size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); };
     57 
     58     template <size_t size, size_t alignment>
     59     void swap(AlignedBuffer<size, alignment>& a, AlignedBuffer<size, alignment>& b)
     60     {
     61         for (size_t i = 0; i < size; ++i)
     62             std::swap(a.buffer[i], b.buffer[i]);
     63     }
     64 
     65     template <bool needsDestruction, typename T>
     66     struct VectorDestructor;
     67 
     68     template<typename T>
     69     struct VectorDestructor<false, T>
     70     {
     71         static void destruct(T*, T*) {}
     72     };
     73 
     74     template<typename T>
     75     struct VectorDestructor<true, T>
     76     {
     77         static void destruct(T* begin, T* end)
     78         {
     79             for (T* cur = begin; cur != end; ++cur)
     80                 cur->~T();
     81         }
     82     };
     83 
     84     template <bool needsInitialization, bool canInitializeWithMemset, typename T>
     85     struct VectorInitializer;
     86 
     87     template<bool ignore, typename T>
     88     struct VectorInitializer<false, ignore, T>
     89     {
     90         static void initialize(T*, T*) {}
     91     };
     92 
     93     template<typename T>
     94     struct VectorInitializer<true, false, T>
     95     {
     96         static void initialize(T* begin, T* end)
     97         {
     98             for (T* cur = begin; cur != end; ++cur)
     99                 new (cur) T;
    100         }
    101     };
    102 
    103     template<typename T>
    104     struct VectorInitializer<true, true, T>
    105     {
    106         static void initialize(T* begin, T* end)
    107         {
    108             memset(begin, 0, reinterpret_cast<char*>(end) - reinterpret_cast<char*>(begin));
    109         }
    110     };
    111 
    112     template <bool canMoveWithMemcpy, typename T>
    113     struct VectorMover;
    114 
    115     template<typename T>
    116     struct VectorMover<false, T>
    117     {
    118         static void move(const T* src, const T* srcEnd, T* dst)
    119         {
    120             while (src != srcEnd) {
    121                 new (dst) T(*src);
    122 #if COMPILER(SUNCC) && __SUNPRO_CC <= 0x590
    123                 const_cast<T*>(src)->~T(); // Work around obscure SunCC 12 compiler bug.
    124 #else
    125                 src->~T();
    126 #endif
    127                 ++dst;
    128                 ++src;
    129             }
    130         }
    131         static void moveOverlapping(const T* src, const T* srcEnd, T* dst)
    132         {
    133             if (src > dst)
    134                 move(src, srcEnd, dst);
    135             else {
    136                 T* dstEnd = dst + (srcEnd - src);
    137                 while (src != srcEnd) {
    138                     --srcEnd;
    139                     --dstEnd;
    140                     new (dstEnd) T(*srcEnd);
    141                     srcEnd->~T();
    142                 }
    143             }
    144         }
    145     };
    146 
    147     template<typename T>
    148     struct VectorMover<true, T>
    149     {
    150         static void move(const T* src, const T* srcEnd, T* dst)
    151         {
    152             memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src));
    153         }
    154         static void moveOverlapping(const T* src, const T* srcEnd, T* dst)
    155         {
    156             memmove(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src));
    157         }
    158     };
    159 
    160     template <bool canCopyWithMemcpy, typename T>
    161     struct VectorCopier;
    162 
    163     template<typename T>
    164     struct VectorCopier<false, T>
    165     {
    166         static void uninitializedCopy(const T* src, const T* srcEnd, T* dst)
    167         {
    168             while (src != srcEnd) {
    169                 new (dst) T(*src);
    170                 ++dst;
    171                 ++src;
    172             }
    173         }
    174     };
    175 
    176     template<typename T>
    177     struct VectorCopier<true, T>
    178     {
    179         static void uninitializedCopy(const T* src, const T* srcEnd, T* dst)
    180         {
    181             memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src));
    182         }
    183     };
    184 
    185     template <bool canFillWithMemset, typename T>
    186     struct VectorFiller;
    187 
    188     template<typename T>
    189     struct VectorFiller<false, T>
    190     {
    191         static void uninitializedFill(T* dst, T* dstEnd, const T& val)
    192         {
    193             while (dst != dstEnd) {
    194                 new (dst) T(val);
    195                 ++dst;
    196             }
    197         }
    198     };
    199 
    200     template<typename T>
    201     struct VectorFiller<true, T>
    202     {
    203         static void uninitializedFill(T* dst, T* dstEnd, const T& val)
    204         {
    205             ASSERT(sizeof(T) == sizeof(char));
    206             memset(dst, val, dstEnd - dst);
    207         }
    208     };
    209 
    210     template<bool canCompareWithMemcmp, typename T>
    211     struct VectorComparer;
    212 
    213     template<typename T>
    214     struct VectorComparer<false, T>
    215     {
    216         static bool compare(const T* a, const T* b, size_t size)
    217         {
    218             for (size_t i = 0; i < size; ++i)
    219                 if (a[i] != b[i])
    220                     return false;
    221             return true;
    222         }
    223     };
    224 
    225     template<typename T>
    226     struct VectorComparer<true, T>
    227     {
    228         static bool compare(const T* a, const T* b, size_t size)
    229         {
    230             return memcmp(a, b, sizeof(T) * size) == 0;
    231         }
    232     };
    233 
    234     template<typename T>
    235     struct VectorTypeOperations
    236     {
    237         static void destruct(T* begin, T* end)
    238         {
    239             VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, end);
    240         }
    241 
    242         static void initialize(T* begin, T* end)
    243         {
    244             VectorInitializer<VectorTraits<T>::needsInitialization, VectorTraits<T>::canInitializeWithMemset, T>::initialize(begin, end);
    245         }
    246 
    247         static void move(const T* src, const T* srcEnd, T* dst)
    248         {
    249             VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::move(src, srcEnd, dst);
    250         }
    251 
    252         static void moveOverlapping(const T* src, const T* srcEnd, T* dst)
    253         {
    254             VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::moveOverlapping(src, srcEnd, dst);
    255         }
    256 
    257         static void uninitializedCopy(const T* src, const T* srcEnd, T* dst)
    258         {
    259             VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(src, srcEnd, dst);
    260         }
    261 
    262         static void uninitializedFill(T* dst, T* dstEnd, const T& val)
    263         {
    264             VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFill(dst, dstEnd, val);
    265         }
    266 
    267         static bool compare(const T* a, const T* b, size_t size)
    268         {
    269             return VectorComparer<VectorTraits<T>::canCompareWithMemcmp, T>::compare(a, b, size);
    270         }
    271     };
    272 
    273     template<typename T>
    274     class VectorBufferBase {
    275         WTF_MAKE_NONCOPYABLE(VectorBufferBase);
    276     public:
    277         void allocateBuffer(size_t newCapacity)
    278         {
    279             ASSERT(newCapacity);
    280             m_capacity = newCapacity;
    281             if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
    282                 CRASH();
    283             m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T)));
    284         }
    285 
    286         bool tryAllocateBuffer(size_t newCapacity)
    287         {
    288             ASSERT(newCapacity);
    289             if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
    290                 return false;
    291 
    292             T* newBuffer;
    293             if (tryFastMalloc(newCapacity * sizeof(T)).getValue(newBuffer)) {
    294                 m_capacity = newCapacity;
    295                 m_buffer = newBuffer;
    296                 return true;
    297             }
    298             return false;
    299         }
    300 
    301         void deallocateBuffer(T* bufferToDeallocate)
    302         {
    303             if (m_buffer == bufferToDeallocate) {
    304                 m_buffer = 0;
    305                 m_capacity = 0;
    306             }
    307             fastFree(bufferToDeallocate);
    308         }
    309 
    310         T* buffer() { return m_buffer; }
    311         const T* buffer() const { return m_buffer; }
    312         T** bufferSlot() { return &m_buffer; }
    313         size_t capacity() const { return m_capacity; }
    314 
    315         T* releaseBuffer()
    316         {
    317             T* buffer = m_buffer;
    318             m_buffer = 0;
    319             m_capacity = 0;
    320             return buffer;
    321         }
    322 
    323     protected:
    324         VectorBufferBase()
    325             : m_buffer(0)
    326             , m_capacity(0)
    327         {
    328         }
    329 
    330         VectorBufferBase(T* buffer, size_t capacity)
    331             : m_buffer(buffer)
    332             , m_capacity(capacity)
    333         {
    334         }
    335 
    336         ~VectorBufferBase()
    337         {
    338             // FIXME: It would be nice to find a way to ASSERT that m_buffer hasn't leaked here.
    339         }
    340 
    341         T* m_buffer;
    342         size_t m_capacity;
    343     };
    344 
    345     template<typename T, size_t inlineCapacity>
    346     class VectorBuffer;
    347 
    348     template<typename T>
    349     class VectorBuffer<T, 0> : private VectorBufferBase<T> {
    350     private:
    351         typedef VectorBufferBase<T> Base;
    352     public:
    353         VectorBuffer()
    354         {
    355         }
    356 
    357         VectorBuffer(size_t capacity)
    358         {
    359             // Calling malloc(0) might take a lock and may actually do an
    360             // allocation on some systems (e.g. Brew).
    361             if (capacity)
    362                 allocateBuffer(capacity);
    363         }
    364 
    365         ~VectorBuffer()
    366         {
    367             deallocateBuffer(buffer());
    368         }
    369 
    370         void swap(VectorBuffer<T, 0>& other)
    371         {
    372             std::swap(m_buffer, other.m_buffer);
    373             std::swap(m_capacity, other.m_capacity);
    374         }
    375 
    376         void restoreInlineBufferIfNeeded() { }
    377 
    378         using Base::allocateBuffer;
    379         using Base::tryAllocateBuffer;
    380         using Base::deallocateBuffer;
    381 
    382         using Base::buffer;
    383         using Base::bufferSlot;
    384         using Base::capacity;
    385 
    386         using Base::releaseBuffer;
    387     private:
    388         using Base::m_buffer;
    389         using Base::m_capacity;
    390     };
    391 
    392     template<typename T, size_t inlineCapacity>
    393     class VectorBuffer : private VectorBufferBase<T> {
    394         WTF_MAKE_NONCOPYABLE(VectorBuffer);
    395     private:
    396         typedef VectorBufferBase<T> Base;
    397     public:
    398         VectorBuffer()
    399             : Base(inlineBuffer(), inlineCapacity)
    400         {
    401         }
    402 
    403         VectorBuffer(size_t capacity)
    404             : Base(inlineBuffer(), inlineCapacity)
    405         {
    406             if (capacity > inlineCapacity)
    407                 Base::allocateBuffer(capacity);
    408         }
    409 
    410         ~VectorBuffer()
    411         {
    412             deallocateBuffer(buffer());
    413         }
    414 
    415         void allocateBuffer(size_t newCapacity)
    416         {
    417             // FIXME: This should ASSERT(!m_buffer) to catch misuse/leaks.
    418             if (newCapacity > inlineCapacity)
    419                 Base::allocateBuffer(newCapacity);
    420             else {
    421                 m_buffer = inlineBuffer();
    422                 m_capacity = inlineCapacity;
    423             }
    424         }
    425 
    426         bool tryAllocateBuffer(size_t newCapacity)
    427         {
    428             if (newCapacity > inlineCapacity)
    429                 return Base::tryAllocateBuffer(newCapacity);
    430             m_buffer = inlineBuffer();
    431             m_capacity = inlineCapacity;
    432             return true;
    433         }
    434 
    435         void deallocateBuffer(T* bufferToDeallocate)
    436         {
    437             if (bufferToDeallocate == inlineBuffer())
    438                 return;
    439             Base::deallocateBuffer(bufferToDeallocate);
    440         }
    441 
    442         void swap(VectorBuffer<T, inlineCapacity>& other)
    443         {
    444             if (buffer() == inlineBuffer() && other.buffer() == other.inlineBuffer()) {
    445                 WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
    446                 std::swap(m_capacity, other.m_capacity);
    447             } else if (buffer() == inlineBuffer()) {
    448                 m_buffer = other.m_buffer;
    449                 other.m_buffer = other.inlineBuffer();
    450                 WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
    451                 std::swap(m_capacity, other.m_capacity);
    452             } else if (other.buffer() == other.inlineBuffer()) {
    453                 other.m_buffer = m_buffer;
    454                 m_buffer = inlineBuffer();
    455                 WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
    456                 std::swap(m_capacity, other.m_capacity);
    457             } else {
    458                 std::swap(m_buffer, other.m_buffer);
    459                 std::swap(m_capacity, other.m_capacity);
    460             }
    461         }
    462 
    463         void restoreInlineBufferIfNeeded()
    464         {
    465             if (m_buffer)
    466                 return;
    467             m_buffer = inlineBuffer();
    468             m_capacity = inlineCapacity;
    469         }
    470 
    471         using Base::buffer;
    472         using Base::bufferSlot;
    473         using Base::capacity;
    474 
    475         T* releaseBuffer()
    476         {
    477             if (buffer() == inlineBuffer())
    478                 return 0;
    479             return Base::releaseBuffer();
    480         }
    481 
    482     private:
    483         using Base::m_buffer;
    484         using Base::m_capacity;
    485 
    486         static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T);
    487         T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffer); }
    488 
    489         AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer;
    490     };
    491 
    492     template<typename T, size_t inlineCapacity = 0>
    493     class Vector {
    494         WTF_MAKE_FAST_ALLOCATED;
    495     private:
    496         typedef VectorBuffer<T, inlineCapacity> Buffer;
    497         typedef VectorTypeOperations<T> TypeOperations;
    498 
    499     public:
    500         typedef T ValueType;
    501 
    502         typedef T* iterator;
    503         typedef const T* const_iterator;
    504 
    505         Vector()
    506             : m_size(0)
    507         {
    508         }
    509 
    510         explicit Vector(size_t size)
    511             : m_size(size)
    512             , m_buffer(size)
    513         {
    514             if (begin())
    515                 TypeOperations::initialize(begin(), end());
    516         }
    517 
    518         ~Vector()
    519         {
    520             if (m_size) shrink(0);
    521         }
    522 
    523         Vector(const Vector&);
    524         template<size_t otherCapacity>
    525         Vector(const Vector<T, otherCapacity>&);
    526 
    527         Vector& operator=(const Vector&);
    528         template<size_t otherCapacity>
    529         Vector& operator=(const Vector<T, otherCapacity>&);
    530 
    531         size_t size() const { return m_size; }
    532         size_t capacity() const { return m_buffer.capacity(); }
    533         bool isEmpty() const { return !size(); }
    534 
    535         T& at(size_t i)
    536         {
    537             ASSERT(i < size());
    538             return m_buffer.buffer()[i];
    539         }
    540         const T& at(size_t i) const
    541         {
    542             ASSERT(i < size());
    543             return m_buffer.buffer()[i];
    544         }
    545 
    546         T& operator[](size_t i) { return at(i); }
    547         const T& operator[](size_t i) const { return at(i); }
    548 
    549         T* data() { return m_buffer.buffer(); }
    550         const T* data() const { return m_buffer.buffer(); }
    551         T** dataSlot() { return m_buffer.bufferSlot(); }
    552 
    553         iterator begin() { return data(); }
    554         iterator end() { return begin() + m_size; }
    555         const_iterator begin() const { return data(); }
    556         const_iterator end() const { return begin() + m_size; }
    557 
    558         T& first() { return at(0); }
    559         const T& first() const { return at(0); }
    560         T& last() { return at(size() - 1); }
    561         const T& last() const { return at(size() - 1); }
    562 
    563         template<typename U> bool contains(const U&) const;
    564         template<typename U> size_t find(const U&) const;
    565         template<typename U> size_t reverseFind(const U&) const;
    566 
    567         void shrink(size_t size);
    568         void grow(size_t size);
    569         void resize(size_t size);
    570         void reserveCapacity(size_t newCapacity);
    571         bool tryReserveCapacity(size_t newCapacity);
    572         void reserveInitialCapacity(size_t initialCapacity);
    573         void shrinkCapacity(size_t newCapacity);
    574         void shrinkToFit() { shrinkCapacity(size()); }
    575 
    576         void clear() { shrinkCapacity(0); }
    577 
    578         template<typename U> void append(const U*, size_t);
    579         template<typename U> void append(const U&);
    580         template<typename U> void uncheckedAppend(const U& val);
    581         template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&);
    582         template<typename U> bool tryAppend(const U*, size_t);
    583 
    584         template<typename U> void insert(size_t position, const U*, size_t);
    585         template<typename U> void insert(size_t position, const U&);
    586         template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&);
    587 
    588         template<typename U> void prepend(const U*, size_t);
    589         template<typename U> void prepend(const U&);
    590         template<typename U, size_t c> void prepend(const Vector<U, c>&);
    591 
    592         void remove(size_t position);
    593         void remove(size_t position, size_t length);
    594 
    595         void removeLast()
    596         {
    597             ASSERT(!isEmpty());
    598             shrink(size() - 1);
    599         }
    600 
    601         Vector(size_t size, const T& val)
    602             : m_size(size)
    603             , m_buffer(size)
    604         {
    605             if (begin())
    606                 TypeOperations::uninitializedFill(begin(), end(), val);
    607         }
    608 
    609         void fill(const T&, size_t);
    610         void fill(const T& val) { fill(val, size()); }
    611 
    612         template<typename Iterator> void appendRange(Iterator start, Iterator end);
    613 
    614         T* releaseBuffer();
    615 
    616         void swap(Vector<T, inlineCapacity>& other)
    617         {
    618             std::swap(m_size, other.m_size);
    619             m_buffer.swap(other.m_buffer);
    620         }
    621 
    622         void checkConsistency();
    623 
    624     private:
    625         void expandCapacity(size_t newMinCapacity);
    626         const T* expandCapacity(size_t newMinCapacity, const T*);
    627         bool tryExpandCapacity(size_t newMinCapacity);
    628         const T* tryExpandCapacity(size_t newMinCapacity, const T*);
    629         template<typename U> U* expandCapacity(size_t newMinCapacity, U*);
    630 
    631         size_t m_size;
    632         Buffer m_buffer;
    633     };
    634 
    635 #if PLATFORM(QT)
    636     template<typename T>
    637     QDataStream& operator<<(QDataStream& stream, const Vector<T>& data)
    638     {
    639         stream << qint64(data.size());
    640         foreach (const T& i, data)
    641             stream << i;
    642         return stream;
    643     }
    644 
    645     template<typename T>
    646     QDataStream& operator>>(QDataStream& stream, Vector<T>& data)
    647     {
    648         data.clear();
    649         qint64 count;
    650         T item;
    651         stream >> count;
    652         data.reserveCapacity(count);
    653         for (qint64 i = 0; i < count; ++i) {
    654             stream >> item;
    655             data.append(item);
    656         }
    657         return stream;
    658     }
    659 #endif
    660 
    661     template<typename T, size_t inlineCapacity>
    662     Vector<T, inlineCapacity>::Vector(const Vector& other)
    663         : m_size(other.size())
    664         , m_buffer(other.capacity())
    665     {
    666         if (begin())
    667             TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
    668     }
    669 
    670     template<typename T, size_t inlineCapacity>
    671     template<size_t otherCapacity>
    672     Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other)
    673         : m_size(other.size())
    674         , m_buffer(other.capacity())
    675     {
    676         if (begin())
    677             TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
    678     }
    679 
    680     template<typename T, size_t inlineCapacity>
    681     Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other)
    682     {
    683         if (&other == this)
    684             return *this;
    685 
    686         if (size() > other.size())
    687             shrink(other.size());
    688         else if (other.size() > capacity()) {
    689             clear();
    690             reserveCapacity(other.size());
    691             if (!begin())
    692                 return *this;
    693         }
    694 
    695 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStudio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last
    696 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL
    697         if (!begin())
    698             return *this;
    699 #endif
    700 
    701         std::copy(other.begin(), other.begin() + size(), begin());
    702         TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
    703         m_size = other.size();
    704 
    705         return *this;
    706     }
    707 
    708     inline bool typelessPointersAreEqual(const void* a, const void* b) { return a == b; }
    709 
    710     template<typename T, size_t inlineCapacity>
    711     template<size_t otherCapacity>
    712     Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other)
    713     {
    714         // If the inline capacities match, we should call the more specific
    715         // template.  If the inline capacities don't match, the two objects
    716         // shouldn't be allocated the same address.
    717         ASSERT(!typelessPointersAreEqual(&other, this));
    718 
    719         if (size() > other.size())
    720             shrink(other.size());
    721         else if (other.size() > capacity()) {
    722             clear();
    723             reserveCapacity(other.size());
    724             if (!begin())
    725                 return *this;
    726         }
    727 
    728 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStudio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last
    729 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL
    730         if (!begin())
    731             return *this;
    732 #endif
    733 
    734         std::copy(other.begin(), other.begin() + size(), begin());
    735         TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
    736         m_size = other.size();
    737 
    738         return *this;
    739     }
    740 
    741     template<typename T, size_t inlineCapacity>
    742     template<typename U>
    743     bool Vector<T, inlineCapacity>::contains(const U& value) const
    744     {
    745         return find(value) != notFound;
    746     }
    747 
    748     template<typename T, size_t inlineCapacity>
    749     template<typename U>
    750     size_t Vector<T, inlineCapacity>::find(const U& value) const
    751     {
    752         for (size_t i = 0; i < size(); ++i) {
    753             if (at(i) == value)
    754                 return i;
    755         }
    756         return notFound;
    757     }
    758 
    759     template<typename T, size_t inlineCapacity>
    760     template<typename U>
    761     size_t Vector<T, inlineCapacity>::reverseFind(const U& value) const
    762     {
    763         for (size_t i = 1; i <= size(); ++i) {
    764             const size_t index = size() - i;
    765             if (at(index) == value)
    766                 return index;
    767         }
    768         return notFound;
    769     }
    770 
    771     template<typename T, size_t inlineCapacity>
    772     void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize)
    773     {
    774         if (size() > newSize)
    775             shrink(newSize);
    776         else if (newSize > capacity()) {
    777             clear();
    778             reserveCapacity(newSize);
    779             if (!begin())
    780                 return;
    781         }
    782 
    783         std::fill(begin(), end(), val);
    784         TypeOperations::uninitializedFill(end(), begin() + newSize, val);
    785         m_size = newSize;
    786     }
    787 
    788     template<typename T, size_t inlineCapacity>
    789     template<typename Iterator>
    790     void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end)
    791     {
    792         for (Iterator it = start; it != end; ++it)
    793             append(*it);
    794     }
    795 
    796     template<typename T, size_t inlineCapacity>
    797     void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
    798     {
    799         reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
    800     }
    801 
    802     template<typename T, size_t inlineCapacity>
    803     const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr)
    804     {
    805         if (ptr < begin() || ptr >= end()) {
    806             expandCapacity(newMinCapacity);
    807             return ptr;
    808         }
    809         size_t index = ptr - begin();
    810         expandCapacity(newMinCapacity);
    811         return begin() + index;
    812     }
    813 
    814     template<typename T, size_t inlineCapacity>
    815     bool Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity)
    816     {
    817         return tryReserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
    818     }
    819 
    820     template<typename T, size_t inlineCapacity>
    821     const T* Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity, const T* ptr)
    822     {
    823         if (ptr < begin() || ptr >= end()) {
    824             if (!tryExpandCapacity(newMinCapacity))
    825                 return 0;
    826             return ptr;
    827         }
    828         size_t index = ptr - begin();
    829         if (!tryExpandCapacity(newMinCapacity))
    830             return 0;
    831         return begin() + index;
    832     }
    833 
    834     template<typename T, size_t inlineCapacity> template<typename U>
    835     inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
    836     {
    837         expandCapacity(newMinCapacity);
    838         return ptr;
    839     }
    840 
    841     template<typename T, size_t inlineCapacity>
    842     inline void Vector<T, inlineCapacity>::resize(size_t size)
    843     {
    844         if (size <= m_size)
    845             TypeOperations::destruct(begin() + size, end());
    846         else {
    847             if (size > capacity())
    848                 expandCapacity(size);
    849             if (begin())
    850                 TypeOperations::initialize(end(), begin() + size);
    851         }
    852 
    853         m_size = size;
    854     }
    855 
    856     template<typename T, size_t inlineCapacity>
    857     void Vector<T, inlineCapacity>::shrink(size_t size)
    858     {
    859         ASSERT(size <= m_size);
    860         TypeOperations::destruct(begin() + size, end());
    861         m_size = size;
    862     }
    863 
    864     template<typename T, size_t inlineCapacity>
    865     void Vector<T, inlineCapacity>::grow(size_t size)
    866     {
    867         ASSERT(size >= m_size);
    868         if (size > capacity())
    869             expandCapacity(size);
    870         if (begin())
    871             TypeOperations::initialize(end(), begin() + size);
    872         m_size = size;
    873     }
    874 
    875     template<typename T, size_t inlineCapacity>
    876     void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity)
    877     {
    878         if (newCapacity <= capacity())
    879             return;
    880         T* oldBuffer = begin();
    881         T* oldEnd = end();
    882         m_buffer.allocateBuffer(newCapacity);
    883         if (begin())
    884             TypeOperations::move(oldBuffer, oldEnd, begin());
    885         m_buffer.deallocateBuffer(oldBuffer);
    886     }
    887 
    888     template<typename T, size_t inlineCapacity>
    889     bool Vector<T, inlineCapacity>::tryReserveCapacity(size_t newCapacity)
    890     {
    891         if (newCapacity <= capacity())
    892             return true;
    893         T* oldBuffer = begin();
    894         T* oldEnd = end();
    895         if (!m_buffer.tryAllocateBuffer(newCapacity))
    896             return false;
    897         ASSERT(begin());
    898         TypeOperations::move(oldBuffer, oldEnd, begin());
    899         m_buffer.deallocateBuffer(oldBuffer);
    900         return true;
    901     }
    902 
    903     template<typename T, size_t inlineCapacity>
    904     inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity)
    905     {
    906         ASSERT(!m_size);
    907         ASSERT(capacity() == inlineCapacity);
    908         if (initialCapacity > inlineCapacity)
    909             m_buffer.allocateBuffer(initialCapacity);
    910     }
    911 
    912     template<typename T, size_t inlineCapacity>
    913     void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity)
    914     {
    915         if (newCapacity >= capacity())
    916             return;
    917 
    918         if (newCapacity < size())
    919             shrink(newCapacity);
    920 
    921         T* oldBuffer = begin();
    922         if (newCapacity > 0) {
    923             T* oldEnd = end();
    924             m_buffer.allocateBuffer(newCapacity);
    925             if (begin() != oldBuffer)
    926                 TypeOperations::move(oldBuffer, oldEnd, begin());
    927         }
    928 
    929         m_buffer.deallocateBuffer(oldBuffer);
    930         m_buffer.restoreInlineBufferIfNeeded();
    931     }
    932 
    933     // Templatizing these is better than just letting the conversion happen implicitly,
    934     // because for instance it allows a PassRefPtr to be appended to a RefPtr vector
    935     // without refcount thrash.
    936 
    937     template<typename T, size_t inlineCapacity> template<typename U>
    938     void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize)
    939     {
    940         size_t newSize = m_size + dataSize;
    941         if (newSize > capacity()) {
    942             data = expandCapacity(newSize, data);
    943             if (!begin())
    944                 return;
    945         }
    946         if (newSize < m_size)
    947             CRASH();
    948         T* dest = end();
    949         for (size_t i = 0; i < dataSize; ++i)
    950             new (&dest[i]) T(data[i]);
    951         m_size = newSize;
    952     }
    953 
    954     template<typename T, size_t inlineCapacity> template<typename U>
    955     bool Vector<T, inlineCapacity>::tryAppend(const U* data, size_t dataSize)
    956     {
    957         size_t newSize = m_size + dataSize;
    958         if (newSize > capacity()) {
    959             data = tryExpandCapacity(newSize, data);
    960             if (!data)
    961                 return false;
    962             ASSERT(begin());
    963         }
    964         if (newSize < m_size)
    965             return false;
    966         T* dest = end();
    967         for (size_t i = 0; i < dataSize; ++i)
    968             new (&dest[i]) T(data[i]);
    969         m_size = newSize;
    970         return true;
    971     }
    972 
    973     template<typename T, size_t inlineCapacity> template<typename U>
    974     ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val)
    975     {
    976         const U* ptr = &val;
    977         if (size() == capacity()) {
    978             ptr = expandCapacity(size() + 1, ptr);
    979             if (!begin())
    980                 return;
    981         }
    982 
    983 #if COMPILER(MSVC7_OR_LOWER)
    984         // FIXME: MSVC7 generates compilation errors when trying to assign
    985         // a pointer to a Vector of its base class (i.e. can't downcast). So far
    986         // I've been unable to determine any logical reason for this, so I can
    987         // only assume it is a bug with the compiler. Casting is a bad solution,
    988         // however, because it subverts implicit conversions, so a better
    989         // one is needed.
    990         new (end()) T(static_cast<T>(*ptr));
    991 #else
    992         new (end()) T(*ptr);
    993 #endif
    994         ++m_size;
    995     }
    996 
    997     // This version of append saves a branch in the case where you know that the
    998     // vector's capacity is large enough for the append to succeed.
    999 
   1000     template<typename T, size_t inlineCapacity> template<typename U>
   1001     inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val)
   1002     {
   1003         ASSERT(size() < capacity());
   1004         const U* ptr = &val;
   1005         new (end()) T(*ptr);
   1006         ++m_size;
   1007     }
   1008 
   1009     // This method should not be called append, a better name would be appendElements.
   1010     // It could also be eliminated entirely, and call sites could just use
   1011     // appendRange(val.begin(), val.end()).
   1012     template<typename T, size_t inlineCapacity> template<size_t otherCapacity>
   1013     inline void Vector<T, inlineCapacity>::append(const Vector<T, otherCapacity>& val)
   1014     {
   1015         append(val.begin(), val.size());
   1016     }
   1017 
   1018     template<typename T, size_t inlineCapacity> template<typename U>
   1019     void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize)
   1020     {
   1021         ASSERT(position <= size());
   1022         size_t newSize = m_size + dataSize;
   1023         if (newSize > capacity()) {
   1024             data = expandCapacity(newSize, data);
   1025             if (!begin())
   1026                 return;
   1027         }
   1028         if (newSize < m_size)
   1029             CRASH();
   1030         T* spot = begin() + position;
   1031         TypeOperations::moveOverlapping(spot, end(), spot + dataSize);
   1032         for (size_t i = 0; i < dataSize; ++i)
   1033             new (&spot[i]) T(data[i]);
   1034         m_size = newSize;
   1035     }
   1036 
   1037     template<typename T, size_t inlineCapacity> template<typename U>
   1038     inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val)
   1039     {
   1040         ASSERT(position <= size());
   1041         const U* data = &val;
   1042         if (size() == capacity()) {
   1043             data = expandCapacity(size() + 1, data);
   1044             if (!begin())
   1045                 return;
   1046         }
   1047         T* spot = begin() + position;
   1048         TypeOperations::moveOverlapping(spot, end(), spot + 1);
   1049         new (spot) T(*data);
   1050         ++m_size;
   1051     }
   1052 
   1053     template<typename T, size_t inlineCapacity> template<typename U, size_t c>
   1054     inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val)
   1055     {
   1056         insert(position, val.begin(), val.size());
   1057     }
   1058 
   1059     template<typename T, size_t inlineCapacity> template<typename U>
   1060     void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize)
   1061     {
   1062         insert(0, data, dataSize);
   1063     }
   1064 
   1065     template<typename T, size_t inlineCapacity> template<typename U>
   1066     inline void Vector<T, inlineCapacity>::prepend(const U& val)
   1067     {
   1068         insert(0, val);
   1069     }
   1070 
   1071     template<typename T, size_t inlineCapacity> template<typename U, size_t c>
   1072     inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val)
   1073     {
   1074         insert(0, val.begin(), val.size());
   1075     }
   1076 
   1077     template<typename T, size_t inlineCapacity>
   1078     inline void Vector<T, inlineCapacity>::remove(size_t position)
   1079     {
   1080         ASSERT(position < size());
   1081         T* spot = begin() + position;
   1082         spot->~T();
   1083         TypeOperations::moveOverlapping(spot + 1, end(), spot);
   1084         --m_size;
   1085     }
   1086 
   1087     template<typename T, size_t inlineCapacity>
   1088     inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length)
   1089     {
   1090         ASSERT(position < size());
   1091         ASSERT(position + length <= size());
   1092         T* beginSpot = begin() + position;
   1093         T* endSpot = beginSpot + length;
   1094         TypeOperations::destruct(beginSpot, endSpot);
   1095         TypeOperations::moveOverlapping(endSpot, end(), beginSpot);
   1096         m_size -= length;
   1097     }
   1098 
   1099     template<typename T, size_t inlineCapacity>
   1100     inline T* Vector<T, inlineCapacity>::releaseBuffer()
   1101     {
   1102         T* buffer = m_buffer.releaseBuffer();
   1103         if (inlineCapacity && !buffer && m_size) {
   1104             // If the vector had some data, but no buffer to release,
   1105             // that means it was using the inline buffer. In that case,
   1106             // we create a brand new buffer so the caller always gets one.
   1107             size_t bytes = m_size * sizeof(T);
   1108             buffer = static_cast<T*>(fastMalloc(bytes));
   1109             memcpy(buffer, data(), bytes);
   1110         }
   1111         m_size = 0;
   1112         return buffer;
   1113     }
   1114 
   1115     template<typename T, size_t inlineCapacity>
   1116     inline void Vector<T, inlineCapacity>::checkConsistency()
   1117     {
   1118 #if !ASSERT_DISABLED
   1119         for (size_t i = 0; i < size(); ++i)
   1120             ValueCheck<T>::checkConsistency(at(i));
   1121 #endif
   1122     }
   1123 
   1124     template<typename T, size_t inlineCapacity>
   1125     void deleteAllValues(const Vector<T, inlineCapacity>& collection)
   1126     {
   1127         typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
   1128         iterator end = collection.end();
   1129         for (iterator it = collection.begin(); it != end; ++it)
   1130             delete *it;
   1131     }
   1132 
   1133     template<typename T, size_t inlineCapacity>
   1134     inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b)
   1135     {
   1136         a.swap(b);
   1137     }
   1138 
   1139     template<typename T, size_t inlineCapacity>
   1140     bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
   1141     {
   1142         if (a.size() != b.size())
   1143             return false;
   1144 
   1145         return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size());
   1146     }
   1147 
   1148     template<typename T, size_t inlineCapacity>
   1149     inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b)
   1150     {
   1151         return !(a == b);
   1152     }
   1153 
   1154 #if !ASSERT_DISABLED
   1155     template<typename T> struct ValueCheck<Vector<T> > {
   1156         typedef Vector<T> TraitType;
   1157         static void checkConsistency(const Vector<T>& v)
   1158         {
   1159             v.checkConsistency();
   1160         }
   1161     };
   1162 #endif
   1163 
   1164 } // namespace WTF
   1165 
   1166 using WTF::Vector;
   1167 
   1168 #endif // WTF_Vector_h
   1169