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