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