blob: 3d17e70bad6d2669e349065d670eaa64dd4ea4a4 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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 "llvm/Support/ErrorHandling.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
35namespace llvm {
36
37/// This is all the non-templated stuff common to all SmallVectors.
38class SmallVectorBase {
39protected:
40 void *BeginX, *EndX, *CapacityX;
41
42protected:
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
50public:
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.
67template <typename T, typename = void>
68class SmallVectorTemplateCommon : public SmallVectorBase {
69private:
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.
75 using U = AlignedCharArrayUnion<T>;
76 U FirstEl;
77 // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
78
79protected:
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
99public:
100 using size_type = size_t;
101 using difference_type = ptrdiff_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.
115 LLVM_ATTRIBUTE_ALWAYS_INLINE
116 iterator begin() { return (iterator)this->BeginX; }
117 LLVM_ATTRIBUTE_ALWAYS_INLINE
118 const_iterator begin() const { return (const_iterator)this->BeginX; }
119 LLVM_ATTRIBUTE_ALWAYS_INLINE
120 iterator end() { return (iterator)this->EndX; }
121 LLVM_ATTRIBUTE_ALWAYS_INLINE
122 const_iterator end() const { return (const_iterator)this->EndX; }
123
124protected:
125 iterator capacity_ptr() { return (iterator)this->CapacityX; }
126 const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;}
127
128public:
129 // reverse iterator creation methods.
130 reverse_iterator rbegin() { return reverse_iterator(end()); }
131 const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
132 reverse_iterator rend() { return reverse_iterator(begin()); }
133 const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
134
135 LLVM_ATTRIBUTE_ALWAYS_INLINE
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
147 LLVM_ATTRIBUTE_ALWAYS_INLINE
148 reference operator[](size_type idx) {
149 assert(idx < size());
150 return begin()[idx];
151 }
152 LLVM_ATTRIBUTE_ALWAYS_INLINE
153 const_reference operator[](size_type idx) const {
154 assert(idx < size());
155 return begin()[idx];
156 }
157
158 reference front() {
159 assert(!empty());
160 return begin()[0];
161 }
162 const_reference front() const {
163 assert(!empty());
164 return begin()[0];
165 }
166
167 reference back() {
168 assert(!empty());
169 return end()[-1];
170 }
171 const_reference back() const {
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.
179template <typename T, bool isPodLike>
180class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
181protected:
182 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
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
211public:
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.
233template <typename T, bool isPodLike>
234void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
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.
263template <typename T>
264class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
265protected:
266 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
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
308public:
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.
323template <typename T>
324class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
325 using SuperClass = SmallVectorTemplateBase<T, isPodLike<T>::value>;
326
327public:
328 using iterator = typename SuperClass::iterator;
329 using const_iterator = typename SuperClass::const_iterator;
330 using size_type = typename SuperClass::size_type;
331
332protected:
333 // Default ctor - Initialize to empty.
334 explicit SmallVectorImpl(unsigned N)
335 : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
336 }
337
338public:
339 SmallVectorImpl(const SmallVectorImpl &) = delete;
340
341 ~SmallVectorImpl() {
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
353 void resize(size_type N) {
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
378 void reserve(size_type N) {
379 if (this->capacity() < N)
380 this->grow(N);
381 }
382
383 LLVM_NODISCARD T pop_back_val() {
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
447 iterator erase(const_iterator CI) {
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
462 iterator erase(const_iterator CS, const_iterator CE) {
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
480 iterator insert(iterator I, T &&Elt) {
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>
594 iterator insert(iterator I, ItTy From, ItTy To) {
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.
687 void set_size(size_type N) {
688 assert(N <= this->capacity());
689 this->setEnd(this->begin() + N);
690 }
691};
692
693template <typename T>
694void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
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
731template <typename T>
732SmallVectorImpl<T> &SmallVectorImpl<T>::
733 operator=(const SmallVectorImpl<T> &RHS) {
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
780template <typename T>
781SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
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.
846template <typename T, unsigned N>
847struct SmallVectorStorage {
848 typename SmallVectorTemplateCommon<T>::U InlineElts[N - 1];
849};
850template <typename T> struct SmallVectorStorage<T, 1> {};
851template <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///
861template <typename T, unsigned N>
862class SmallVector : public SmallVectorImpl<T> {
863 /// Inline space for elements which aren't stored in the base class.
864 SmallVectorStorage<T, N> Storage;
865
866public:
867 SmallVector() : SmallVectorImpl<T>(N) {}
868
869 ~SmallVector() {
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>
883 SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
884 this->append(S, E);
885 }
886
887 template <typename RangeTy>
888 explicit SmallVector(const iterator_range<RangeTy> &R)
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
897 SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
898 if (!RHS.empty())
899 SmallVectorImpl<T>::operator=(RHS);
900 }
901
902 const SmallVector &operator=(const SmallVector &RHS) {
903 SmallVectorImpl<T>::operator=(RHS);
904 return *this;
905 }
906
907 SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
908 if (!RHS.empty())
909 SmallVectorImpl<T>::operator=(::std::move(RHS));
910 }
911
912 SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) {
913 if (!RHS.empty())
914 SmallVectorImpl<T>::operator=(::std::move(RHS));
915 }
916
917 const SmallVector &operator=(SmallVector &&RHS) {
918 SmallVectorImpl<T>::operator=(::std::move(RHS));
919 return *this;
920 }
921
922 const SmallVector &operator=(SmallVectorImpl<T> &&RHS) {
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
933template <typename T, unsigned N>
934inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
935 return X.capacity_in_bytes();
936}
937
938} // end namespace llvm
939
940namespace std {
941
942 /// Implement std::swap in terms of SmallVector swap.
943 template<typename T>
944 inline void
945 swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
946 LHS.swap(RHS);
947 }
948
949 /// Implement std::swap in terms of SmallVector swap.
950 template<typename T, unsigned N>
951 inline void
952 swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
953 LHS.swap(RHS);
954 }
955
956} // end namespace std
957
958#endif // LLVM_ADT_SMALLVECTOR_H