LCOV - code coverage report
Current view: top level - llvm/ADT - SmallVector.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 29 38 76.3 %
Date: 2016-01-31 12:01:00 Functions: 19 48 39.6 %

          Line data    Source code
       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/ADT/iterator_range.h"
      18             : #include "llvm/Support/AlignOf.h"
      19             : #include "llvm/Support/Compiler.h"
      20             : #include "llvm/Support/MathExtras.h"
      21             : #include "llvm/Support/type_traits.h"
      22             : #include <algorithm>
      23             : #include <cassert>
      24             : #include <cstddef>
      25             : #include <cstdlib>
      26             : #include <cstring>
      27             : #include <initializer_list>
      28             : #include <iterator>
      29             : #include <memory>
      30             : 
      31             : namespace llvm {
      32             : 
      33             : /// This is all the non-templated stuff common to all SmallVectors.
      34             : class SmallVectorBase {
      35             : protected:
      36             :   void *BeginX, *EndX, *CapacityX;
      37             : 
      38             : protected:
      39             :   SmallVectorBase(void *FirstEl, size_t Size)
      40           2 :     : BeginX(FirstEl), EndX(FirstEl), CapacityX((char*)FirstEl+Size) {}
      41             : 
      42             :   /// This is an implementation of the grow() method which only works
      43             :   /// on POD-like data types and is out of line to reduce code duplication.
      44             :   void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize);
      45             : 
      46             : public:
      47             :   /// This returns size()*sizeof(T).
      48             :   size_t size_in_bytes() const {
      49             :     return size_t((char*)EndX - (char*)BeginX);
      50             :   }
      51             : 
      52             :   /// capacity_in_bytes - This returns capacity()*sizeof(T).
      53             :   size_t capacity_in_bytes() const {
      54             :     return size_t((char*)CapacityX - (char*)BeginX);
      55             :   }
      56             : 
      57          18 :   bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return BeginX == EndX; }
      58             : };
      59             : 
      60             : template <typename T, unsigned N> struct SmallVectorStorage;
      61             : 
      62             : /// This is the part of SmallVectorTemplateBase which does not depend on whether
      63             : /// the type T is a POD. The extra dummy template argument is used by ArrayRef
      64             : /// to avoid unnecessarily requiring T to be complete.
      65             : template <typename T, typename = void>
      66             : class SmallVectorTemplateCommon : public SmallVectorBase {
      67             : private:
      68             :   template <typename, unsigned> friend struct SmallVectorStorage;
      69             : 
      70             :   // Allocate raw space for N elements of type T.  If T has a ctor or dtor, we
      71             :   // don't want it to be automatically run, so we need to represent the space as
      72             :   // something else.  Use an array of char of sufficient alignment.
      73             :   typedef llvm::AlignedCharArrayUnion<T> U;
      74             :   U FirstEl;
      75             :   // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
      76             : 
      77             : protected:
      78           2 :   SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(&FirstEl, Size) {}
      79             : 
      80             :   void grow_pod(size_t MinSizeInBytes, size_t TSize) {
      81           0 :     SmallVectorBase::grow_pod(&FirstEl, MinSizeInBytes, TSize);
      82           0 :   }
      83             : 
      84             :   /// Return true if this is a smallvector which has not had dynamic
      85             :   /// memory allocated for it.
      86             :   bool isSmall() const {
      87           2 :     return BeginX == static_cast<const void*>(&FirstEl);
      88             :   }
      89             : 
      90             :   /// Put this vector in a state of being small.
      91             :   void resetToSmall() {
      92             :     BeginX = EndX = CapacityX = &FirstEl;
      93             :   }
      94             : 
      95          10 :   void setEnd(T *P) { this->EndX = P; }
      96             : public:
      97             :   typedef size_t size_type;
      98             :   typedef ptrdiff_t difference_type;
      99             :   typedef T value_type;
     100             :   typedef T *iterator;
     101             :   typedef const T *const_iterator;
     102             : 
     103             :   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     104             :   typedef std::reverse_iterator<iterator> reverse_iterator;
     105             : 
     106             :   typedef T &reference;
     107             :   typedef const T &const_reference;
     108             :   typedef T *pointer;
     109             :   typedef const T *const_pointer;
     110             : 
     111             :   // forward iterator creation methods.
     112           2 :   iterator begin() { return (iterator)this->BeginX; }
     113          33 :   const_iterator begin() const { return (const_iterator)this->BeginX; }
     114          25 :   iterator end() { return (iterator)this->EndX; }
     115          22 :   const_iterator end() const { return (const_iterator)this->EndX; }
     116             : protected:
     117             :   iterator capacity_ptr() { return (iterator)this->CapacityX; }
     118             :   const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;}
     119             : public:
     120             : 
     121             :   // reverse iterator creation methods.
     122             :   reverse_iterator rbegin()            { return reverse_iterator(end()); }
     123             :   const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
     124             :   reverse_iterator rend()              { return reverse_iterator(begin()); }
     125             :   const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
     126             : 
     127          22 :   size_type size() const { return end()-begin(); }
     128             :   size_type max_size() const { return size_type(-1) / sizeof(T); }
     129             : 
     130             :   /// Return the total number of elements in the currently allocated buffer.
     131             :   size_t capacity() const { return capacity_ptr() - begin(); }
     132             : 
     133             :   /// Return a pointer to the vector's buffer, even if empty().
     134             :   pointer data() { return pointer(begin()); }
     135             :   /// Return a pointer to the vector's buffer, even if empty().
     136           0 :   const_pointer data() const { return const_pointer(begin()); }
     137             : 
     138             :   reference operator[](size_type idx) {
     139           0 :     assert(idx < size());
     140           0 :     return begin()[idx];
     141             :   }
     142             :   const_reference operator[](size_type idx) const {
     143          22 :     assert(idx < size());
     144          11 :     return begin()[idx];
     145             :   }
     146             : 
     147             :   reference front() {
     148             :     assert(!empty());
     149             :     return begin()[0];
     150             :   }
     151             :   const_reference front() const {
     152             :     assert(!empty());
     153             :     return begin()[0];
     154             :   }
     155             : 
     156             :   reference back() {
     157          16 :     assert(!empty());
     158           8 :     return end()[-1];
     159             :   }
     160             :   const_reference back() const {
     161             :     assert(!empty());
     162             :     return end()[-1];
     163             :   }
     164             : };
     165             : 
     166             : /// SmallVectorTemplateBase<isPodLike = false> - This is where we put method
     167             : /// implementations that are designed to work with non-POD-like T's.
     168             : template <typename T, bool isPodLike>
     169             : class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
     170             : protected:
     171             :   SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
     172             : 
     173             :   static void destroy_range(T *S, T *E) {
     174             :     while (S != E) {
     175             :       --E;
     176             :       E->~T();
     177             :     }
     178             :   }
     179             : 
     180             :   /// Use move-assignment to move the range [I, E) onto the
     181             :   /// objects starting with "Dest".  This is just <memory>'s
     182             :   /// std::move, but not all stdlibs actually provide that.
     183             :   template<typename It1, typename It2>
     184             :   static It2 move(It1 I, It1 E, It2 Dest) {
     185             :     for (; I != E; ++I, ++Dest)
     186             :       *Dest = ::std::move(*I);
     187             :     return Dest;
     188             :   }
     189             : 
     190             :   /// Use move-assignment to move the range
     191             :   /// [I, E) onto the objects ending at "Dest", moving objects
     192             :   /// in reverse order.  This is just <algorithm>'s
     193             :   /// std::move_backward, but not all stdlibs actually provide that.
     194             :   template<typename It1, typename It2>
     195             :   static It2 move_backward(It1 I, It1 E, It2 Dest) {
     196             :     while (I != E)
     197             :       *--Dest = ::std::move(*--E);
     198             :     return Dest;
     199             :   }
     200             : 
     201             :   /// Move the range [I, E) into the uninitialized memory starting with "Dest",
     202             :   /// constructing elements as needed.
     203             :   template<typename It1, typename It2>
     204             :   static void uninitialized_move(It1 I, It1 E, It2 Dest) {
     205             :     for (; I != E; ++I, ++Dest)
     206             :       ::new ((void*) &*Dest) T(::std::move(*I));
     207             :   }
     208             : 
     209             :   /// Copy the range [I, E) onto the uninitialized memory starting with "Dest",
     210             :   /// constructing elements as needed.
     211             :   template<typename It1, typename It2>
     212             :   static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
     213             :     std::uninitialized_copy(I, E, Dest);
     214             :   }
     215             : 
     216             :   /// Grow the allocated memory (without initializing new elements), doubling
     217             :   /// the size of the allocated memory. Guarantees space for at least one more
     218             :   /// element, or MinSize more elements if specified.
     219             :   void grow(size_t MinSize = 0);
     220             : 
     221             : public:
     222             :   void push_back(const T &Elt) {
     223             :     if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
     224             :       this->grow();
     225             :     ::new ((void*) this->end()) T(Elt);
     226             :     this->setEnd(this->end()+1);
     227             :   }
     228             : 
     229             :   void push_back(T &&Elt) {
     230             :     if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
     231             :       this->grow();
     232             :     ::new ((void*) this->end()) T(::std::move(Elt));
     233             :     this->setEnd(this->end()+1);
     234             :   }
     235             : 
     236             :   void pop_back() {
     237             :     this->setEnd(this->end()-1);
     238             :     this->end()->~T();
     239             :   }
     240             : };
     241             : 
     242             : // Define this out-of-line to dissuade the C++ compiler from inlining it.
     243             : template <typename T, bool isPodLike>
     244             : void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
     245             :   size_t CurCapacity = this->capacity();
     246             :   size_t CurSize = this->size();
     247             :   // Always grow, even from zero.
     248             :   size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
     249             :   if (NewCapacity < MinSize)
     250             :     NewCapacity = MinSize;
     251             :   T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
     252             : 
     253             :   // Move the elements over.
     254             :   this->uninitialized_move(this->begin(), this->end(), NewElts);
     255             : 
     256             :   // Destroy the original elements.
     257             :   destroy_range(this->begin(), this->end());
     258             : 
     259             :   // If this wasn't grown from the inline copy, deallocate the old space.
     260             :   if (!this->isSmall())
     261             :     free(this->begin());
     262             : 
     263             :   this->setEnd(NewElts+CurSize);
     264             :   this->BeginX = NewElts;
     265             :   this->CapacityX = this->begin()+NewCapacity;
     266             : }
     267             : 
     268             : 
     269             : /// SmallVectorTemplateBase<isPodLike = true> - This is where we put method
     270             : /// implementations that are designed to work with POD-like T's.
     271             : template <typename T>
     272             : class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
     273             : protected:
     274           2 :   SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
     275             : 
     276             :   // No need to do a destroy loop for POD's.
     277           2 :   static void destroy_range(T *, T *) {}
     278             : 
     279             :   /// Use move-assignment to move the range [I, E) onto the
     280             :   /// objects starting with "Dest".  For PODs, this is just memcpy.
     281             :   template<typename It1, typename It2>
     282             :   static It2 move(It1 I, It1 E, It2 Dest) {
     283             :     return ::std::copy(I, E, Dest);
     284             :   }
     285             : 
     286             :   /// Use move-assignment to move the range [I, E) onto the objects ending at
     287             :   /// "Dest", moving objects in reverse order.
     288             :   template<typename It1, typename It2>
     289             :   static It2 move_backward(It1 I, It1 E, It2 Dest) {
     290             :     return ::std::copy_backward(I, E, Dest);
     291             :   }
     292             : 
     293             :   /// Move the range [I, E) onto the uninitialized memory
     294             :   /// starting with "Dest", constructing elements into it as needed.
     295             :   template<typename It1, typename It2>
     296             :   static void uninitialized_move(It1 I, It1 E, It2 Dest) {
     297             :     // Just do a copy.
     298             :     uninitialized_copy(I, E, Dest);
     299             :   }
     300             : 
     301             :   /// Copy the range [I, E) onto the uninitialized memory
     302             :   /// starting with "Dest", constructing elements into it as needed.
     303             :   template<typename It1, typename It2>
     304             :   static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
     305             :     // Arbitrary iterator types; just use the basic implementation.
     306             :     std::uninitialized_copy(I, E, Dest);
     307             :   }
     308             : 
     309             :   /// Copy the range [I, E) onto the uninitialized memory
     310             :   /// starting with "Dest", constructing elements into it as needed.
     311             :   template <typename T1, typename T2>
     312             :   static void uninitialized_copy(
     313             :       T1 *I, T1 *E, T2 *Dest,
     314             :       typename std::enable_if<std::is_same<typename std::remove_const<T1>::type,
     315             :                                            T2>::value>::type * = nullptr) {
     316             :     // Use memcpy for PODs iterated by pointers (which includes SmallVector
     317             :     // iterators): std::uninitialized_copy optimizes to memmove, but we can
     318             :     // use memcpy here. Note that I and E are iterators and thus might be
     319             :     // invalid for memcpy if they are equal.
     320             :     if (I != E)
     321             :       memcpy(Dest, I, (E - I) * sizeof(T));
     322             :   }
     323             : 
     324             :   /// Double the size of the allocated memory, guaranteeing space for at
     325             :   /// least one more element or MinSize if specified.
     326             :   void grow(size_t MinSize = 0) {
     327           0 :     this->grow_pod(MinSize*sizeof(T), sizeof(T));
     328           0 :   }
     329             : public:
     330             :   void push_back(const T &Elt) {
     331           5 :     if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
     332           0 :       this->grow();
     333           5 :     memcpy(this->end(), &Elt, sizeof(T));
     334           5 :     this->setEnd(this->end()+1);
     335           5 :   }
     336             : 
     337             :   void pop_back() {
     338           5 :     this->setEnd(this->end()-1);
     339           5 :   }
     340             : };
     341             : 
     342             : 
     343             : /// This class consists of common code factored out of the SmallVector class to
     344             : /// reduce code duplication based on the SmallVector 'N' template parameter.
     345             : template <typename T>
     346             : class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
     347             :   typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
     348             : 
     349             :   SmallVectorImpl(const SmallVectorImpl&) = delete;
     350             : public:
     351             :   typedef typename SuperClass::iterator iterator;
     352             :   typedef typename SuperClass::size_type size_type;
     353             : 
     354             : protected:
     355             :   // Default ctor - Initialize to empty.
     356             :   explicit SmallVectorImpl(unsigned N)
     357           2 :     : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
     358           2 :   }
     359             : 
     360             : public:
     361             :   ~SmallVectorImpl() {
     362             :     // Destroy the constructed elements in the vector.
     363           6 :     this->destroy_range(this->begin(), this->end());
     364             : 
     365             :     // If this wasn't grown from the inline copy, deallocate the old space.
     366           4 :     if (!this->isSmall())
     367           0 :       free(this->begin());
     368           2 :   }
     369             : 
     370             : 
     371             :   void clear() {
     372             :     this->destroy_range(this->begin(), this->end());
     373             :     this->EndX = this->BeginX;
     374             :   }
     375             : 
     376             :   void resize(size_type N) {
     377             :     if (N < this->size()) {
     378             :       this->destroy_range(this->begin()+N, this->end());
     379             :       this->setEnd(this->begin()+N);
     380             :     } else if (N > this->size()) {
     381             :       if (this->capacity() < N)
     382             :         this->grow(N);
     383             :       for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
     384             :         new (&*I) T();
     385             :       this->setEnd(this->begin()+N);
     386             :     }
     387             :   }
     388             : 
     389             :   void resize(size_type N, const T &NV) {
     390             :     if (N < this->size()) {
     391             :       this->destroy_range(this->begin()+N, this->end());
     392             :       this->setEnd(this->begin()+N);
     393             :     } else if (N > this->size()) {
     394             :       if (this->capacity() < N)
     395             :         this->grow(N);
     396             :       std::uninitialized_fill(this->end(), this->begin()+N, NV);
     397             :       this->setEnd(this->begin()+N);
     398             :     }
     399             :   }
     400             : 
     401             :   void reserve(size_type N) {
     402             :     if (this->capacity() < N)
     403             :       this->grow(N);
     404             :   }
     405             : 
     406             :   T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() {
     407             :     T Result = ::std::move(this->back());
     408             :     this->pop_back();
     409             :     return Result;
     410             :   }
     411             : 
     412             :   void swap(SmallVectorImpl &RHS);
     413             : 
     414             :   /// Add the specified range to the end of the SmallVector.
     415             :   template<typename in_iter>
     416             :   void append(in_iter in_start, in_iter in_end) {
     417             :     size_type NumInputs = std::distance(in_start, in_end);
     418             :     // Grow allocated space if needed.
     419             :     if (NumInputs > size_type(this->capacity_ptr()-this->end()))
     420             :       this->grow(this->size()+NumInputs);
     421             : 
     422             :     // Copy the new elements over.
     423             :     this->uninitialized_copy(in_start, in_end, this->end());
     424             :     this->setEnd(this->end() + NumInputs);
     425             :   }
     426             : 
     427             :   /// Add the specified range to the end of the SmallVector.
     428             :   void append(size_type NumInputs, const T &Elt) {
     429             :     // Grow allocated space if needed.
     430             :     if (NumInputs > size_type(this->capacity_ptr()-this->end()))
     431             :       this->grow(this->size()+NumInputs);
     432             : 
     433             :     // Copy the new elements over.
     434             :     std::uninitialized_fill_n(this->end(), NumInputs, Elt);
     435             :     this->setEnd(this->end() + NumInputs);
     436             :   }
     437             : 
     438             :   void append(std::initializer_list<T> IL) {
     439             :     append(IL.begin(), IL.end());
     440             :   }
     441             : 
     442             :   void assign(size_type NumElts, const T &Elt) {
     443             :     clear();
     444             :     if (this->capacity() < NumElts)
     445             :       this->grow(NumElts);
     446             :     this->setEnd(this->begin()+NumElts);
     447             :     std::uninitialized_fill(this->begin(), this->end(), Elt);
     448             :   }
     449             : 
     450             :   void assign(std::initializer_list<T> IL) {
     451             :     clear();
     452             :     append(IL);
     453             :   }
     454             : 
     455             :   iterator erase(iterator I) {
     456             :     assert(I >= this->begin() && "Iterator to erase is out of bounds.");
     457             :     assert(I < this->end() && "Erasing at past-the-end iterator.");
     458             : 
     459             :     iterator N = I;
     460             :     // Shift all elts down one.
     461             :     this->move(I+1, this->end(), I);
     462             :     // Drop the last elt.
     463             :     this->pop_back();
     464             :     return(N);
     465             :   }
     466             : 
     467             :   iterator erase(iterator S, iterator E) {
     468             :     assert(S >= this->begin() && "Range to erase is out of bounds.");
     469             :     assert(S <= E && "Trying to erase invalid range.");
     470             :     assert(E <= this->end() && "Trying to erase past the end.");
     471             : 
     472             :     iterator N = S;
     473             :     // Shift all elts down.
     474             :     iterator I = this->move(E, this->end(), S);
     475             :     // Drop the last elts.
     476             :     this->destroy_range(I, this->end());
     477             :     this->setEnd(I);
     478             :     return(N);
     479             :   }
     480             : 
     481             :   iterator insert(iterator I, T &&Elt) {
     482             :     if (I == this->end()) {  // Important special case for empty vector.
     483             :       this->push_back(::std::move(Elt));
     484             :       return this->end()-1;
     485             :     }
     486             : 
     487             :     assert(I >= this->begin() && "Insertion iterator is out of bounds.");
     488             :     assert(I <= this->end() && "Inserting past the end of the vector.");
     489             : 
     490             :     if (this->EndX >= this->CapacityX) {
     491             :       size_t EltNo = I-this->begin();
     492             :       this->grow();
     493             :       I = this->begin()+EltNo;
     494             :     }
     495             : 
     496             :     ::new ((void*) this->end()) T(::std::move(this->back()));
     497             :     // Push everything else over.
     498             :     this->move_backward(I, this->end()-1, this->end());
     499             :     this->setEnd(this->end()+1);
     500             : 
     501             :     // If we just moved the element we're inserting, be sure to update
     502             :     // the reference.
     503             :     T *EltPtr = &Elt;
     504             :     if (I <= EltPtr && EltPtr < this->EndX)
     505             :       ++EltPtr;
     506             : 
     507             :     *I = ::std::move(*EltPtr);
     508             :     return I;
     509             :   }
     510             : 
     511             :   iterator insert(iterator I, const T &Elt) {
     512             :     if (I == this->end()) {  // Important special case for empty vector.
     513             :       this->push_back(Elt);
     514             :       return this->end()-1;
     515             :     }
     516             : 
     517             :     assert(I >= this->begin() && "Insertion iterator is out of bounds.");
     518             :     assert(I <= this->end() && "Inserting past the end of the vector.");
     519             : 
     520             :     if (this->EndX >= this->CapacityX) {
     521             :       size_t EltNo = I-this->begin();
     522             :       this->grow();
     523             :       I = this->begin()+EltNo;
     524             :     }
     525             :     ::new ((void*) this->end()) T(std::move(this->back()));
     526             :     // Push everything else over.
     527             :     this->move_backward(I, this->end()-1, this->end());
     528             :     this->setEnd(this->end()+1);
     529             : 
     530             :     // If we just moved the element we're inserting, be sure to update
     531             :     // the reference.
     532             :     const T *EltPtr = &Elt;
     533             :     if (I <= EltPtr && EltPtr < this->EndX)
     534             :       ++EltPtr;
     535             : 
     536             :     *I = *EltPtr;
     537             :     return I;
     538             :   }
     539             : 
     540             :   iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
     541             :     // Convert iterator to elt# to avoid invalidating iterator when we reserve()
     542             :     size_t InsertElt = I - this->begin();
     543             : 
     544             :     if (I == this->end()) {  // Important special case for empty vector.
     545             :       append(NumToInsert, Elt);
     546             :       return this->begin()+InsertElt;
     547             :     }
     548             : 
     549             :     assert(I >= this->begin() && "Insertion iterator is out of bounds.");
     550             :     assert(I <= this->end() && "Inserting past the end of the vector.");
     551             : 
     552             :     // Ensure there is enough space.
     553             :     reserve(this->size() + NumToInsert);
     554             : 
     555             :     // Uninvalidate the iterator.
     556             :     I = this->begin()+InsertElt;
     557             : 
     558             :     // If there are more elements between the insertion point and the end of the
     559             :     // range than there are being inserted, we can use a simple approach to
     560             :     // insertion.  Since we already reserved space, we know that this won't
     561             :     // reallocate the vector.
     562             :     if (size_t(this->end()-I) >= NumToInsert) {
     563             :       T *OldEnd = this->end();
     564             :       append(std::move_iterator<iterator>(this->end() - NumToInsert),
     565             :              std::move_iterator<iterator>(this->end()));
     566             : 
     567             :       // Copy the existing elements that get replaced.
     568             :       this->move_backward(I, OldEnd-NumToInsert, OldEnd);
     569             : 
     570             :       std::fill_n(I, NumToInsert, Elt);
     571             :       return I;
     572             :     }
     573             : 
     574             :     // Otherwise, we're inserting more elements than exist already, and we're
     575             :     // not inserting at the end.
     576             : 
     577             :     // Move over the elements that we're about to overwrite.
     578             :     T *OldEnd = this->end();
     579             :     this->setEnd(this->end() + NumToInsert);
     580             :     size_t NumOverwritten = OldEnd-I;
     581             :     this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
     582             : 
     583             :     // Replace the overwritten part.
     584             :     std::fill_n(I, NumOverwritten, Elt);
     585             : 
     586             :     // Insert the non-overwritten middle part.
     587             :     std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
     588             :     return I;
     589             :   }
     590             : 
     591             :   template<typename ItTy>
     592             :   iterator insert(iterator I, ItTy From, ItTy To) {
     593             :     // Convert iterator to elt# to avoid invalidating iterator when we reserve()
     594             :     size_t InsertElt = I - this->begin();
     595             : 
     596             :     if (I == this->end()) {  // Important special case for empty vector.
     597             :       append(From, To);
     598             :       return this->begin()+InsertElt;
     599             :     }
     600             : 
     601             :     assert(I >= this->begin() && "Insertion iterator is out of bounds.");
     602             :     assert(I <= this->end() && "Inserting past the end of the vector.");
     603             : 
     604             :     size_t NumToInsert = std::distance(From, To);
     605             : 
     606             :     // Ensure there is enough space.
     607             :     reserve(this->size() + NumToInsert);
     608             : 
     609             :     // Uninvalidate the iterator.
     610             :     I = this->begin()+InsertElt;
     611             : 
     612             :     // If there are more elements between the insertion point and the end of the
     613             :     // range than there are being inserted, we can use a simple approach to
     614             :     // insertion.  Since we already reserved space, we know that this won't
     615             :     // reallocate the vector.
     616             :     if (size_t(this->end()-I) >= NumToInsert) {
     617             :       T *OldEnd = this->end();
     618             :       append(std::move_iterator<iterator>(this->end() - NumToInsert),
     619             :              std::move_iterator<iterator>(this->end()));
     620             : 
     621             :       // Copy the existing elements that get replaced.
     622             :       this->move_backward(I, OldEnd-NumToInsert, OldEnd);
     623             : 
     624             :       std::copy(From, To, I);
     625             :       return I;
     626             :     }
     627             : 
     628             :     // Otherwise, we're inserting more elements than exist already, and we're
     629             :     // not inserting at the end.
     630             : 
     631             :     // Move over the elements that we're about to overwrite.
     632             :     T *OldEnd = this->end();
     633             :     this->setEnd(this->end() + NumToInsert);
     634             :     size_t NumOverwritten = OldEnd-I;
     635             :     this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
     636             : 
     637             :     // Replace the overwritten part.
     638             :     for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
     639             :       *J = *From;
     640             :       ++J; ++From;
     641             :     }
     642             : 
     643             :     // Insert the non-overwritten middle part.
     644             :     this->uninitialized_copy(From, To, OldEnd);
     645             :     return I;
     646             :   }
     647             : 
     648             :   void insert(iterator I, std::initializer_list<T> IL) {
     649             :     insert(I, IL.begin(), IL.end());
     650             :   }
     651             : 
     652             :   template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) {
     653             :     if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
     654             :       this->grow();
     655             :     ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
     656             :     this->setEnd(this->end() + 1);
     657             :   }
     658             : 
     659             :   SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
     660             : 
     661             :   SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
     662             : 
     663             :   bool operator==(const SmallVectorImpl &RHS) const {
     664             :     if (this->size() != RHS.size()) return false;
     665             :     return std::equal(this->begin(), this->end(), RHS.begin());
     666             :   }
     667             :   bool operator!=(const SmallVectorImpl &RHS) const {
     668             :     return !(*this == RHS);
     669             :   }
     670             : 
     671             :   bool operator<(const SmallVectorImpl &RHS) const {
     672             :     return std::lexicographical_compare(this->begin(), this->end(),
     673             :                                         RHS.begin(), RHS.end());
     674             :   }
     675             : 
     676             :   /// Set the array size to \p N, which the current array must have enough
     677             :   /// capacity for.
     678             :   ///
     679             :   /// This does not construct or destroy any elements in the vector.
     680             :   ///
     681             :   /// Clients can use this in conjunction with capacity() to write past the end
     682             :   /// of the buffer when they know that more elements are available, and only
     683             :   /// update the size later. This avoids the cost of value initializing elements
     684             :   /// which will only be overwritten.
     685             :   void set_size(size_type N) {
     686             :     assert(N <= this->capacity());
     687             :     this->setEnd(this->begin() + N);
     688             :   }
     689             : };
     690             : 
     691             : 
     692             : template <typename T>
     693             : void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
     694             :   if (this == &RHS) return;
     695             : 
     696             :   // We can only avoid copying elements if neither vector is small.
     697             :   if (!this->isSmall() && !RHS.isSmall()) {
     698             :     std::swap(this->BeginX, RHS.BeginX);
     699             :     std::swap(this->EndX, RHS.EndX);
     700             :     std::swap(this->CapacityX, RHS.CapacityX);
     701             :     return;
     702             :   }
     703             :   if (RHS.size() > this->capacity())
     704             :     this->grow(RHS.size());
     705             :   if (this->size() > RHS.capacity())
     706             :     RHS.grow(this->size());
     707             : 
     708             :   // Swap the shared elements.
     709             :   size_t NumShared = this->size();
     710             :   if (NumShared > RHS.size()) NumShared = RHS.size();
     711             :   for (size_type i = 0; i != NumShared; ++i)
     712             :     std::swap((*this)[i], RHS[i]);
     713             : 
     714             :   // Copy over the extra elts.
     715             :   if (this->size() > RHS.size()) {
     716             :     size_t EltDiff = this->size() - RHS.size();
     717             :     this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
     718             :     RHS.setEnd(RHS.end()+EltDiff);
     719             :     this->destroy_range(this->begin()+NumShared, this->end());
     720             :     this->setEnd(this->begin()+NumShared);
     721             :   } else if (RHS.size() > this->size()) {
     722             :     size_t EltDiff = RHS.size() - this->size();
     723             :     this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
     724             :     this->setEnd(this->end() + EltDiff);
     725             :     this->destroy_range(RHS.begin()+NumShared, RHS.end());
     726             :     RHS.setEnd(RHS.begin()+NumShared);
     727             :   }
     728             : }
     729             : 
     730             : template <typename T>
     731             : SmallVectorImpl<T> &SmallVectorImpl<T>::
     732             :   operator=(const SmallVectorImpl<T> &RHS) {
     733             :   // Avoid self-assignment.
     734             :   if (this == &RHS) return *this;
     735             : 
     736             :   // If we already have sufficient space, assign the common elements, then
     737             :   // destroy any excess.
     738             :   size_t RHSSize = RHS.size();
     739             :   size_t CurSize = this->size();
     740             :   if (CurSize >= RHSSize) {
     741             :     // Assign common elements.
     742             :     iterator NewEnd;
     743             :     if (RHSSize)
     744             :       NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
     745             :     else
     746             :       NewEnd = this->begin();
     747             : 
     748             :     // Destroy excess elements.
     749             :     this->destroy_range(NewEnd, this->end());
     750             : 
     751             :     // Trim.
     752             :     this->setEnd(NewEnd);
     753             :     return *this;
     754             :   }
     755             : 
     756             :   // If we have to grow to have enough elements, destroy the current elements.
     757             :   // This allows us to avoid copying them during the grow.
     758             :   // FIXME: don't do this if they're efficiently moveable.
     759             :   if (this->capacity() < RHSSize) {
     760             :     // Destroy current elements.
     761             :     this->destroy_range(this->begin(), this->end());
     762             :     this->setEnd(this->begin());
     763             :     CurSize = 0;
     764             :     this->grow(RHSSize);
     765             :   } else if (CurSize) {
     766             :     // Otherwise, use assignment for the already-constructed elements.
     767             :     std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
     768             :   }
     769             : 
     770             :   // Copy construct the new elements in place.
     771             :   this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
     772             :                            this->begin()+CurSize);
     773             : 
     774             :   // Set end.
     775             :   this->setEnd(this->begin()+RHSSize);
     776             :   return *this;
     777             : }
     778             : 
     779             : template <typename T>
     780             : SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
     781             :   // Avoid self-assignment.
     782             :   if (this == &RHS) return *this;
     783             : 
     784             :   // If the RHS isn't small, clear this vector and then steal its buffer.
     785             :   if (!RHS.isSmall()) {
     786             :     this->destroy_range(this->begin(), this->end());
     787             :     if (!this->isSmall()) free(this->begin());
     788             :     this->BeginX = RHS.BeginX;
     789             :     this->EndX = RHS.EndX;
     790             :     this->CapacityX = RHS.CapacityX;
     791             :     RHS.resetToSmall();
     792             :     return *this;
     793             :   }
     794             : 
     795             :   // If we already have sufficient space, assign the common elements, then
     796             :   // destroy any excess.
     797             :   size_t RHSSize = RHS.size();
     798             :   size_t CurSize = this->size();
     799             :   if (CurSize >= RHSSize) {
     800             :     // Assign common elements.
     801             :     iterator NewEnd = this->begin();
     802             :     if (RHSSize)
     803             :       NewEnd = this->move(RHS.begin(), RHS.end(), NewEnd);
     804             : 
     805             :     // Destroy excess elements and trim the bounds.
     806             :     this->destroy_range(NewEnd, this->end());
     807             :     this->setEnd(NewEnd);
     808             : 
     809             :     // Clear the RHS.
     810             :     RHS.clear();
     811             : 
     812             :     return *this;
     813             :   }
     814             : 
     815             :   // If we have to grow to have enough elements, destroy the current elements.
     816             :   // This allows us to avoid copying them during the grow.
     817             :   // FIXME: this may not actually make any sense if we can efficiently move
     818             :   // elements.
     819             :   if (this->capacity() < RHSSize) {
     820             :     // Destroy current elements.
     821             :     this->destroy_range(this->begin(), this->end());
     822             :     this->setEnd(this->begin());
     823             :     CurSize = 0;
     824             :     this->grow(RHSSize);
     825             :   } else if (CurSize) {
     826             :     // Otherwise, use assignment for the already-constructed elements.
     827             :     this->move(RHS.begin(), RHS.begin()+CurSize, this->begin());
     828             :   }
     829             : 
     830             :   // Move-construct the new elements in place.
     831             :   this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
     832             :                            this->begin()+CurSize);
     833             : 
     834             :   // Set end.
     835             :   this->setEnd(this->begin()+RHSSize);
     836             : 
     837             :   RHS.clear();
     838             :   return *this;
     839             : }
     840             : 
     841             : /// Storage for the SmallVector elements which aren't contained in
     842             : /// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
     843             : /// element is in the base class. This is specialized for the N=1 and N=0 cases
     844             : /// to avoid allocating unnecessary storage.
     845             : template <typename T, unsigned N>
     846             : struct SmallVectorStorage {
     847             :   typename SmallVectorTemplateCommon<T>::U InlineElts[N - 1];
     848             : };
     849             : template <typename T> struct SmallVectorStorage<T, 1> {};
     850             : template <typename T> struct SmallVectorStorage<T, 0> {};
     851             : 
     852             : /// This is a 'vector' (really, a variable-sized array), optimized
     853             : /// for the case when the array is small.  It contains some number of elements
     854             : /// in-place, which allows it to avoid heap allocation when the actual number of
     855             : /// elements is below that threshold.  This allows normal "small" cases to be
     856             : /// fast without losing generality for large inputs.
     857             : ///
     858             : /// Note that this does not attempt to be exception safe.
     859             : ///
     860             : template <typename T, unsigned N>
     861             : class SmallVector : public SmallVectorImpl<T> {
     862             :   /// Inline space for elements which aren't stored in the base class.
     863             :   SmallVectorStorage<T, N> Storage;
     864             : public:
     865           2 :   SmallVector() : SmallVectorImpl<T>(N) {
     866           2 :   }
     867             : 
     868             :   explicit SmallVector(size_t Size, const T &Value = T())
     869             :     : SmallVectorImpl<T>(N) {
     870             :     this->assign(Size, Value);
     871             :   }
     872             : 
     873             :   template<typename ItTy>
     874             :   SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
     875             :     this->append(S, E);
     876             :   }
     877             : 
     878             :   template <typename RangeTy>
     879             :   explicit SmallVector(const llvm::iterator_range<RangeTy> R)
     880             :       : SmallVectorImpl<T>(N) {
     881             :     this->append(R.begin(), R.end());
     882             :   }
     883             : 
     884             :   SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
     885             :     this->assign(IL);
     886             :   }
     887             : 
     888             :   SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
     889             :     if (!RHS.empty())
     890             :       SmallVectorImpl<T>::operator=(RHS);
     891             :   }
     892             : 
     893             :   const SmallVector &operator=(const SmallVector &RHS) {
     894             :     SmallVectorImpl<T>::operator=(RHS);
     895             :     return *this;
     896             :   }
     897             : 
     898             :   SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
     899             :     if (!RHS.empty())
     900             :       SmallVectorImpl<T>::operator=(::std::move(RHS));
     901             :   }
     902             : 
     903             :   const SmallVector &operator=(SmallVector &&RHS) {
     904             :     SmallVectorImpl<T>::operator=(::std::move(RHS));
     905             :     return *this;
     906             :   }
     907             : 
     908             :   SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) {
     909             :     if (!RHS.empty())
     910             :       SmallVectorImpl<T>::operator=(::std::move(RHS));
     911             :   }
     912             : 
     913             :   const SmallVector &operator=(SmallVectorImpl<T> &&RHS) {
     914             :     SmallVectorImpl<T>::operator=(::std::move(RHS));
     915             :     return *this;
     916             :   }
     917             : 
     918             :   const SmallVector &operator=(std::initializer_list<T> IL) {
     919             :     this->assign(IL);
     920             :     return *this;
     921             :   }
     922             : };
     923             : 
     924             : template<typename T, unsigned N>
     925             : static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
     926             :   return X.capacity_in_bytes();
     927             : }
     928             : 
     929             : } // End llvm namespace
     930             : 
     931             : namespace std {
     932             :   /// Implement std::swap in terms of SmallVector swap.
     933             :   template<typename T>
     934             :   inline void
     935             :   swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
     936             :     LHS.swap(RHS);
     937             :   }
     938             : 
     939             :   /// Implement std::swap in terms of SmallVector swap.
     940             :   template<typename T, unsigned N>
     941             :   inline void
     942             :   swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
     943             :     LHS.swap(RHS);
     944             :   }
     945             : }
     946             : 
     947             : #endif

Generated by: LCOV version 1.11