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