File indexing completed on 2024-05-12 15:43:40

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
0004  *
0005  *  This library is free software; you can redistribute it and/or
0006  *  modify it under the terms of the GNU Library General Public
0007  *  License as published by the Free Software Foundation; either
0008  *  version 2 of the License, or (at your option) any later version.
0009  *
0010  *  This library is distributed in the hope that it will be useful,
0011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  *  Library General Public License for more details.
0014  *
0015  *  You should have received a copy of the GNU Library General Public License
0016  *  along with this library; see the file COPYING.LIB.  If not, write to
0017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  *  Boston, MA 02110-1301, USA.
0019  *
0020  */
0021 
0022 #ifndef WTF_Vector_h
0023 #define WTF_Vector_h
0024 
0025 #include <wtf/Assertions.h>
0026 #include <wtf/FastMalloc.h>
0027 #include <wtf/Noncopyable.h>
0028 #include <wtf/VectorTraits.h>
0029 #include <limits>
0030 #include <stdlib.h>
0031 #include <cstring>
0032 #include <utility>
0033 
0034 // Temporary workaround for Win32.
0035 // We should use NOMINMAX instead.
0036 #undef max
0037 
0038 namespace WTF
0039 {
0040 
0041 using std::min;
0042 using std::max;
0043 
0044 template <bool needsDestruction, typename T>
0045 struct VectorDestructor;
0046 
0047 template<typename T>
0048 struct VectorDestructor<false, T> {
0049     static void destruct(T *, T *) {}
0050 };
0051 
0052 template<typename T>
0053 struct VectorDestructor<true, T> {
0054     static void destruct(T *begin, T *end)
0055     {
0056         for (T *cur = begin; cur != end; ++cur) {
0057             cur->~T();
0058         }
0059     }
0060 };
0061 
0062 template <bool needsInitialization, bool canInitializeWithMemset, typename T>
0063 struct VectorInitializer;
0064 
0065 template<bool ignore, typename T>
0066 struct VectorInitializer<false, ignore, T> {
0067     static void initialize(T *, T *) {}
0068 };
0069 
0070 template<typename T>
0071 struct VectorInitializer<true, false, T> {
0072     static void initialize(T *begin, T *end)
0073     {
0074         for (T *cur = begin; cur != end; ++cur) {
0075             new(cur) T;
0076         }
0077     }
0078 };
0079 
0080 template<typename T>
0081 struct VectorInitializer<true, true, T> {
0082     static void initialize(T *begin, T *end)
0083     {
0084         std::memset(begin, 0, reinterpret_cast<char *>(end) - reinterpret_cast<char *>(begin));
0085     }
0086 };
0087 
0088 template <bool canMoveWithMemcpy, typename T>
0089 struct VectorMover;
0090 
0091 template<typename T>
0092 struct VectorMover<false, T> {
0093     static void move(const T *src, const T *srcEnd, T *dst)
0094     {
0095         while (src != srcEnd) {
0096             new(dst) T(*src);
0097             const_cast<T *>(src)->~T();
0098             ++dst;
0099             ++src;
0100         }
0101     }
0102     static void moveOverlapping(const T *src, const T *srcEnd, T *dst)
0103     {
0104         if (src > dst) {
0105             move(src, srcEnd, dst);
0106         } else {
0107             T *dstEnd = dst + (srcEnd - src);
0108             while (src != srcEnd) {
0109                 --srcEnd;
0110                 --dstEnd;
0111                 new(dstEnd) T(*srcEnd);
0112                 const_cast<T *>(srcEnd)->~T();
0113             }
0114         }
0115     }
0116 };
0117 
0118 template<typename T>
0119 struct VectorMover<true, T> {
0120     static void move(const T *src, const T *srcEnd, T *dst)
0121     {
0122         std::memcpy(dst, src, reinterpret_cast<const char *>(srcEnd) - reinterpret_cast<const char *>(src));
0123     }
0124     static void moveOverlapping(const T *src, const T *srcEnd, T *dst)
0125     {
0126         std::memmove(dst, src, reinterpret_cast<const char *>(srcEnd) - reinterpret_cast<const char *>(src));
0127     }
0128 };
0129 
0130 template <bool canCopyWithMemcpy, typename T>
0131 struct VectorCopier;
0132 
0133 template<typename T>
0134 struct VectorCopier<false, T> {
0135     static void uninitializedCopy(const T *src, const T *srcEnd, T *dst)
0136     {
0137         while (src != srcEnd) {
0138             new(dst) T(*src);
0139             ++dst;
0140             ++src;
0141         }
0142     }
0143 };
0144 
0145 template<typename T>
0146 struct VectorCopier<true, T> {
0147     static void uninitializedCopy(const T *src, const T *srcEnd, T *dst)
0148     {
0149         std::memcpy(dst, src, reinterpret_cast<const char *>(srcEnd) - reinterpret_cast<const char *>(src));
0150     }
0151 };
0152 
0153 template <bool canFillWithMemset, typename T>
0154 struct VectorFiller;
0155 
0156 template<typename T>
0157 struct VectorFiller<false, T> {
0158     static void uninitializedFill(T *dst, T *dstEnd, const T &val)
0159     {
0160         while (dst != dstEnd) {
0161             new(dst) T(val);
0162             ++dst;
0163         }
0164     }
0165 };
0166 
0167 template<typename T>
0168 struct VectorFiller<true, T> {
0169     static void uninitializedFill(T *dst, T *dstEnd, const T &val)
0170     {
0171         ASSERT(sizeof(T) == sizeof(char));
0172         std::memset(dst, val, dstEnd - dst);
0173     }
0174 };
0175 
0176 template<bool canCompareWithMemcmp, typename T>
0177 struct VectorComparer;
0178 
0179 template<typename T>
0180 struct VectorComparer<false, T> {
0181     static bool compare(const T *a, const T *b, size_t size)
0182     {
0183         for (size_t i = 0; i < size; ++i)
0184             if (a[i] != b[i]) {
0185                 return false;
0186             }
0187         return true;
0188     }
0189 };
0190 
0191 template<typename T>
0192 struct VectorComparer<true, T> {
0193     static bool compare(const T *a, const T *b, size_t size)
0194     {
0195         return std::memcmp(a, b, sizeof(T) * size) == 0;
0196     }
0197 };
0198 
0199 template<typename T>
0200 struct VectorTypeOperations {
0201     static void destruct(T *begin, T *end)
0202     {
0203         VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, end);
0204     }
0205 
0206     static void initialize(T *begin, T *end)
0207     {
0208         VectorInitializer<VectorTraits<T>::needsInitialization, VectorTraits<T>::canInitializeWithMemset, T>::initialize(begin, end);
0209     }
0210 
0211     static void move(const T *src, const T *srcEnd, T *dst)
0212     {
0213         VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::move(src, srcEnd, dst);
0214     }
0215 
0216     static void moveOverlapping(const T *src, const T *srcEnd, T *dst)
0217     {
0218         VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::moveOverlapping(src, srcEnd, dst);
0219     }
0220 
0221     static void uninitializedCopy(const T *src, const T *srcEnd, T *dst)
0222     {
0223         VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(src, srcEnd, dst);
0224     }
0225 
0226     static void uninitializedFill(T *dst, T *dstEnd, const T &val)
0227     {
0228         VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFill(dst, dstEnd, val);
0229     }
0230 
0231     static bool compare(const T *a, const T *b, size_t size)
0232     {
0233         return VectorComparer<VectorTraits<T>::canCompareWithMemcmp, T>::compare(a, b, size);
0234     }
0235 };
0236 
0237 template<typename T>
0238 class VectorBufferBase : Noncopyable
0239 {
0240 public:
0241     void allocateBuffer(size_t newCapacity)
0242     {
0243         m_capacity = newCapacity;
0244         if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T)) {
0245             CRASH();
0246         }
0247         m_buffer = static_cast<T *>(fastMalloc(newCapacity * sizeof(T)));
0248     }
0249 
0250     void deallocateBuffer(T *bufferToDeallocate)
0251     {
0252         if (m_buffer == bufferToDeallocate) {
0253             m_buffer = nullptr;
0254         }
0255         fastFree(bufferToDeallocate);
0256     }
0257 
0258     T *buffer()
0259     {
0260         return m_buffer;
0261     }
0262     const T *buffer() const
0263     {
0264         return m_buffer;
0265     }
0266     size_t capacity() const
0267     {
0268         return m_capacity;
0269     }
0270 
0271     T *releaseBuffer()
0272     {
0273         T *buffer = m_buffer;
0274         m_buffer = nullptr;
0275         m_capacity = 0;
0276         return buffer;
0277     }
0278 
0279 protected:
0280     VectorBufferBase()
0281         : m_buffer(nullptr)
0282         , m_capacity(0)
0283     {
0284     }
0285 
0286     VectorBufferBase(T *buffer, size_t capacity)
0287         : m_buffer(buffer)
0288         , m_capacity(capacity)
0289     {
0290     }
0291 
0292     ~VectorBufferBase()
0293     {
0294         // FIXME: It would be nice to find a way to ASSERT that m_buffer hasn't leaked here.
0295     }
0296 
0297     T *m_buffer;
0298     size_t m_capacity;
0299 };
0300 
0301 template<typename T, size_t inlineCapacity>
0302 class VectorBuffer;
0303 
0304 template<typename T>
0305 class VectorBuffer<T, 0> : private VectorBufferBase<T>
0306 {
0307 private:
0308     typedef VectorBufferBase<T> Base;
0309 public:
0310     VectorBuffer()
0311     {
0312     }
0313 
0314     VectorBuffer(size_t capacity)
0315     {
0316         allocateBuffer(capacity);
0317     }
0318 
0319     ~VectorBuffer()
0320     {
0321         deallocateBuffer(buffer());
0322     }
0323 
0324     void swap(VectorBuffer<T, 0> &other)
0325     {
0326         std::swap(m_buffer, other.m_buffer);
0327         std::swap(m_capacity, other.m_capacity);
0328     }
0329 
0330     using Base::allocateBuffer;
0331     using Base::deallocateBuffer;
0332 
0333     using Base::buffer;
0334     using Base::capacity;
0335 
0336     using Base::releaseBuffer;
0337 private:
0338     using Base::m_buffer;
0339     using Base::m_capacity;
0340 };
0341 
0342 template<typename T, size_t inlineCapacity>
0343 class VectorBuffer : private VectorBufferBase<T>
0344 {
0345 private:
0346     typedef VectorBufferBase<T> Base;
0347 public:
0348     VectorBuffer()
0349         : Base(inlineBuffer(), inlineCapacity)
0350     {
0351     }
0352 
0353     VectorBuffer(size_t capacity)
0354         : Base(inlineBuffer(), inlineCapacity)
0355     {
0356         allocateBuffer(capacity);
0357     }
0358 
0359     ~VectorBuffer()
0360     {
0361         deallocateBuffer(buffer());
0362     }
0363 
0364     void allocateBuffer(size_t newCapacity)
0365     {
0366         if (newCapacity > inlineCapacity) {
0367             Base::allocateBuffer(newCapacity);
0368         }
0369     }
0370 
0371     void deallocateBuffer(T *bufferToDeallocate)
0372     {
0373         if (bufferToDeallocate == inlineBuffer()) {
0374             return;
0375         }
0376         Base::deallocateBuffer(bufferToDeallocate);
0377     }
0378 
0379     using Base::buffer;
0380     using Base::capacity;
0381 
0382     T *releaseBuffer()
0383     {
0384         if (buffer() == inlineBuffer()) {
0385             return nullptr;
0386         }
0387         return Base::releaseBuffer();
0388     }
0389 
0390 private:
0391     using Base::m_buffer;
0392     using Base::m_capacity;
0393 
0394     static const size_t m_inlineBufferSize = inlineCapacity *sizeof(T);
0395     T *inlineBuffer()
0396     {
0397         return reinterpret_cast<T *>(&m_inlineBuffer);
0398     }
0399 
0400     // FIXME: Nothing guarantees this buffer is appropriately aligned to hold objects of type T.
0401     char m_inlineBuffer[m_inlineBufferSize];
0402 };
0403 
0404 template<typename T, size_t inlineCapacity = 0>
0405 class Vector
0406 {
0407 private:
0408     typedef VectorBuffer<T, inlineCapacity> Buffer;
0409     typedef VectorTypeOperations<T> TypeOperations;
0410 
0411 public:
0412     typedef T ValueType;
0413 
0414     typedef T *iterator;
0415     typedef const T *const_iterator;
0416 
0417     Vector()
0418         : m_size(0)
0419     {
0420     }
0421 
0422     explicit Vector(size_t size)
0423         : m_size(size)
0424         , m_buffer(size)
0425     {
0426         TypeOperations::initialize(begin(), end());
0427     }
0428 
0429     ~Vector()
0430     {
0431         clear();
0432     }
0433 
0434     Vector(const Vector &);
0435     template<size_t otherCapacity>
0436     Vector(const Vector<T, otherCapacity> &);
0437 
0438     Vector &operator=(const Vector &);
0439     template<size_t otherCapacity>
0440     Vector &operator=(const Vector<T, otherCapacity> &);
0441 
0442     size_t size() const
0443     {
0444         return m_size;
0445     }
0446     size_t capacity() const
0447     {
0448         return m_buffer.capacity();
0449     }
0450     bool isEmpty() const
0451     {
0452         return !size();
0453     }
0454 
0455     T &at(size_t i)
0456     {
0457         ASSERT(i < size());
0458         return m_buffer.buffer()[i];
0459     }
0460     const T &at(size_t i) const
0461     {
0462         ASSERT(i < size());
0463         return m_buffer.buffer()[i];
0464     }
0465 
0466     T &operator[](size_t i)
0467     {
0468         return at(i);
0469     }
0470     const T &operator[](size_t i) const
0471     {
0472         return at(i);
0473     }
0474 
0475     T *data()
0476     {
0477         return m_buffer.buffer();
0478     }
0479     const T *data() const
0480     {
0481         return m_buffer.buffer();
0482     }
0483 
0484     iterator begin()
0485     {
0486         return data();
0487     }
0488     iterator end()
0489     {
0490         return begin() + m_size;
0491     }
0492     const_iterator begin() const
0493     {
0494         return data();
0495     }
0496     const_iterator end() const
0497     {
0498         return begin() + m_size;
0499     }
0500 
0501     T &first()
0502     {
0503         return at(0);
0504     }
0505     const T &first() const
0506     {
0507         return at(0);
0508     }
0509     T &last()
0510     {
0511         return at(size() - 1);
0512     }
0513     const T &last() const
0514     {
0515         return at(size() - 1);
0516     }
0517 
0518     void shrink(size_t size);
0519     void grow(size_t size);
0520     void resize(size_t size);
0521     void reserveCapacity(size_t newCapacity);
0522     void shrinkCapacity(size_t newCapacity);
0523 
0524     void clear()
0525     {
0526         if (m_size) {
0527             shrink(0);
0528         }
0529     }
0530 
0531     template<typename U> void append(const U *, size_t);
0532     template<typename U> void append(const U &);
0533     template<typename U> void uncheckedAppend(const U &val);
0534     template<typename U, size_t c> void append(const Vector<U, c> &);
0535 
0536     template<typename U> void insert(size_t position, const U *, size_t);
0537     template<typename U> void insert(size_t position, const U &);
0538     template<typename U, size_t c> void insert(size_t position, const Vector<U, c> &);
0539 
0540     template<typename U> void prepend(const U *, size_t);
0541     template<typename U> void prepend(const U &);
0542     template<typename U, size_t c> void prepend(const Vector<U, c> &);
0543 
0544     void remove(size_t position);
0545     void remove(size_t position, size_t length);
0546 
0547     void removeLast()
0548     {
0549         ASSERT(!isEmpty());
0550         shrink(size() - 1);
0551     }
0552 
0553     Vector(size_t size, const T &val)
0554         : m_size(size)
0555         , m_buffer(size)
0556     {
0557         TypeOperations::uninitializedFill(begin(), end(), val);
0558     }
0559 
0560     void fill(const T &, size_t);
0561     void fill(const T &val)
0562     {
0563         fill(val, size());
0564     }
0565 
0566     template<typename Iterator> void appendRange(Iterator start, Iterator end);
0567 
0568     T *releaseBuffer();
0569 
0570     void swap(Vector<T, inlineCapacity> &other)
0571     {
0572         std::swap(m_size, other.m_size);
0573         m_buffer.swap(other.m_buffer);
0574     }
0575 
0576 private:
0577     void expandCapacity(size_t newMinCapacity);
0578     const T *expandCapacity(size_t newMinCapacity, const T *);
0579     template<typename U> U *expandCapacity(size_t newMinCapacity, U *);
0580 
0581     size_t m_size;
0582     Buffer m_buffer;
0583 };
0584 
0585 template<typename T, size_t inlineCapacity>
0586 Vector<T, inlineCapacity>::Vector(const Vector &other)
0587     : m_size(other.size())
0588     , m_buffer(other.capacity())
0589 {
0590     TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
0591 }
0592 
0593 template<typename T, size_t inlineCapacity>
0594 template<size_t otherCapacity>
0595 Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity> &other)
0596     : m_size(other.size())
0597     , m_buffer(other.capacity())
0598 {
0599     TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
0600 }
0601 
0602 template<typename T, size_t inlineCapacity>
0603 Vector<T, inlineCapacity> &Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity> &other)
0604 {
0605     if (&other == this) {
0606         return *this;
0607     }
0608 
0609     if (size() > other.size()) {
0610         shrink(other.size());
0611     } else if (other.size() > capacity()) {
0612         clear();
0613         reserveCapacity(other.size());
0614     }
0615 
0616     std::copy(other.begin(), other.begin() + size(), begin());
0617     TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
0618     m_size = other.size();
0619 
0620     return *this;
0621 }
0622 
0623 template<typename T, size_t inlineCapacity>
0624 template<size_t otherCapacity>
0625 Vector<T, inlineCapacity> &Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity> &other)
0626 {
0627     if (&other == this) {
0628         return *this;
0629     }
0630 
0631     if (size() > other.size()) {
0632         shrink(other.size());
0633     } else if (other.size() > capacity()) {
0634         clear();
0635         reserveCapacity(other.size());
0636     }
0637 
0638     std::copy(other.begin(), other.begin() + size(), begin());
0639     TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
0640     m_size = other.size();
0641 
0642     return *this;
0643 }
0644 
0645 template<typename T, size_t inlineCapacity>
0646 void Vector<T, inlineCapacity>::fill(const T &val, size_t newSize)
0647 {
0648     if (size() > newSize) {
0649         shrink(newSize);
0650     } else if (newSize > capacity()) {
0651         clear();
0652         reserveCapacity(newSize);
0653     }
0654 
0655     std::fill(begin(), end(), val);
0656     TypeOperations::uninitializedFill(end(), begin() + newSize, val);
0657     m_size = newSize;
0658 }
0659 
0660 template<typename T, size_t inlineCapacity>
0661 template<typename Iterator>
0662 void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end)
0663 {
0664     for (Iterator it = start; it != end; ++it) {
0665         append(*it);
0666     }
0667 }
0668 
0669 template<typename T, size_t inlineCapacity>
0670 void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
0671 {
0672     reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
0673 }
0674 
0675 template<typename T, size_t inlineCapacity>
0676 const T *Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T *ptr)
0677 {
0678     if (ptr < begin() || ptr >= end()) {
0679         expandCapacity(newMinCapacity);
0680         return ptr;
0681     }
0682     size_t index = ptr - begin();
0683     expandCapacity(newMinCapacity);
0684     return begin() + index;
0685 }
0686 
0687 template<typename T, size_t inlineCapacity> template<typename U>
0688 inline U *Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U *ptr)
0689 {
0690     expandCapacity(newMinCapacity);
0691     return ptr;
0692 }
0693 
0694 template<typename T, size_t inlineCapacity>
0695 void Vector<T, inlineCapacity>::resize(size_t size)
0696 {
0697     if (size <= m_size) {
0698         TypeOperations::destruct(begin() + size, end());
0699     } else {
0700         if (size > capacity()) {
0701             expandCapacity(size);
0702         }
0703         if (begin()) {
0704             TypeOperations::initialize(end(), begin() + size);
0705         }
0706     }
0707 
0708     m_size = size;
0709 }
0710 
0711 template<typename T, size_t inlineCapacity>
0712 void Vector<T, inlineCapacity>::shrink(size_t size)
0713 {
0714     ASSERT(size <= m_size);
0715     TypeOperations::destruct(begin() + size, end());
0716     m_size = size;
0717 }
0718 
0719 template<typename T, size_t inlineCapacity>
0720 void Vector<T, inlineCapacity>::grow(size_t size)
0721 {
0722     ASSERT(size >= m_size);
0723     if (size > capacity()) {
0724         expandCapacity(size);
0725     }
0726     if (begin()) {
0727         TypeOperations::initialize(end(), begin() + size);
0728     }
0729     m_size = size;
0730 }
0731 
0732 template<typename T, size_t inlineCapacity>
0733 void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity)
0734 {
0735     if (newCapacity <= capacity()) {
0736         return;
0737     }
0738     T *oldBuffer = begin();
0739     T *oldEnd = end();
0740     m_buffer.allocateBuffer(newCapacity);
0741     if (begin()) {
0742         TypeOperations::move(oldBuffer, oldEnd, begin());
0743     }
0744     m_buffer.deallocateBuffer(oldBuffer);
0745 }
0746 
0747 template<typename T, size_t inlineCapacity>
0748 void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity)
0749 {
0750     if (newCapacity >= capacity()) {
0751         return;
0752     }
0753 
0754     resize(min(m_size, newCapacity));
0755 
0756     T *oldBuffer = begin();
0757     if (newCapacity > 0) {
0758         T *oldEnd = end();
0759         m_buffer.allocateBuffer(newCapacity);
0760         if (begin() != oldBuffer) {
0761             TypeOperations::move(oldBuffer, oldEnd, begin());
0762         }
0763     }
0764 
0765     m_buffer.deallocateBuffer(oldBuffer);
0766 }
0767 
0768 // Templatizing these is better than just letting the conversion happen implicitly,
0769 // because for instance it allows a PassRefPtr to be appended to a RefPtr vector
0770 // without refcount thrash.
0771 
0772 template<typename T, size_t inlineCapacity> template<typename U>
0773 void Vector<T, inlineCapacity>::append(const U *data, size_t dataSize)
0774 {
0775     size_t newSize = m_size + dataSize;
0776     if (newSize > capacity()) {
0777         data = expandCapacity(newSize, data);
0778         if (!begin()) {
0779             return;
0780         }
0781     }
0782     T *dest = end();
0783     for (size_t i = 0; i < dataSize; ++i) {
0784         new(&dest[i]) T(data[i]);
0785     }
0786     m_size = newSize;
0787 }
0788 
0789 template<typename T, size_t inlineCapacity> template<typename U>
0790 inline void Vector<T, inlineCapacity>::append(const U &val)
0791 {
0792     const U *ptr = &val;
0793     if (size() == capacity()) {
0794         ptr = expandCapacity(size() + 1, ptr);
0795         if (!begin()) {
0796             return;
0797         }
0798     }
0799 
0800 #if defined(WTF_COMPILER_MSVC7)
0801     // FIXME: MSVC7 generates compilation errors when trying to assign
0802     // a pointer to a Vector of its base class (i.e. can't downcast). So far
0803     // I've been unable to determine any logical reason for this, so I can
0804     // only assume it is a bug with the compiler. Casting is a bad solution,
0805     // however, because it subverts implicit conversions, so a better
0806     // one is needed.
0807     new(end()) T(static_cast<T>(*ptr));
0808 #else
0809     new(end()) T(*ptr);
0810 #endif
0811     ++m_size;
0812 }
0813 
0814 // This version of append saves a branch in the case where you know that the
0815 // vector's capacity is large enough for the append to succeed.
0816 
0817 template<typename T, size_t inlineCapacity> template<typename U>
0818 inline void Vector<T, inlineCapacity>::uncheckedAppend(const U &val)
0819 {
0820     ASSERT(size() < capacity());
0821     const U *ptr = &val;
0822     new(end()) T(*ptr);
0823     ++m_size;
0824 }
0825 
0826 template<typename T, size_t inlineCapacity> template<typename U, size_t c>
0827 inline void Vector<T, inlineCapacity>::append(const Vector<U, c> &val)
0828 {
0829     append(val.begin(), val.size());
0830 }
0831 
0832 template<typename T, size_t inlineCapacity> template<typename U>
0833 void Vector<T, inlineCapacity>::insert(size_t position, const U *data, size_t dataSize)
0834 {
0835     ASSERT(position <= size());
0836     size_t newSize = m_size + dataSize;
0837     if (newSize > capacity()) {
0838         data = expandCapacity(newSize, data);
0839         if (!begin()) {
0840             return;
0841         }
0842     }
0843     T *spot = begin() + position;
0844     TypeOperations::moveOverlapping(spot, end(), spot + dataSize);
0845     for (size_t i = 0; i < dataSize; ++i) {
0846         new(&spot[i]) T(data[i]);
0847     }
0848     m_size = newSize;
0849 }
0850 
0851 template<typename T, size_t inlineCapacity> template<typename U>
0852 inline void Vector<T, inlineCapacity>::insert(size_t position, const U &val)
0853 {
0854     ASSERT(position <= size());
0855     const U *data = &val;
0856     if (size() == capacity()) {
0857         data = expandCapacity(size() + 1, data);
0858         if (!begin()) {
0859             return;
0860         }
0861     }
0862     T *spot = begin() + position;
0863     TypeOperations::moveOverlapping(spot, end(), spot + 1);
0864     new(spot) T(*data);
0865     ++m_size;
0866 }
0867 
0868 template<typename T, size_t inlineCapacity> template<typename U, size_t c>
0869 inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c> &val)
0870 {
0871     insert(position, val.begin(), val.size());
0872 }
0873 
0874 template<typename T, size_t inlineCapacity> template<typename U>
0875 void Vector<T, inlineCapacity>::prepend(const U *data, size_t dataSize)
0876 {
0877     insert(0, data, dataSize);
0878 }
0879 
0880 template<typename T, size_t inlineCapacity> template<typename U>
0881 inline void Vector<T, inlineCapacity>::prepend(const U &val)
0882 {
0883     insert(0, val);
0884 }
0885 
0886 template<typename T, size_t inlineCapacity> template<typename U, size_t c>
0887 inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c> &val)
0888 {
0889     insert(0, val.begin(), val.size());
0890 }
0891 
0892 template<typename T, size_t inlineCapacity>
0893 inline void Vector<T, inlineCapacity>::remove(size_t position)
0894 {
0895     ASSERT(position < size());
0896     T *spot = begin() + position;
0897     spot->~T();
0898     TypeOperations::moveOverlapping(spot + 1, end(), spot);
0899     --m_size;
0900 }
0901 
0902 template<typename T, size_t inlineCapacity>
0903 inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length)
0904 {
0905     ASSERT(position < size());
0906     ASSERT(position + length < size());
0907     T *beginSpot = begin() + position;
0908     T *endSpot = beginSpot + length;
0909     TypeOperations::destruct(beginSpot, endSpot);
0910     TypeOperations::moveOverlapping(endSpot, end(), beginSpot);
0911     m_size -= length;
0912 }
0913 
0914 template<typename T, size_t inlineCapacity>
0915 inline T *Vector<T, inlineCapacity>::releaseBuffer()
0916 {
0917     T *buffer = m_buffer.releaseBuffer();
0918     if (inlineCapacity && !buffer && m_size) {
0919         // If the vector had some data, but no buffer to release,
0920         // that means it was using the inline buffer. In that case,
0921         // we create a brand new buffer so the caller always gets one.
0922         size_t bytes = m_size * sizeof(T);
0923         buffer = static_cast<T *>(fastMalloc(bytes));
0924         memcpy(buffer, data(), bytes);
0925     }
0926     ASSERT(buffer);
0927     m_size = 0;
0928     return buffer;
0929 }
0930 
0931 template<typename T, size_t inlineCapacity>
0932 void deleteAllValues(const Vector<T, inlineCapacity> &collection)
0933 {
0934     typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
0935     iterator end = collection.end();
0936     for (iterator it = collection.begin(); it != end; ++it) {
0937         delete *it;
0938     }
0939 }
0940 
0941 template<typename T, size_t inlineCapacity>
0942 inline void swap(Vector<T, inlineCapacity> &a, Vector<T, inlineCapacity> &b)
0943 {
0944     a.swap(b);
0945 }
0946 
0947 template<typename T, size_t inlineCapacity>
0948 bool operator==(const Vector<T, inlineCapacity> &a, const Vector<T, inlineCapacity> &b)
0949 {
0950     if (a.size() != b.size()) {
0951         return false;
0952     }
0953 
0954     return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size());
0955 }
0956 
0957 template<typename T, size_t inlineCapacity>
0958 inline bool operator!=(const Vector<T, inlineCapacity> &a, const Vector<T, inlineCapacity> &b)
0959 {
0960     return !(a == b);
0961 }
0962 
0963 } // namespace WTF
0964 
0965 using WTF::Vector;
0966 
0967 #endif // WTF_Vector_h