Home | History | Annotate | Download | only in ADT
      1 //===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the SmallVector class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_ADT_SMALLVECTOR_H
     15 #define LLVM_ADT_SMALLVECTOR_H
     16 
     17 #include "llvm/Support/type_traits.h"
     18 #include <algorithm>
     19 #include <cassert>
     20 #include <cstddef>
     21 #include <cstdlib>
     22 #include <cstring>
     23 #include <iterator>
     24 #include <memory>
     25 
     26 #ifdef _MSC_VER
     27 namespace std {
     28 #if _MSC_VER <= 1310
     29   // Work around flawed VC++ implementation of std::uninitialized_copy.  Define
     30   // additional overloads so that elements with pointer types are recognized as
     31   // scalars and not objects, causing bizarre type conversion errors.
     32   template<class T1, class T2>
     33   inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
     34     _Scalar_ptr_iterator_tag _Cat;
     35     return _Cat;
     36   }
     37 
     38   template<class T1, class T2>
     39   inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
     40     _Scalar_ptr_iterator_tag _Cat;
     41     return _Cat;
     42   }
     43 #else
     44 // FIXME: It is not clear if the problem is fixed in VS 2005.  What is clear
     45 // is that the above hack won't work if it wasn't fixed.
     46 #endif
     47 }
     48 #endif
     49 
     50 namespace llvm {
     51 
     52 /// SmallVectorBase - This is all the non-templated stuff common to all
     53 /// SmallVectors.
     54 class SmallVectorBase {
     55 protected:
     56   void *BeginX, *EndX, *CapacityX;
     57 
     58   // Allocate raw space for N elements of type T.  If T has a ctor or dtor, we
     59   // don't want it to be automatically run, so we need to represent the space as
     60   // something else.  An array of char would work great, but might not be
     61   // aligned sufficiently.  Instead we use some number of union instances for
     62   // the space, which guarantee maximal alignment.
     63   union U {
     64     double D;
     65     long double LD;
     66     long long L;
     67     void *P;
     68   } FirstEl;
     69   // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
     70 
     71 protected:
     72   SmallVectorBase(size_t Size)
     73     : BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {}
     74 
     75   /// isSmall - Return true if this is a smallvector which has not had dynamic
     76   /// memory allocated for it.
     77   bool isSmall() const {
     78     return BeginX == static_cast<const void*>(&FirstEl);
     79   }
     80 
     81   /// grow_pod - This is an implementation of the grow() method which only works
     82   /// on POD-like data types and is out of line to reduce code duplication.
     83   void grow_pod(size_t MinSizeInBytes, size_t TSize);
     84 
     85 public:
     86   /// size_in_bytes - This returns size()*sizeof(T).
     87   size_t size_in_bytes() const {
     88     return size_t((char*)EndX - (char*)BeginX);
     89   }
     90 
     91   /// capacity_in_bytes - This returns capacity()*sizeof(T).
     92   size_t capacity_in_bytes() const {
     93     return size_t((char*)CapacityX - (char*)BeginX);
     94   }
     95 
     96   bool empty() const { return BeginX == EndX; }
     97 };
     98 
     99 
    100 template <typename T>
    101 class SmallVectorTemplateCommon : public SmallVectorBase {
    102 protected:
    103   void setEnd(T *P) { this->EndX = P; }
    104 public:
    105   SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {}
    106 
    107   typedef size_t size_type;
    108   typedef ptrdiff_t difference_type;
    109   typedef T value_type;
    110   typedef T *iterator;
    111   typedef const T *const_iterator;
    112 
    113   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
    114   typedef std::reverse_iterator<iterator> reverse_iterator;
    115 
    116   typedef T &reference;
    117   typedef const T &const_reference;
    118   typedef T *pointer;
    119   typedef const T *const_pointer;
    120 
    121   // forward iterator creation methods.
    122   iterator begin() { return (iterator)this->BeginX; }
    123   const_iterator begin() const { return (const_iterator)this->BeginX; }
    124   iterator end() { return (iterator)this->EndX; }
    125   const_iterator end() const { return (const_iterator)this->EndX; }
    126 protected:
    127   iterator capacity_ptr() { return (iterator)this->CapacityX; }
    128   const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;}
    129 public:
    130 
    131   // reverse iterator creation methods.
    132   reverse_iterator rbegin()            { return reverse_iterator(end()); }
    133   const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
    134   reverse_iterator rend()              { return reverse_iterator(begin()); }
    135   const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
    136 
    137   size_type size() const { return end()-begin(); }
    138   size_type max_size() const { return size_type(-1) / sizeof(T); }
    139 
    140   /// capacity - Return the total number of elements in the currently allocated
    141   /// buffer.
    142   size_t capacity() const { return capacity_ptr() - begin(); }
    143 
    144   /// data - Return a pointer to the vector's buffer, even if empty().
    145   pointer data() { return pointer(begin()); }
    146   /// data - Return a pointer to the vector's buffer, even if empty().
    147   const_pointer data() const { return const_pointer(begin()); }
    148 
    149   reference operator[](unsigned idx) {
    150     assert(begin() + idx < end());
    151     return begin()[idx];
    152   }
    153   const_reference operator[](unsigned idx) const {
    154     assert(begin() + idx < end());
    155     return begin()[idx];
    156   }
    157 
    158   reference front() {
    159     return begin()[0];
    160   }
    161   const_reference front() const {
    162     return begin()[0];
    163   }
    164 
    165   reference back() {
    166     return end()[-1];
    167   }
    168   const_reference back() const {
    169     return end()[-1];
    170   }
    171 };
    172 
    173 /// SmallVectorTemplateBase<isPodLike = false> - This is where we put method
    174 /// implementations that are designed to work with non-POD-like T's.
    175 template <typename T, bool isPodLike>
    176 class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
    177 public:
    178   SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
    179 
    180   static void destroy_range(T *S, T *E) {
    181     while (S != E) {
    182       --E;
    183       E->~T();
    184     }
    185   }
    186 
    187   /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
    188   /// starting with "Dest", constructing elements into it as needed.
    189   template<typename It1, typename It2>
    190   static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
    191     std::uninitialized_copy(I, E, Dest);
    192   }
    193 
    194   /// grow - double the size of the allocated memory, guaranteeing space for at
    195   /// least one more element or MinSize if specified.
    196   void grow(size_t MinSize = 0);
    197 };
    198 
    199 // Define this out-of-line to dissuade the C++ compiler from inlining it.
    200 template <typename T, bool isPodLike>
    201 void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
    202   size_t CurCapacity = this->capacity();
    203   size_t CurSize = this->size();
    204   size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero.
    205   if (NewCapacity < MinSize)
    206     NewCapacity = MinSize;
    207   T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
    208 
    209   // Copy the elements over.
    210   this->uninitialized_copy(this->begin(), this->end(), NewElts);
    211 
    212   // Destroy the original elements.
    213   destroy_range(this->begin(), this->end());
    214 
    215   // If this wasn't grown from the inline copy, deallocate the old space.
    216   if (!this->isSmall())
    217     free(this->begin());
    218 
    219   this->setEnd(NewElts+CurSize);
    220   this->BeginX = NewElts;
    221   this->CapacityX = this->begin()+NewCapacity;
    222 }
    223 
    224 
    225 /// SmallVectorTemplateBase<isPodLike = true> - This is where we put method
    226 /// implementations that are designed to work with POD-like T's.
    227 template <typename T>
    228 class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
    229 public:
    230   SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
    231 
    232   // No need to do a destroy loop for POD's.
    233   static void destroy_range(T *, T *) {}
    234 
    235   /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
    236   /// starting with "Dest", constructing elements into it as needed.
    237   template<typename It1, typename It2>
    238   static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
    239     // Arbitrary iterator types; just use the basic implementation.
    240     std::uninitialized_copy(I, E, Dest);
    241   }
    242 
    243   /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
    244   /// starting with "Dest", constructing elements into it as needed.
    245   template<typename T1, typename T2>
    246   static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) {
    247     // Use memcpy for PODs iterated by pointers (which includes SmallVector
    248     // iterators): std::uninitialized_copy optimizes to memmove, but we can
    249     // use memcpy here.
    250     memcpy(Dest, I, (E-I)*sizeof(T));
    251   }
    252 
    253   /// grow - double the size of the allocated memory, guaranteeing space for at
    254   /// least one more element or MinSize if specified.
    255   void grow(size_t MinSize = 0) {
    256     this->grow_pod(MinSize*sizeof(T), sizeof(T));
    257   }
    258 };
    259 
    260 
    261 /// SmallVectorImpl - This class consists of common code factored out of the
    262 /// SmallVector class to reduce code duplication based on the SmallVector 'N'
    263 /// template parameter.
    264 template <typename T>
    265 class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
    266   typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
    267 
    268   SmallVectorImpl(const SmallVectorImpl&); // DISABLED.
    269 public:
    270   typedef typename SuperClass::iterator iterator;
    271   typedef typename SuperClass::size_type size_type;
    272 
    273   // Default ctor - Initialize to empty.
    274   explicit SmallVectorImpl(unsigned N)
    275     : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
    276   }
    277 
    278   ~SmallVectorImpl() {
    279     // Destroy the constructed elements in the vector.
    280     this->destroy_range(this->begin(), this->end());
    281 
    282     // If this wasn't grown from the inline copy, deallocate the old space.
    283     if (!this->isSmall())
    284       free(this->begin());
    285   }
    286 
    287 
    288   void clear() {
    289     this->destroy_range(this->begin(), this->end());
    290     this->EndX = this->BeginX;
    291   }
    292 
    293   void resize(unsigned N) {
    294     if (N < this->size()) {
    295       this->destroy_range(this->begin()+N, this->end());
    296       this->setEnd(this->begin()+N);
    297     } else if (N > this->size()) {
    298       if (this->capacity() < N)
    299         this->grow(N);
    300       this->construct_range(this->end(), this->begin()+N, T());
    301       this->setEnd(this->begin()+N);
    302     }
    303   }
    304 
    305   void resize(unsigned N, const T &NV) {
    306     if (N < this->size()) {
    307       this->destroy_range(this->begin()+N, this->end());
    308       this->setEnd(this->begin()+N);
    309     } else if (N > this->size()) {
    310       if (this->capacity() < N)
    311         this->grow(N);
    312       construct_range(this->end(), this->begin()+N, NV);
    313       this->setEnd(this->begin()+N);
    314     }
    315   }
    316 
    317   void reserve(unsigned N) {
    318     if (this->capacity() < N)
    319       this->grow(N);
    320   }
    321 
    322   void push_back(const T &Elt) {
    323     if (this->EndX < this->CapacityX) {
    324     Retry:
    325       new (this->end()) T(Elt);
    326       this->setEnd(this->end()+1);
    327       return;
    328     }
    329     this->grow();
    330     goto Retry;
    331   }
    332 
    333   void pop_back() {
    334     this->setEnd(this->end()-1);
    335     this->end()->~T();
    336   }
    337 
    338   T pop_back_val() {
    339     T Result = this->back();
    340     pop_back();
    341     return Result;
    342   }
    343 
    344   void swap(SmallVectorImpl &RHS);
    345 
    346   /// append - Add the specified range to the end of the SmallVector.
    347   ///
    348   template<typename in_iter>
    349   void append(in_iter in_start, in_iter in_end) {
    350     size_type NumInputs = std::distance(in_start, in_end);
    351     // Grow allocated space if needed.
    352     if (NumInputs > size_type(this->capacity_ptr()-this->end()))
    353       this->grow(this->size()+NumInputs);
    354 
    355     // Copy the new elements over.
    356     // TODO: NEED To compile time dispatch on whether in_iter is a random access
    357     // iterator to use the fast uninitialized_copy.
    358     std::uninitialized_copy(in_start, in_end, this->end());
    359     this->setEnd(this->end() + NumInputs);
    360   }
    361 
    362   /// append - Add the specified range to the end of the SmallVector.
    363   ///
    364   void append(size_type NumInputs, const T &Elt) {
    365     // Grow allocated space if needed.
    366     if (NumInputs > size_type(this->capacity_ptr()-this->end()))
    367       this->grow(this->size()+NumInputs);
    368 
    369     // Copy the new elements over.
    370     std::uninitialized_fill_n(this->end(), NumInputs, Elt);
    371     this->setEnd(this->end() + NumInputs);
    372   }
    373 
    374   void assign(unsigned NumElts, const T &Elt) {
    375     clear();
    376     if (this->capacity() < NumElts)
    377       this->grow(NumElts);
    378     this->setEnd(this->begin()+NumElts);
    379     construct_range(this->begin(), this->end(), Elt);
    380   }
    381 
    382   iterator erase(iterator I) {
    383     iterator N = I;
    384     // Shift all elts down one.
    385     std::copy(I+1, this->end(), I);
    386     // Drop the last elt.
    387     pop_back();
    388     return(N);
    389   }
    390 
    391   iterator erase(iterator S, iterator E) {
    392     iterator N = S;
    393     // Shift all elts down.
    394     iterator I = std::copy(E, this->end(), S);
    395     // Drop the last elts.
    396     this->destroy_range(I, this->end());
    397     this->setEnd(I);
    398     return(N);
    399   }
    400 
    401   iterator insert(iterator I, const T &Elt) {
    402     if (I == this->end()) {  // Important special case for empty vector.
    403       push_back(Elt);
    404       return this->end()-1;
    405     }
    406 
    407     if (this->EndX < this->CapacityX) {
    408     Retry:
    409       new (this->end()) T(this->back());
    410       this->setEnd(this->end()+1);
    411       // Push everything else over.
    412       std::copy_backward(I, this->end()-1, this->end());
    413 
    414       // If we just moved the element we're inserting, be sure to update
    415       // the reference.
    416       const T *EltPtr = &Elt;
    417       if (I <= EltPtr && EltPtr < this->EndX)
    418         ++EltPtr;
    419 
    420       *I = *EltPtr;
    421       return I;
    422     }
    423     size_t EltNo = I-this->begin();
    424     this->grow();
    425     I = this->begin()+EltNo;
    426     goto Retry;
    427   }
    428 
    429   iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
    430     if (I == this->end()) {  // Important special case for empty vector.
    431       append(NumToInsert, Elt);
    432       return this->end()-1;
    433     }
    434 
    435     // Convert iterator to elt# to avoid invalidating iterator when we reserve()
    436     size_t InsertElt = I - this->begin();
    437 
    438     // Ensure there is enough space.
    439     reserve(static_cast<unsigned>(this->size() + NumToInsert));
    440 
    441     // Uninvalidate the iterator.
    442     I = this->begin()+InsertElt;
    443 
    444     // If there are more elements between the insertion point and the end of the
    445     // range than there are being inserted, we can use a simple approach to
    446     // insertion.  Since we already reserved space, we know that this won't
    447     // reallocate the vector.
    448     if (size_t(this->end()-I) >= NumToInsert) {
    449       T *OldEnd = this->end();
    450       append(this->end()-NumToInsert, this->end());
    451 
    452       // Copy the existing elements that get replaced.
    453       std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
    454 
    455       std::fill_n(I, NumToInsert, Elt);
    456       return I;
    457     }
    458 
    459     // Otherwise, we're inserting more elements than exist already, and we're
    460     // not inserting at the end.
    461 
    462     // Copy over the elements that we're about to overwrite.
    463     T *OldEnd = this->end();
    464     this->setEnd(this->end() + NumToInsert);
    465     size_t NumOverwritten = OldEnd-I;
    466     this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
    467 
    468     // Replace the overwritten part.
    469     std::fill_n(I, NumOverwritten, Elt);
    470 
    471     // Insert the non-overwritten middle part.
    472     std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
    473     return I;
    474   }
    475 
    476   template<typename ItTy>
    477   iterator insert(iterator I, ItTy From, ItTy To) {
    478     if (I == this->end()) {  // Important special case for empty vector.
    479       append(From, To);
    480       return this->end()-1;
    481     }
    482 
    483     size_t NumToInsert = std::distance(From, To);
    484     // Convert iterator to elt# to avoid invalidating iterator when we reserve()
    485     size_t InsertElt = I - this->begin();
    486 
    487     // Ensure there is enough space.
    488     reserve(static_cast<unsigned>(this->size() + NumToInsert));
    489 
    490     // Uninvalidate the iterator.
    491     I = this->begin()+InsertElt;
    492 
    493     // If there are more elements between the insertion point and the end of the
    494     // range than there are being inserted, we can use a simple approach to
    495     // insertion.  Since we already reserved space, we know that this won't
    496     // reallocate the vector.
    497     if (size_t(this->end()-I) >= NumToInsert) {
    498       T *OldEnd = this->end();
    499       append(this->end()-NumToInsert, this->end());
    500 
    501       // Copy the existing elements that get replaced.
    502       std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
    503 
    504       std::copy(From, To, I);
    505       return I;
    506     }
    507 
    508     // Otherwise, we're inserting more elements than exist already, and we're
    509     // not inserting at the end.
    510 
    511     // Copy over the elements that we're about to overwrite.
    512     T *OldEnd = this->end();
    513     this->setEnd(this->end() + NumToInsert);
    514     size_t NumOverwritten = OldEnd-I;
    515     this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
    516 
    517     // Replace the overwritten part.
    518     for (; NumOverwritten > 0; --NumOverwritten) {
    519       *I = *From;
    520       ++I; ++From;
    521     }
    522 
    523     // Insert the non-overwritten middle part.
    524     this->uninitialized_copy(From, To, OldEnd);
    525     return I;
    526   }
    527 
    528   const SmallVectorImpl
    529   &operator=(const SmallVectorImpl &RHS);
    530 
    531   bool operator==(const SmallVectorImpl &RHS) const {
    532     if (this->size() != RHS.size()) return false;
    533     return std::equal(this->begin(), this->end(), RHS.begin());
    534   }
    535   bool operator!=(const SmallVectorImpl &RHS) const {
    536     return !(*this == RHS);
    537   }
    538 
    539   bool operator<(const SmallVectorImpl &RHS) const {
    540     return std::lexicographical_compare(this->begin(), this->end(),
    541                                         RHS.begin(), RHS.end());
    542   }
    543 
    544   /// set_size - Set the array size to \arg N, which the current array must have
    545   /// enough capacity for.
    546   ///
    547   /// This does not construct or destroy any elements in the vector.
    548   ///
    549   /// Clients can use this in conjunction with capacity() to write past the end
    550   /// of the buffer when they know that more elements are available, and only
    551   /// update the size later. This avoids the cost of value initializing elements
    552   /// which will only be overwritten.
    553   void set_size(unsigned N) {
    554     assert(N <= this->capacity());
    555     this->setEnd(this->begin() + N);
    556   }
    557 
    558 private:
    559   static void construct_range(T *S, T *E, const T &Elt) {
    560     for (; S != E; ++S)
    561       new (S) T(Elt);
    562   }
    563 };
    564 
    565 
    566 template <typename T>
    567 void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
    568   if (this == &RHS) return;
    569 
    570   // We can only avoid copying elements if neither vector is small.
    571   if (!this->isSmall() && !RHS.isSmall()) {
    572     std::swap(this->BeginX, RHS.BeginX);
    573     std::swap(this->EndX, RHS.EndX);
    574     std::swap(this->CapacityX, RHS.CapacityX);
    575     return;
    576   }
    577   if (RHS.size() > this->capacity())
    578     this->grow(RHS.size());
    579   if (this->size() > RHS.capacity())
    580     RHS.grow(this->size());
    581 
    582   // Swap the shared elements.
    583   size_t NumShared = this->size();
    584   if (NumShared > RHS.size()) NumShared = RHS.size();
    585   for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
    586     std::swap((*this)[i], RHS[i]);
    587 
    588   // Copy over the extra elts.
    589   if (this->size() > RHS.size()) {
    590     size_t EltDiff = this->size() - RHS.size();
    591     this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
    592     RHS.setEnd(RHS.end()+EltDiff);
    593     this->destroy_range(this->begin()+NumShared, this->end());
    594     this->setEnd(this->begin()+NumShared);
    595   } else if (RHS.size() > this->size()) {
    596     size_t EltDiff = RHS.size() - this->size();
    597     this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
    598     this->setEnd(this->end() + EltDiff);
    599     this->destroy_range(RHS.begin()+NumShared, RHS.end());
    600     RHS.setEnd(RHS.begin()+NumShared);
    601   }
    602 }
    603 
    604 template <typename T>
    605 const SmallVectorImpl<T> &SmallVectorImpl<T>::
    606   operator=(const SmallVectorImpl<T> &RHS) {
    607   // Avoid self-assignment.
    608   if (this == &RHS) return *this;
    609 
    610   // If we already have sufficient space, assign the common elements, then
    611   // destroy any excess.
    612   size_t RHSSize = RHS.size();
    613   size_t CurSize = this->size();
    614   if (CurSize >= RHSSize) {
    615     // Assign common elements.
    616     iterator NewEnd;
    617     if (RHSSize)
    618       NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
    619     else
    620       NewEnd = this->begin();
    621 
    622     // Destroy excess elements.
    623     this->destroy_range(NewEnd, this->end());
    624 
    625     // Trim.
    626     this->setEnd(NewEnd);
    627     return *this;
    628   }
    629 
    630   // If we have to grow to have enough elements, destroy the current elements.
    631   // This allows us to avoid copying them during the grow.
    632   if (this->capacity() < RHSSize) {
    633     // Destroy current elements.
    634     this->destroy_range(this->begin(), this->end());
    635     this->setEnd(this->begin());
    636     CurSize = 0;
    637     this->grow(RHSSize);
    638   } else if (CurSize) {
    639     // Otherwise, use assignment for the already-constructed elements.
    640     std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
    641   }
    642 
    643   // Copy construct the new elements in place.
    644   this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
    645                            this->begin()+CurSize);
    646 
    647   // Set end.
    648   this->setEnd(this->begin()+RHSSize);
    649   return *this;
    650 }
    651 
    652 
    653 /// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
    654 /// for the case when the array is small.  It contains some number of elements
    655 /// in-place, which allows it to avoid heap allocation when the actual number of
    656 /// elements is below that threshold.  This allows normal "small" cases to be
    657 /// fast without losing generality for large inputs.
    658 ///
    659 /// Note that this does not attempt to be exception safe.
    660 ///
    661 template <typename T, unsigned N>
    662 class SmallVector : public SmallVectorImpl<T> {
    663   /// InlineElts - These are 'N-1' elements that are stored inline in the body
    664   /// of the vector.  The extra '1' element is stored in SmallVectorImpl.
    665   typedef typename SmallVectorImpl<T>::U U;
    666   enum {
    667     // MinUs - The number of U's require to cover N T's.
    668     MinUs = (static_cast<unsigned int>(sizeof(T))*N +
    669              static_cast<unsigned int>(sizeof(U)) - 1) /
    670             static_cast<unsigned int>(sizeof(U)),
    671 
    672     // NumInlineEltsElts - The number of elements actually in this array.  There
    673     // is already one in the parent class, and we have to round up to avoid
    674     // having a zero-element array.
    675     NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
    676 
    677     // NumTsAvailable - The number of T's we actually have space for, which may
    678     // be more than N due to rounding.
    679     NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/
    680                      static_cast<unsigned int>(sizeof(T))
    681   };
    682   U InlineElts[NumInlineEltsElts];
    683 public:
    684   SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
    685   }
    686 
    687   explicit SmallVector(unsigned Size, const T &Value = T())
    688     : SmallVectorImpl<T>(NumTsAvailable) {
    689     this->reserve(Size);
    690     while (Size--)
    691       this->push_back(Value);
    692   }
    693 
    694   template<typename ItTy>
    695   SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
    696     this->append(S, E);
    697   }
    698 
    699   SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
    700     if (!RHS.empty())
    701       SmallVectorImpl<T>::operator=(RHS);
    702   }
    703 
    704   const SmallVector &operator=(const SmallVector &RHS) {
    705     SmallVectorImpl<T>::operator=(RHS);
    706     return *this;
    707   }
    708 
    709 };
    710 
    711 /// Specialize SmallVector at N=0.  This specialization guarantees
    712 /// that it can be instantiated at an incomplete T if none of its
    713 /// members are required.
    714 template <typename T>
    715 class SmallVector<T,0> : public SmallVectorImpl<T> {
    716 public:
    717   SmallVector() : SmallVectorImpl<T>(0) {}
    718 
    719   explicit SmallVector(unsigned Size, const T &Value = T())
    720     : SmallVectorImpl<T>(0) {
    721     this->reserve(Size);
    722     while (Size--)
    723       this->push_back(Value);
    724   }
    725 
    726   template<typename ItTy>
    727   SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(0) {
    728     this->append(S, E);
    729   }
    730 
    731   SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(0) {
    732     SmallVectorImpl<T>::operator=(RHS);
    733   }
    734 
    735   SmallVector &operator=(const SmallVectorImpl<T> &RHS) {
    736     return SmallVectorImpl<T>::operator=(RHS);
    737   }
    738 
    739 };
    740 
    741 template<typename T, unsigned N>
    742 static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
    743   return X.capacity_in_bytes();
    744 }
    745 
    746 } // End llvm namespace
    747 
    748 namespace std {
    749   /// Implement std::swap in terms of SmallVector swap.
    750   template<typename T>
    751   inline void
    752   swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
    753     LHS.swap(RHS);
    754   }
    755 
    756   /// Implement std::swap in terms of SmallVector swap.
    757   template<typename T, unsigned N>
    758   inline void
    759   swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
    760     LHS.swap(RHS);
    761   }
    762 }
    763 
    764 #endif
    765