00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef LLVM_ADT_SMALLVECTOR_H
00015 #define LLVM_ADT_SMALLVECTOR_H
00016
00017 #include "llvm/Support/type_traits.h"
00018 #include <algorithm>
00019 #include <cassert>
00020 #include <cstddef>
00021 #include <cstdlib>
00022 #include <cstring>
00023 #include <iterator>
00024 #include <memory>
00025
00026 #ifdef _MSC_VER
00027 namespace std {
00028 #if _MSC_VER <= 1310
00029
00030
00031
00032 template<class T1, class T2>
00033 inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
00034 _Scalar_ptr_iterator_tag _Cat;
00035 return _Cat;
00036 }
00037
00038 template<class T1, class T2>
00039 inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
00040 _Scalar_ptr_iterator_tag _Cat;
00041 return _Cat;
00042 }
00043 #else
00044
00045
00046 #endif
00047 }
00048 #endif
00049
00050 namespace llvm {
00051
00054 class SmallVectorBase {
00055 protected:
00056 void *BeginX, *EndX, *CapacityX;
00057
00058
00059
00060
00061
00062
00063 union U {
00064 double D;
00065 long double LD;
00066 long long L;
00067 void *P;
00068 } FirstEl;
00069
00070
00071 protected:
00072 SmallVectorBase(size_t Size)
00073 : BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {}
00074
00077 bool isSmall() const {
00078 return BeginX == static_cast<const void*>(&FirstEl);
00079 }
00080
00083 void grow_pod(size_t MinSizeInBytes, size_t TSize);
00084
00085 public:
00087 size_t size_in_bytes() const {
00088 return size_t((char*)EndX - (char*)BeginX);
00089 }
00090
00092 size_t capacity_in_bytes() const {
00093 return size_t((char*)CapacityX - (char*)BeginX);
00094 }
00095
00096 bool empty() const { return BeginX == EndX; }
00097 };
00098
00099
00100 template <typename T>
00101 class SmallVectorTemplateCommon : public SmallVectorBase {
00102 protected:
00103 void setEnd(T *P) { this->EndX = P; }
00104 public:
00105 SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {}
00106
00107 typedef size_t size_type;
00108 typedef ptrdiff_t difference_type;
00109 typedef T value_type;
00110 typedef T *iterator;
00111 typedef const T *const_iterator;
00112
00113 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00114 typedef std::reverse_iterator<iterator> reverse_iterator;
00115
00116 typedef T &reference;
00117 typedef const T &const_reference;
00118 typedef T *pointer;
00119 typedef const T *const_pointer;
00120
00121
00122 iterator begin() { return (iterator)this->BeginX; }
00123 const_iterator begin() const { return (const_iterator)this->BeginX; }
00124 iterator end() { return (iterator)this->EndX; }
00125 const_iterator end() const { return (const_iterator)this->EndX; }
00126 protected:
00127 iterator capacity_ptr() { return (iterator)this->CapacityX; }
00128 const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;}
00129 public:
00130
00131
00132 reverse_iterator rbegin() { return reverse_iterator(end()); }
00133 const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
00134 reverse_iterator rend() { return reverse_iterator(begin()); }
00135 const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
00136
00137 size_type size() const { return end()-begin(); }
00138 size_type max_size() const { return size_type(-1) / sizeof(T); }
00139
00142 size_t capacity() const { return capacity_ptr() - begin(); }
00143
00145 pointer data() { return pointer(begin()); }
00147 const_pointer data() const { return const_pointer(begin()); }
00148
00149 reference operator[](unsigned idx) {
00150 assert(begin() + idx < end());
00151 return begin()[idx];
00152 }
00153 const_reference operator[](unsigned idx) const {
00154 assert(begin() + idx < end());
00155 return begin()[idx];
00156 }
00157
00158 reference front() {
00159 return begin()[0];
00160 }
00161 const_reference front() const {
00162 return begin()[0];
00163 }
00164
00165 reference back() {
00166 return end()[-1];
00167 }
00168 const_reference back() const {
00169 return end()[-1];
00170 }
00171 };
00172
00175 template <typename T, bool isPodLike>
00176 class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
00177 public:
00178 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
00179
00180 static void destroy_range(T *S, T *E) {
00181 while (S != E) {
00182 --E;
00183 E->~T();
00184 }
00185 }
00186
00189 template<typename It1, typename It2>
00190 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
00191 std::uninitialized_copy(I, E, Dest);
00192 }
00193
00196 void grow(size_t MinSize = 0);
00197 };
00198
00199
00200 template <typename T, bool isPodLike>
00201 void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
00202 size_t CurCapacity = this->capacity();
00203 size_t CurSize = this->size();
00204 size_t NewCapacity = 2*CurCapacity + 1;
00205 if (NewCapacity < MinSize)
00206 NewCapacity = MinSize;
00207 T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
00208
00209
00210 this->uninitialized_copy(this->begin(), this->end(), NewElts);
00211
00212
00213 destroy_range(this->begin(), this->end());
00214
00215
00216 if (!this->isSmall())
00217 free(this->begin());
00218
00219 this->setEnd(NewElts+CurSize);
00220 this->BeginX = NewElts;
00221 this->CapacityX = this->begin()+NewCapacity;
00222 }
00223
00224
00227 template <typename T>
00228 class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
00229 public:
00230 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
00231
00232
00233 static void destroy_range(T *, T *) {}
00234
00237 template<typename It1, typename It2>
00238 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
00239
00240 std::uninitialized_copy(I, E, Dest);
00241 }
00242
00245 template<typename T1, typename T2>
00246 static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) {
00247
00248
00249
00250 memcpy(Dest, I, (E-I)*sizeof(T));
00251 }
00252
00255 void grow(size_t MinSize = 0) {
00256 this->grow_pod(MinSize*sizeof(T), sizeof(T));
00257 }
00258 };
00259
00260
00264 template <typename T>
00265 class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
00266 typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
00267
00268 SmallVectorImpl(const SmallVectorImpl&);
00269 public:
00270 typedef typename SuperClass::iterator iterator;
00271 typedef typename SuperClass::size_type size_type;
00272
00273
00274 explicit SmallVectorImpl(unsigned N)
00275 : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
00276 }
00277
00278 ~SmallVectorImpl() {
00279
00280 this->destroy_range(this->begin(), this->end());
00281
00282
00283 if (!this->isSmall())
00284 free(this->begin());
00285 }
00286
00287
00288 void clear() {
00289 this->destroy_range(this->begin(), this->end());
00290 this->EndX = this->BeginX;
00291 }
00292
00293 void resize(unsigned N) {
00294 if (N < this->size()) {
00295 this->destroy_range(this->begin()+N, this->end());
00296 this->setEnd(this->begin()+N);
00297 } else if (N > this->size()) {
00298 if (this->capacity() < N)
00299 this->grow(N);
00300 this->construct_range(this->end(), this->begin()+N, T());
00301 this->setEnd(this->begin()+N);
00302 }
00303 }
00304
00305 void resize(unsigned N, const T &NV) {
00306 if (N < this->size()) {
00307 this->destroy_range(this->begin()+N, this->end());
00308 this->setEnd(this->begin()+N);
00309 } else if (N > this->size()) {
00310 if (this->capacity() < N)
00311 this->grow(N);
00312 construct_range(this->end(), this->begin()+N, NV);
00313 this->setEnd(this->begin()+N);
00314 }
00315 }
00316
00317 void reserve(unsigned N) {
00318 if (this->capacity() < N)
00319 this->grow(N);
00320 }
00321
00322 void push_back(const T &Elt) {
00323 if (this->EndX < this->CapacityX) {
00324 Retry:
00325 new (this->end()) T(Elt);
00326 this->setEnd(this->end()+1);
00327 return;
00328 }
00329 this->grow();
00330 goto Retry;
00331 }
00332
00333 void pop_back() {
00334 this->setEnd(this->end()-1);
00335 this->end()->~T();
00336 }
00337
00338 T pop_back_val() {
00339 T Result = this->back();
00340 pop_back();
00341 return Result;
00342 }
00343
00344 void swap(SmallVectorImpl &RHS);
00345
00348 template<typename in_iter>
00349 void append(in_iter in_start, in_iter in_end) {
00350 size_type NumInputs = std::distance(in_start, in_end);
00351
00352 if (NumInputs > size_type(this->capacity_ptr()-this->end()))
00353 this->grow(this->size()+NumInputs);
00354
00355
00356
00357
00358 std::uninitialized_copy(in_start, in_end, this->end());
00359 this->setEnd(this->end() + NumInputs);
00360 }
00361
00364 void append(size_type NumInputs, const T &Elt) {
00365
00366 if (NumInputs > size_type(this->capacity_ptr()-this->end()))
00367 this->grow(this->size()+NumInputs);
00368
00369
00370 std::uninitialized_fill_n(this->end(), NumInputs, Elt);
00371 this->setEnd(this->end() + NumInputs);
00372 }
00373
00374 void assign(unsigned NumElts, const T &Elt) {
00375 clear();
00376 if (this->capacity() < NumElts)
00377 this->grow(NumElts);
00378 this->setEnd(this->begin()+NumElts);
00379 construct_range(this->begin(), this->end(), Elt);
00380 }
00381
00382 iterator erase(iterator I) {
00383 iterator N = I;
00384
00385 std::copy(I+1, this->end(), I);
00386
00387 pop_back();
00388 return(N);
00389 }
00390
00391 iterator erase(iterator S, iterator E) {
00392 iterator N = S;
00393
00394 iterator I = std::copy(E, this->end(), S);
00395
00396 this->destroy_range(I, this->end());
00397 this->setEnd(I);
00398 return(N);
00399 }
00400
00401 iterator insert(iterator I, const T &Elt) {
00402 if (I == this->end()) {
00403 push_back(Elt);
00404 return this->end()-1;
00405 }
00406
00407 if (this->EndX < this->CapacityX) {
00408 Retry:
00409 new (this->end()) T(this->back());
00410 this->setEnd(this->end()+1);
00411
00412 std::copy_backward(I, this->end()-1, this->end());
00413
00414
00415
00416 const T *EltPtr = &Elt;
00417 if (I <= EltPtr && EltPtr < this->EndX)
00418 ++EltPtr;
00419
00420 *I = *EltPtr;
00421 return I;
00422 }
00423 size_t EltNo = I-this->begin();
00424 this->grow();
00425 I = this->begin()+EltNo;
00426 goto Retry;
00427 }
00428
00429 iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
00430 if (I == this->end()) {
00431 append(NumToInsert, Elt);
00432 return this->end()-1;
00433 }
00434
00435
00436 size_t InsertElt = I - this->begin();
00437
00438
00439 reserve(static_cast<unsigned>(this->size() + NumToInsert));
00440
00441
00442 I = this->begin()+InsertElt;
00443
00444
00445
00446
00447
00448 if (size_t(this->end()-I) >= NumToInsert) {
00449 T *OldEnd = this->end();
00450 append(this->end()-NumToInsert, this->end());
00451
00452
00453 std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
00454
00455 std::fill_n(I, NumToInsert, Elt);
00456 return I;
00457 }
00458
00459
00460
00461
00462
00463 T *OldEnd = this->end();
00464 this->setEnd(this->end() + NumToInsert);
00465 size_t NumOverwritten = OldEnd-I;
00466 this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
00467
00468
00469 std::fill_n(I, NumOverwritten, Elt);
00470
00471
00472 std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
00473 return I;
00474 }
00475
00476 template<typename ItTy>
00477 iterator insert(iterator I, ItTy From, ItTy To) {
00478 if (I == this->end()) {
00479 append(From, To);
00480 return this->end()-1;
00481 }
00482
00483 size_t NumToInsert = std::distance(From, To);
00484
00485 size_t InsertElt = I - this->begin();
00486
00487
00488 reserve(static_cast<unsigned>(this->size() + NumToInsert));
00489
00490
00491 I = this->begin()+InsertElt;
00492
00493
00494
00495
00496
00497 if (size_t(this->end()-I) >= NumToInsert) {
00498 T *OldEnd = this->end();
00499 append(this->end()-NumToInsert, this->end());
00500
00501
00502 std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
00503
00504 std::copy(From, To, I);
00505 return I;
00506 }
00507
00508
00509
00510
00511
00512 T *OldEnd = this->end();
00513 this->setEnd(this->end() + NumToInsert);
00514 size_t NumOverwritten = OldEnd-I;
00515 this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
00516
00517
00518 for (; NumOverwritten > 0; --NumOverwritten) {
00519 *I = *From;
00520 ++I; ++From;
00521 }
00522
00523
00524 this->uninitialized_copy(From, To, OldEnd);
00525 return I;
00526 }
00527
00528 const SmallVectorImpl
00529 &operator=(const SmallVectorImpl &RHS);
00530
00531 bool operator==(const SmallVectorImpl &RHS) const {
00532 if (this->size() != RHS.size()) return false;
00533 return std::equal(this->begin(), this->end(), RHS.begin());
00534 }
00535 bool operator!=(const SmallVectorImpl &RHS) const {
00536 return !(*this == RHS);
00537 }
00538
00539 bool operator<(const SmallVectorImpl &RHS) const {
00540 return std::lexicographical_compare(this->begin(), this->end(),
00541 RHS.begin(), RHS.end());
00542 }
00543
00553 void set_size(unsigned N) {
00554 assert(N <= this->capacity());
00555 this->setEnd(this->begin() + N);
00556 }
00557
00558 private:
00559 static void construct_range(T *S, T *E, const T &Elt) {
00560 for (; S != E; ++S)
00561 new (S) T(Elt);
00562 }
00563 };
00564
00565
00566 template <typename T>
00567 void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
00568 if (this == &RHS) return;
00569
00570
00571 if (!this->isSmall() && !RHS.isSmall()) {
00572 std::swap(this->BeginX, RHS.BeginX);
00573 std::swap(this->EndX, RHS.EndX);
00574 std::swap(this->CapacityX, RHS.CapacityX);
00575 return;
00576 }
00577 if (RHS.size() > this->capacity())
00578 this->grow(RHS.size());
00579 if (this->size() > RHS.capacity())
00580 RHS.grow(this->size());
00581
00582
00583 size_t NumShared = this->size();
00584 if (NumShared > RHS.size()) NumShared = RHS.size();
00585 for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
00586 std::swap((*this)[i], RHS[i]);
00587
00588
00589 if (this->size() > RHS.size()) {
00590 size_t EltDiff = this->size() - RHS.size();
00591 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
00592 RHS.setEnd(RHS.end()+EltDiff);
00593 this->destroy_range(this->begin()+NumShared, this->end());
00594 this->setEnd(this->begin()+NumShared);
00595 } else if (RHS.size() > this->size()) {
00596 size_t EltDiff = RHS.size() - this->size();
00597 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
00598 this->setEnd(this->end() + EltDiff);
00599 this->destroy_range(RHS.begin()+NumShared, RHS.end());
00600 RHS.setEnd(RHS.begin()+NumShared);
00601 }
00602 }
00603
00604 template <typename T>
00605 const SmallVectorImpl<T> &SmallVectorImpl<T>::
00606 operator=(const SmallVectorImpl<T> &RHS) {
00607
00608 if (this == &RHS) return *this;
00609
00610
00611
00612 size_t RHSSize = RHS.size();
00613 size_t CurSize = this->size();
00614 if (CurSize >= RHSSize) {
00615
00616 iterator NewEnd;
00617 if (RHSSize)
00618 NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
00619 else
00620 NewEnd = this->begin();
00621
00622
00623 this->destroy_range(NewEnd, this->end());
00624
00625
00626 this->setEnd(NewEnd);
00627 return *this;
00628 }
00629
00630
00631
00632 if (this->capacity() < RHSSize) {
00633
00634 this->destroy_range(this->begin(), this->end());
00635 this->setEnd(this->begin());
00636 CurSize = 0;
00637 this->grow(RHSSize);
00638 } else if (CurSize) {
00639
00640 std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
00641 }
00642
00643
00644 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
00645 this->begin()+CurSize);
00646
00647
00648 this->setEnd(this->begin()+RHSSize);
00649 return *this;
00650 }
00651
00652
00661 template <typename T, unsigned N>
00662 class SmallVector : public SmallVectorImpl<T> {
00665 typedef typename SmallVectorImpl<T>::U U;
00666 enum {
00667
00668 MinUs = (static_cast<unsigned int>(sizeof(T))*N +
00669 static_cast<unsigned int>(sizeof(U)) - 1) /
00670 static_cast<unsigned int>(sizeof(U)),
00671
00672
00673
00674
00675 NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
00676
00677
00678
00679 NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/
00680 static_cast<unsigned int>(sizeof(T))
00681 };
00682 U InlineElts[NumInlineEltsElts];
00683 public:
00684 SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
00685 }
00686
00687 explicit SmallVector(unsigned Size, const T &Value = T())
00688 : SmallVectorImpl<T>(NumTsAvailable) {
00689 this->reserve(Size);
00690 while (Size--)
00691 this->push_back(Value);
00692 }
00693
00694 template<typename ItTy>
00695 SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
00696 this->append(S, E);
00697 }
00698
00699 SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
00700 if (!RHS.empty())
00701 SmallVectorImpl<T>::operator=(RHS);
00702 }
00703
00704 const SmallVector &operator=(const SmallVector &RHS) {
00705 SmallVectorImpl<T>::operator=(RHS);
00706 return *this;
00707 }
00708
00709 };
00710
00714 template <typename T>
00715 class SmallVector<T,0> : public SmallVectorImpl<T> {
00716 public:
00717 SmallVector() : SmallVectorImpl<T>(0) {}
00718
00719 explicit SmallVector(unsigned Size, const T &Value = T())
00720 : SmallVectorImpl<T>(0) {
00721 this->reserve(Size);
00722 while (Size--)
00723 this->push_back(Value);
00724 }
00725
00726 template<typename ItTy>
00727 SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(0) {
00728 this->append(S, E);
00729 }
00730
00731 SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(0) {
00732 SmallVectorImpl<T>::operator=(RHS);
00733 }
00734
00735 SmallVector &operator=(const SmallVectorImpl<T> &RHS) {
00736 return SmallVectorImpl<T>::operator=(RHS);
00737 }
00738
00739 };
00740
00741 template<typename T, unsigned N>
00742 static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
00743 return X.capacity_in_bytes();
00744 }
00745
00746 }
00747
00748 namespace std {
00750 template<typename T>
00751 inline void
00752 swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
00753 LHS.swap(RHS);
00754 }
00755
00757 template<typename T, unsigned N>
00758 inline void
00759 swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
00760 LHS.swap(RHS);
00761 }
00762 }
00763
00764 #endif