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