00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef WTF_Vector_h
00024 #define WTF_Vector_h
00025
00026 #include "Assertions.h"
00027 #include "FastMalloc.h"
00028 #include "VectorTraits.h"
00029 #include <limits>
00030 #include <stdlib.h>
00031 #include <cstring>
00032 #include <utility>
00033
00034
00035
00036 #undef max
00037
00038 namespace WTF {
00039
00040 using std::min;
00041 using std::max;
00042
00043 template <bool needsDestruction, typename T>
00044 struct VectorDestructor;
00045
00046 template<typename T>
00047 struct VectorDestructor<false, T>
00048 {
00049 static void destruct(T*, T*) {}
00050 };
00051
00052 template<typename T>
00053 struct VectorDestructor<true, T>
00054 {
00055 static void destruct(T* begin, T* end)
00056 {
00057 for (T* cur = begin; cur != end; ++cur)
00058 cur->~T();
00059 }
00060 };
00061
00062 template <bool needsInitialization, bool canInitializeWithMemset, typename T>
00063 struct VectorInitializer;
00064
00065 template<bool ignore, typename T>
00066 struct VectorInitializer<false, ignore, T>
00067 {
00068 static void initialize(T*, T*) {}
00069 };
00070
00071 template<typename T>
00072 struct VectorInitializer<true, false, T>
00073 {
00074 static void initialize(T* begin, T* end)
00075 {
00076 for (T* cur = begin; cur != end; ++cur)
00077 new (cur) T;
00078 }
00079 };
00080
00081 template<typename T>
00082 struct VectorInitializer<true, true, T>
00083 {
00084 static void initialize(T* begin, T* end)
00085 {
00086 std::memset(begin, 0, reinterpret_cast<char *>(end) - reinterpret_cast<char *>(begin));
00087 }
00088 };
00089
00090 template <bool canMoveWithMemcpy, typename T>
00091 struct VectorMover;
00092
00093 template<typename T>
00094 struct VectorMover<false, T>
00095 {
00096 static void move(const T* src, const T* srcEnd, T* dst)
00097 {
00098 while (src != srcEnd) {
00099 new (dst) T(*src);
00100 src->~T();
00101 ++dst;
00102 ++src;
00103 }
00104 }
00105 static void moveOverlapping(const T* src, const T* srcEnd, T* dst)
00106 {
00107 if (src > dst)
00108 move(src, srcEnd, dst);
00109 else {
00110 T* dstEnd = dst + (srcEnd - src);
00111 while (src != srcEnd) {
00112 --srcEnd;
00113 --dstEnd;
00114 new (dstEnd) T(*srcEnd);
00115 srcEnd->~T();
00116 }
00117 }
00118 }
00119 };
00120
00121 template<typename T>
00122 struct VectorMover<true, T>
00123 {
00124 static void move(const T* src, const T* srcEnd, T* dst)
00125 {
00126 std::memcpy(dst, src, reinterpret_cast<const char *>(srcEnd) - reinterpret_cast<const char *>(src));
00127 }
00128 static void moveOverlapping(const T* src, const T* srcEnd, T* dst)
00129 {
00130 std::memmove(dst, src, reinterpret_cast<const char *>(srcEnd) - reinterpret_cast<const char *>(src));
00131 }
00132 };
00133
00134 template <bool canCopyWithMemcpy, typename T>
00135 struct VectorCopier;
00136
00137 template<typename T>
00138 struct VectorCopier<false, T>
00139 {
00140 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst)
00141 {
00142 while (src != srcEnd) {
00143 new (dst) T(*src);
00144 ++dst;
00145 ++src;
00146 }
00147 }
00148 };
00149
00150 template<typename T>
00151 struct VectorCopier<true, T>
00152 {
00153 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst)
00154 {
00155 std::memcpy(dst, src, reinterpret_cast<const char *>(srcEnd) - reinterpret_cast<const char *>(src));
00156 }
00157 };
00158
00159 template <bool canFillWithMemset, typename T>
00160 struct VectorFiller;
00161
00162 template<typename T>
00163 struct VectorFiller<false, T>
00164 {
00165 static void uninitializedFill(T* dst, T* dstEnd, const T& val)
00166 {
00167 while (dst != dstEnd) {
00168 new (dst) T(val);
00169 ++dst;
00170 }
00171 }
00172 };
00173
00174 template<typename T>
00175 struct VectorFiller<true, T>
00176 {
00177 static void uninitializedFill(T* dst, T* dstEnd, const T& val)
00178 {
00179 ASSERT(sizeof(T) == sizeof(char));
00180 std::memset(dst, val, dstEnd - dst);
00181 }
00182 };
00183
00184 template<typename T>
00185 struct VectorTypeOperations
00186 {
00187 static void destruct(T* begin, T* end)
00188 {
00189 VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, end);
00190 }
00191
00192 static void initialize(T* begin, T* end)
00193 {
00194 VectorInitializer<VectorTraits<T>::needsInitialization, VectorTraits<T>::canInitializeWithMemset, T>::initialize(begin, end);
00195 }
00196
00197 static void move(const T* src, const T* srcEnd, T* dst)
00198 {
00199 VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::move(src, srcEnd, dst);
00200 }
00201
00202 static void moveOverlapping(const T* src, const T* srcEnd, T* dst)
00203 {
00204 VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::moveOverlapping(src, srcEnd, dst);
00205 }
00206
00207 static void uninitializedCopy(const T* src, const T* srcEnd, T* dst)
00208 {
00209 VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(src, srcEnd, dst);
00210 }
00211
00212 static void uninitializedFill(T* dst, T* dstEnd, const T& val)
00213 {
00214 VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFill(dst, dstEnd, val);
00215 }
00216 };
00217
00218 template<typename T, size_t inlineCapacity>
00219 class VectorBuffer;
00220
00221 template<typename T>
00222 class VectorBuffer<T, 0>
00223 {
00224 public:
00225 VectorBuffer()
00226 : m_capacity(0)
00227 , m_buffer(0)
00228 {
00229 }
00230
00231 VectorBuffer(size_t capacity)
00232 : m_capacity(0)
00233 {
00234 allocateBuffer(capacity);
00235 }
00236
00237 ~VectorBuffer()
00238 {
00239 deallocateBuffer(m_buffer);
00240 }
00241
00242 void swap(VectorBuffer<T, 0>& other)
00243 {
00244 std::swap(m_buffer, other.m_buffer);
00245 std::swap(m_capacity, other.m_capacity);
00246 }
00247
00248 void deallocateBuffer(T* buffer)
00249 {
00250 fastFree(buffer);
00251 }
00252
00253 void allocateBuffer(size_t newCapacity)
00254 {
00255 ASSERT(newCapacity >= m_capacity);
00256 m_capacity = newCapacity;
00257 if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
00258 abort();
00259 m_buffer = reinterpret_cast<T*>(fastMalloc(newCapacity * sizeof(T)));
00260 }
00261
00262 T* buffer() { return m_buffer; }
00263 const T* buffer() const { return m_buffer; }
00264 size_t capacity() const { return m_capacity; }
00265
00266 protected:
00267 VectorBuffer(T* buffer, size_t capacity)
00268 : m_capacity(capacity)
00269 , m_buffer(buffer)
00270 {
00271 }
00272
00273 size_t m_capacity;
00274 T *m_buffer;
00275 };
00276
00277 template<typename T, size_t inlineCapacity>
00278 class VectorBuffer : public VectorBuffer<T, 0> {
00279 private:
00280 typedef VectorBuffer<T, 0> BaseBuffer;
00281 public:
00282 VectorBuffer()
00283 : BaseBuffer(inlineBuffer(), inlineCapacity)
00284 {
00285 }
00286
00287 VectorBuffer(size_t capacity)
00288 : BaseBuffer(inlineBuffer(), inlineCapacity)
00289 {
00290 if (capacity > inlineCapacity)
00291 BaseBuffer::allocateBuffer(capacity);
00292 }
00293
00294 ~VectorBuffer()
00295 {
00296 if (BaseBuffer::buffer() == inlineBuffer())
00297 BaseBuffer::m_buffer = 0;
00298 }
00299
00300 void deallocateBuffer(T* buffer)
00301 {
00302 if (buffer != inlineBuffer())
00303 BaseBuffer::deallocateBuffer(buffer);
00304 }
00305
00306 private:
00307 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T);
00308 T *inlineBuffer() { return reinterpret_cast<T *>(&m_inlineBuffer); }
00309 char m_inlineBuffer[m_inlineBufferSize];
00310 };
00311
00312 template<typename T, size_t inlineCapacity = 0>
00313 class Vector {
00314 private:
00315 typedef VectorBuffer<T, inlineCapacity> Impl;
00316 typedef VectorTypeOperations<T> TypeOperations;
00317
00318 public:
00319 typedef T* iterator;
00320 typedef const T* const_iterator;
00321
00322 Vector()
00323 : m_size(0)
00324 {
00325 }
00326
00327 explicit Vector(size_t size)
00328 : m_size(0)
00329 {
00330 resize(size);
00331 }
00332
00333 ~Vector()
00334 {
00335 clear();
00336 }
00337
00338 Vector(const Vector&);
00339 template<size_t otherCapacity>
00340 Vector(const Vector<T, otherCapacity>&);
00341
00342 Vector& operator=(const Vector&);
00343 template<size_t otherCapacity>
00344 Vector& operator=(const Vector<T, otherCapacity>&);
00345
00346 size_t size() const { return m_size; }
00347 size_t capacity() const { return m_impl.capacity(); }
00348 bool isEmpty() const { return !size(); }
00349
00350 T& at(size_t i)
00351 {
00352 ASSERT(i < size());
00353 return m_impl.buffer()[i];
00354 }
00355 const T& at(size_t i) const
00356 {
00357 ASSERT(i < size());
00358 return m_impl.buffer()[i];
00359 }
00360
00361 T& operator[](long i) { return at(i); }
00362 const T& operator[](long i) const { return at(i); }
00363 T& operator[](unsigned long i) { return at(i); }
00364 const T& operator[](unsigned long i) const { return at(i); }
00365 T& operator[](int i) { return at(i); }
00366 const T& operator[](int i) const { return at(i); }
00367 T& operator[](unsigned i) { return at(i); }
00368 const T& operator[](unsigned i) const { return at(i); }
00369 T& operator[](short i) { return at(i); }
00370 const T& operator[](short i) const { return at(i); }
00371 T& operator[](unsigned short i) { return at(i); }
00372 const T& operator[](unsigned short i) const { return at(i); }
00373
00374 T* data() { return m_impl.buffer(); }
00375 const T* data() const { return m_impl.buffer(); }
00376 operator T*() { return data(); }
00377 operator const T*() const { return data(); }
00378
00379 iterator begin() { return data(); }
00380 iterator end() { return begin() + m_size; }
00381 const_iterator begin() const { return data(); }
00382 const_iterator end() const { return begin() + m_size; }
00383
00384 T& first() { return at(0); }
00385 const T& first() const { return at(0); }
00386 T& last() { return at(size() - 1); }
00387 const T& last() const { return at(size() - 1); }
00388
00389 void resize(size_t size);
00390 void reserveCapacity(size_t newCapacity);
00391
00392 void clear() { resize(0); }
00393
00394 template<typename U> void append(const U&);
00395 template<typename U> void append(const Vector<U>&);
00396 template<typename U> void insert(size_t position, const U&);
00397 void remove(size_t position);
00398
00399 void removeLast()
00400 {
00401 ASSERT(!isEmpty());
00402 resize(size() - 1);
00403 }
00404
00405 Vector(size_t size, const T& val)
00406 : m_size(size)
00407 , m_impl(size)
00408 {
00409 TypeOperations::uninitializedFill(begin(), end(), val);
00410 }
00411
00412 void fill(const T& val, size_t size);
00413 void fill(const T& val) { fill(val, size()); }
00414
00415 void swap(Vector<T, inlineCapacity>& other)
00416 {
00417 std::swap(m_size, other.m_size);
00418 m_impl.swap(other.m_impl);
00419 }
00420
00421 private:
00422 void expandCapacity(size_t newMinCapacity);
00423 const T* expandCapacity(size_t newMinCapacity, const T*);
00424 template<typename U> U* expandCapacity(size_t newMinCapacity, U*);
00425
00426 size_t m_size;
00427 Impl m_impl;
00428 };
00429
00430 template<typename T, size_t inlineCapacity>
00431 Vector<T, inlineCapacity>::Vector(const Vector& other)
00432 : m_size(other.size())
00433 , m_impl(other.capacity())
00434 {
00435 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
00436 }
00437
00438 template<typename T, size_t inlineCapacity>
00439 template<size_t otherCapacity>
00440 Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other)
00441 : m_size(other.size())
00442 , m_impl(other.capacity())
00443 {
00444 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
00445 }
00446
00447 template<typename T, size_t inlineCapacity>
00448 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other)
00449 {
00450 if (&other == this)
00451 return *this;
00452
00453 if (size() > other.size())
00454 resize(other.size());
00455 else if (other.size() > capacity()) {
00456 clear();
00457 reserveCapacity(other.size());
00458 }
00459
00460 std::copy(other.begin(), other.begin() + size(), begin());
00461 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
00462 m_size = other.size();
00463
00464 return *this;
00465 }
00466
00467 template<typename T, size_t inlineCapacity>
00468 template<size_t otherCapacity>
00469 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other)
00470 {
00471 if (&other == this)
00472 return *this;
00473
00474 if (size() > other.size())
00475 resize(other.size());
00476 else if (other.size() > capacity()) {
00477 clear();
00478 reserveCapacity(other.size());
00479 }
00480
00481 std::copy(other.begin(), other.begin() + size(), begin());
00482 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end());
00483 m_size = other.size();
00484
00485 return *this;
00486 }
00487
00488 template<typename T, size_t inlineCapacity>
00489 void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize)
00490 {
00491 if (size() > newSize)
00492 resize(newSize);
00493 else if (newSize > capacity()) {
00494 clear();
00495 reserveCapacity(newSize);
00496 }
00497
00498 std::fill(begin(), end(), val);
00499 TypeOperations::uninitializedFill(end(), begin() + newSize, val);
00500 m_size = newSize;
00501 }
00502
00503 template<typename T, size_t inlineCapacity>
00504 void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
00505 {
00506 reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
00507 }
00508
00509 template<typename T, size_t inlineCapacity>
00510 const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr)
00511 {
00512 if (ptr < begin() || ptr >= end()) {
00513 expandCapacity(newMinCapacity);
00514 return ptr;
00515 }
00516 size_t index = ptr - begin();
00517 expandCapacity(newMinCapacity);
00518 return begin() + index;
00519 }
00520
00521 template<typename T, size_t inlineCapacity> template<typename U>
00522 inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
00523 {
00524 expandCapacity(newMinCapacity);
00525 return ptr;
00526 }
00527
00528 template<typename T, size_t inlineCapacity>
00529 void Vector<T, inlineCapacity>::resize(size_t size)
00530 {
00531 if (size <= m_size)
00532 TypeOperations::destruct(begin() + size, end());
00533 else {
00534 if (size > capacity())
00535 expandCapacity(size);
00536 TypeOperations::initialize(end(), begin() + size);
00537 }
00538
00539 m_size = size;
00540 }
00541
00542 template<typename T, size_t inlineCapacity>
00543 void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity)
00544 {
00545 if (newCapacity < capacity())
00546 return;
00547 T* oldBuffer = begin();
00548 T* oldEnd = end();
00549 m_impl.allocateBuffer(newCapacity);
00550 TypeOperations::move(oldBuffer, oldEnd, begin());
00551 m_impl.deallocateBuffer(oldBuffer);
00552 }
00553
00554
00555
00556
00557
00558 template<typename T, size_t inlineCapacity> template<typename U>
00559 inline void Vector<T, inlineCapacity>::append(const U& val)
00560 {
00561 const U* ptr = &val;
00562 if (size() == capacity())
00563 ptr = expandCapacity(size() + 1, ptr);
00564 #if defined(_MSC_VER)
00565 new (end()) T(static_cast<T>(*ptr));
00566 #else
00567 new (end()) T(*ptr);
00568 #endif
00569 ++m_size;
00570 }
00571
00572 template<typename T, size_t inlineCapacity> template<typename U>
00573 inline void Vector<T, inlineCapacity>::append(const Vector<U>& val)
00574 {
00575 if (size() + val.size() >= capacity())
00576 expandCapacity(size() + val.size());
00577 for (unsigned i = 0; i < val.size(); i++)
00578 append(val[i]);
00579 }
00580
00581 template<typename T, size_t inlineCapacity> template<typename U>
00582 inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val)
00583 {
00584 ASSERT(position <= size());
00585 const U* ptr = &val;
00586 if (size() == capacity())
00587 ptr = expandCapacity(size() + 1, ptr);
00588 T* spot = begin() + position;
00589 TypeOperations::moveOverlapping(spot, end(), spot + 1);
00590 new (spot) T(*ptr);
00591 ++m_size;
00592 }
00593
00594 template<typename T, size_t inlineCapacity>
00595 inline void Vector<T, inlineCapacity>::remove(size_t position)
00596 {
00597 ASSERT(position < size());
00598 T* spot = begin() + position;
00599 spot->~T();
00600 TypeOperations::moveOverlapping(spot + 1, end(), spot);
00601 --m_size;
00602 }
00603
00604 template<typename T, size_t inlineCapacity>
00605 void deleteAllValues(const Vector<T, inlineCapacity>& collection)
00606 {
00607 typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
00608 iterator end = collection.end();
00609 for (iterator it = collection.begin(); it != end; ++it)
00610 delete *it;
00611 }
00612
00613 template<typename T, size_t inlineCapacity>
00614 inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b)
00615 {
00616 a.swap(b);
00617 }
00618
00619 }
00620
00621 using WTF::Vector;
00622
00623 #endif // WTF_Vector_h
00624