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