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