Thanks to visit codestin.com
Credit goes to llvm.org

LLVM 22.0.0git
SmallVector.h
Go to the documentation of this file.
1//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines the SmallVector class.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_SMALLVECTOR_H
15#define LLVM_ADT_SMALLVECTOR_H
16
19#include <algorithm>
20#include <cassert>
21#include <cstddef>
22#include <cstdint>
23#include <cstdlib>
24#include <cstring>
25#include <functional>
26#include <initializer_list>
27#include <iterator>
28#include <limits>
29#include <memory>
30#include <new>
31#include <type_traits>
32#include <utility>
33
34namespace llvm {
35
36template <typename T> class ArrayRef;
37
38template <typename IteratorT> class iterator_range;
39
40template <class Iterator>
41using EnableIfConvertibleToInputIterator = std::enable_if_t<std::is_convertible<
42 typename std::iterator_traits<Iterator>::iterator_category,
43 std::input_iterator_tag>::value>;
44
45/// This is all the stuff common to all SmallVectors.
46///
47/// The template parameter specifies the type which should be used to hold the
48/// Size and Capacity of the SmallVector, so it can be adjusted.
49/// Using 32 bit size is desirable to shrink the size of the SmallVector.
50/// Using 64 bit size is desirable for cases like SmallVector<char>, where a
51/// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
52/// buffering bitcode output - which can exceed 4GB.
53template <class Size_T> class SmallVectorBase {
54protected:
55 void *BeginX;
56 Size_T Size = 0, Capacity;
57
58 /// The maximum value of the Size_T used.
59 static constexpr size_t SizeTypeMax() {
60 return std::numeric_limits<Size_T>::max();
61 }
62
63 SmallVectorBase() = delete;
64 SmallVectorBase(void *FirstEl, size_t TotalCapacity)
65 : BeginX(FirstEl), Capacity(static_cast<Size_T>(TotalCapacity)) {}
66
67 /// This is a helper for \a grow() that's out of line to reduce code
68 /// duplication. This function will report a fatal error if it can't grow at
69 /// least to \p MinSize.
70 LLVM_ABI void *mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize,
71 size_t &NewCapacity);
72
73 /// This is an implementation of the grow() method which only works
74 /// on POD-like data types and is out of line to reduce code duplication.
75 /// This function will report a fatal error if it cannot increase capacity.
76 LLVM_ABI void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
77
78public:
79 size_t size() const { return Size; }
80 size_t capacity() const { return Capacity; }
81
82 [[nodiscard]] bool empty() const { return !Size; }
83
84protected:
85 /// Set the array size to \p N, which the current array must have enough
86 /// capacity for.
87 ///
88 /// This does not construct or destroy any elements in the vector.
89 void set_size(size_t N) {
90 assert(N <= capacity()); // implies no overflow in assignment
91 Size = static_cast<Size_T>(N);
92 }
93
94 /// Set the array data pointer to \p Begin and capacity to \p N.
95 ///
96 /// This does not construct or destroy any elements in the vector.
97 // This does not clean up any existing allocation.
98 void set_allocation_range(void *Begin, size_t N) {
99 assert(N <= SizeTypeMax());
100 BeginX = Begin;
101 Capacity = static_cast<Size_T>(N);
102 }
103};
104
105template <class T>
107 std::conditional_t<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t,
108 uint32_t>;
109
110/// Figure out the offset of the first element.
111template <class T, typename = void> struct SmallVectorAlignmentAndSize {
114 alignas(T) char FirstEl[sizeof(T)];
115};
116
117/// This is the part of SmallVectorTemplateBase which does not depend on whether
118/// the type T is a POD. The extra dummy template argument is used by ArrayRef
119/// to avoid unnecessarily requiring T to be complete.
120template <typename T, typename = void>
122 : public SmallVectorBase<SmallVectorSizeType<T>> {
124
125protected:
126 /// Find the address of the first element. For this pointer math to be valid
127 /// with small-size of 0 for T with lots of alignment, it's important that
128 /// SmallVectorStorage is properly-aligned even for small-size of 0.
129 void *getFirstEl() const {
130 return const_cast<void *>(reinterpret_cast<const void *>(
131 reinterpret_cast<const char *>(this) +
133 }
134 // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
135
137
138 void grow_pod(size_t MinSize, size_t TSize) {
139 Base::grow_pod(getFirstEl(), MinSize, TSize);
140 }
141
142 /// Return true if this is a smallvector which has not had dynamic
143 /// memory allocated for it.
144 bool isSmall() const { return this->BeginX == getFirstEl(); }
145
146 /// Put this vector in a state of being small.
148 this->BeginX = getFirstEl();
149 this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
150 }
151
152 /// Return true if V is an internal reference to the given range.
153 bool isReferenceToRange(const void *V, const void *First, const void *Last) const {
154 // Use std::less to avoid UB.
155 std::less<> LessThan;
156 return !LessThan(V, First) && LessThan(V, Last);
157 }
158
159 /// Return true if V is an internal reference to this vector.
160 bool isReferenceToStorage(const void *V) const {
161 return isReferenceToRange(V, this->begin(), this->end());
162 }
163
164 /// Return true if First and Last form a valid (possibly empty) range in this
165 /// vector's storage.
166 bool isRangeInStorage(const void *First, const void *Last) const {
167 // Use std::less to avoid UB.
168 std::less<> LessThan;
169 return !LessThan(First, this->begin()) && !LessThan(Last, First) &&
170 !LessThan(this->end(), Last);
171 }
172
173 /// Return true unless Elt will be invalidated by resizing the vector to
174 /// NewSize.
175 bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
176 // Past the end.
178 return true;
179
180 // Return false if Elt will be destroyed by shrinking.
181 if (NewSize <= this->size())
182 return Elt < this->begin() + NewSize;
183
184 // Return false if we need to grow.
185 return NewSize <= this->capacity();
186 }
187
188 /// Check whether Elt will be invalidated by resizing the vector to NewSize.
189 void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
190 assert(isSafeToReferenceAfterResize(Elt, NewSize) &&
191 "Attempting to reference an element of the vector in an operation "
192 "that invalidates it");
193 }
194
195 /// Check whether Elt will be invalidated by increasing the size of the
196 /// vector by N.
197 void assertSafeToAdd(const void *Elt, size_t N = 1) {
198 this->assertSafeToReferenceAfterResize(Elt, this->size() + N);
199 }
200
201 /// Check whether any part of the range will be invalidated by clearing.
202 template <class ItTy>
204 if constexpr (std::is_pointer_v<ItTy> &&
205 std::is_same_v<
206 std::remove_const_t<std::remove_pointer_t<ItTy>>,
207 std::remove_const_t<T>>) {
208 if (From == To)
209 return;
211 this->assertSafeToReferenceAfterResize(To - 1, 0);
212 }
213 }
214
215 /// Check whether any part of the range will be invalidated by growing.
216 template <class ItTy> void assertSafeToAddRange(ItTy From, ItTy To) {
217 if constexpr (std::is_pointer_v<ItTy> &&
218 std::is_same_v<std::remove_cv_t<std::remove_pointer_t<ItTy>>,
219 T>) {
220 if (From == To)
221 return;
222 this->assertSafeToAdd(From, To - From);
223 this->assertSafeToAdd(To - 1, To - From);
224 }
225 (void)From;
226 (void)To;
227 }
228
229 /// Reserve enough space to add one element, and return the updated element
230 /// pointer in case it was a reference to the storage.
231 template <class U>
232 static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt,
233 size_t N) {
234 size_t NewSize = This->size() + N;
235 if (LLVM_LIKELY(NewSize <= This->capacity()))
236 return &Elt;
237
238 bool ReferencesStorage = false;
239 int64_t Index = -1;
240 if (!U::TakesParamByValue) {
241 if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
242 ReferencesStorage = true;
243 Index = &Elt - This->begin();
244 }
245 }
246 This->grow(NewSize);
247 return ReferencesStorage ? This->begin() + Index : &Elt;
248 }
249
250public:
251 using size_type = size_t;
253 using value_type = T;
254 using iterator = T *;
255 using const_iterator = const T *;
256
257 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
258 using reverse_iterator = std::reverse_iterator<iterator>;
259
260 using reference = T &;
261 using const_reference = const T &;
262 using pointer = T *;
263 using const_pointer = const T *;
264
265 using Base::capacity;
266 using Base::empty;
267 using Base::size;
268
269 // forward iterator creation methods.
270 iterator begin() { return (iterator)this->BeginX; }
271 const_iterator begin() const { return (const_iterator)this->BeginX; }
272 iterator end() { return begin() + size(); }
273 const_iterator end() const { return begin() + size(); }
274
275 // reverse iterator creation methods.
280
281 size_type size_in_bytes() const { return size() * sizeof(T); }
283 return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T));
284 }
285
286 size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
287
288 /// Return a pointer to the vector's buffer, even if empty().
289 pointer data() { return pointer(begin()); }
290 /// Return a pointer to the vector's buffer, even if empty().
291 const_pointer data() const { return const_pointer(begin()); }
292
294 assert(idx < size());
295 return begin()[idx];
296 }
298 assert(idx < size());
299 return begin()[idx];
300 }
301
303 assert(!empty());
304 return begin()[0];
305 }
307 assert(!empty());
308 return begin()[0];
309 }
310
312 assert(!empty());
313 return end()[-1];
314 }
316 assert(!empty());
317 return end()[-1];
318 }
319};
320
321/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put
322/// method implementations that are designed to work with non-trivial T's.
323///
324/// We approximate is_trivially_copyable with trivial move/copy construction and
325/// trivial destruction. While the standard doesn't specify that you're allowed
326/// copy these types with memcpy, there is no way for the type to observe this.
327/// This catches the important case of std::pair<POD, POD>, which is not
328/// trivially assignable.
329template <typename T, bool = (std::is_trivially_copy_constructible<T>::value) &&
330 (std::is_trivially_move_constructible<T>::value) &&
331 std::is_trivially_destructible<T>::value>
333 friend class SmallVectorTemplateCommon<T>;
334
335protected:
336 static constexpr bool TakesParamByValue = false;
337 using ValueParamT = const T &;
338
340
341 static void destroy_range(T *S, T *E) {
342 while (S != E) {
343 --E;
344 E->~T();
345 }
346 }
347
348 /// Move the range [I, E) into the uninitialized memory starting with "Dest",
349 /// constructing elements as needed.
350 template<typename It1, typename It2>
351 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
352 std::uninitialized_move(I, E, Dest);
353 }
354
355 /// Copy the range [I, E) onto the uninitialized memory starting with "Dest",
356 /// constructing elements as needed.
357 template<typename It1, typename It2>
358 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
359 std::uninitialized_copy(I, E, Dest);
360 }
361
362 /// Grow the allocated memory (without initializing new elements), doubling
363 /// the size of the allocated memory. Guarantees space for at least one more
364 /// element, or MinSize more elements if specified.
365 void grow(size_t MinSize = 0);
366
367 /// Create a new allocation big enough for \p MinSize and pass back its size
368 /// in \p NewCapacity. This is the first section of \a grow().
369 T *mallocForGrow(size_t MinSize, size_t &NewCapacity);
370
371 /// Move existing elements over to the new allocation \p NewElts, the middle
372 /// section of \a grow().
373 void moveElementsForGrow(T *NewElts);
374
375 /// Transfer ownership of the allocation, finishing up \a grow().
376 void takeAllocationForGrow(T *NewElts, size_t NewCapacity);
377
378 /// Reserve enough space to add one element, and return the updated element
379 /// pointer in case it was a reference to the storage.
380 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
381 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
382 }
383
384 /// Reserve enough space to add one element, and return the updated element
385 /// pointer in case it was a reference to the storage.
386 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
387 return const_cast<T *>(
388 this->reserveForParamAndGetAddressImpl(this, Elt, N));
389 }
390
391 static T &&forward_value_param(T &&V) { return std::move(V); }
392 static const T &forward_value_param(const T &V) { return V; }
393
394 void growAndAssign(size_t NumElts, const T &Elt) {
395 // Grow manually in case Elt is an internal reference.
396 size_t NewCapacity;
397 T *NewElts = mallocForGrow(NumElts, NewCapacity);
398 std::uninitialized_fill_n(NewElts, NumElts, Elt);
399 this->destroy_range(this->begin(), this->end());
400 takeAllocationForGrow(NewElts, NewCapacity);
401 this->set_size(NumElts);
402 }
403
404 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
405 // Grow manually in case one of Args is an internal reference.
406 size_t NewCapacity;
407 T *NewElts = mallocForGrow(0, NewCapacity);
408 ::new ((void *)(NewElts + this->size())) T(std::forward<ArgTypes>(Args)...);
409 moveElementsForGrow(NewElts);
410 takeAllocationForGrow(NewElts, NewCapacity);
411 this->set_size(this->size() + 1);
412 return this->back();
413 }
414
415public:
416 void push_back(const T &Elt) {
417 const T *EltPtr = reserveForParamAndGetAddress(Elt);
418 ::new ((void *)this->end()) T(*EltPtr);
419 this->set_size(this->size() + 1);
420 }
421
422 void push_back(T &&Elt) {
423 T *EltPtr = reserveForParamAndGetAddress(Elt);
424 ::new ((void *)this->end()) T(::std::move(*EltPtr));
425 this->set_size(this->size() + 1);
426 }
427
428 void pop_back() {
429 this->set_size(this->size() - 1);
430 this->end()->~T();
431 }
432};
433
434// Define this out-of-line to dissuade the C++ compiler from inlining it.
435template <typename T, bool TriviallyCopyable>
437 size_t NewCapacity;
438 T *NewElts = mallocForGrow(MinSize, NewCapacity);
439 moveElementsForGrow(NewElts);
440 takeAllocationForGrow(NewElts, NewCapacity);
441}
442
443template <typename T, bool TriviallyCopyable>
445 size_t MinSize, size_t &NewCapacity) {
446 return static_cast<T *>(
448 this->getFirstEl(), MinSize, sizeof(T), NewCapacity));
449}
450
451// Define this out-of-line to dissuade the C++ compiler from inlining it.
452template <typename T, bool TriviallyCopyable>
454 T *NewElts) {
455 // Move the elements over.
456 this->uninitialized_move(this->begin(), this->end(), NewElts);
457
458 // Destroy the original elements.
459 destroy_range(this->begin(), this->end());
460}
461
462// Define this out-of-line to dissuade the C++ compiler from inlining it.
463template <typename T, bool TriviallyCopyable>
465 T *NewElts, size_t NewCapacity) {
466 // If this wasn't grown from the inline copy, deallocate the old space.
467 if (!this->isSmall())
468 free(this->begin());
469
470 this->set_allocation_range(NewElts, NewCapacity);
471}
472
473/// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put
474/// method implementations that are designed to work with trivially copyable
475/// T's. This allows using memcpy in place of copy/move construction and
476/// skipping destruction.
477template <typename T>
479 friend class SmallVectorTemplateCommon<T>;
480
481protected:
482 /// True if it's cheap enough to take parameters by value. Doing so avoids
483 /// overhead related to mitigations for reference invalidation.
484 static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
485
486 /// Either const T& or T, depending on whether it's cheap enough to take
487 /// parameters by value.
488 using ValueParamT = std::conditional_t<TakesParamByValue, T, const T &>;
489
491
492 // No need to do a destroy loop for POD's.
493 static void destroy_range(T *, T *) {}
494
495 /// Move the range [I, E) onto the uninitialized memory
496 /// starting with "Dest", constructing elements into it as needed.
497 template<typename It1, typename It2>
498 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
499 // Just do a copy.
500 uninitialized_copy(I, E, Dest);
501 }
502
503 /// Copy the range [I, E) onto the uninitialized memory
504 /// starting with "Dest", constructing elements into it as needed.
505 template<typename It1, typename It2>
506 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
507 // Arbitrary iterator types; just use the basic implementation.
508 std::uninitialized_copy(I, E, Dest);
509 }
510
511 /// Copy the range [I, E) onto the uninitialized memory
512 /// starting with "Dest", constructing elements into it as needed.
513 template <typename T1, typename T2>
515 T1 *I, T1 *E, T2 *Dest,
516 std::enable_if_t<std::is_same<std::remove_const_t<T1>, T2>::value> * =
517 nullptr) {
518 // Use memcpy for PODs iterated by pointers (which includes SmallVector
519 // iterators): std::uninitialized_copy optimizes to memmove, but we can
520 // use memcpy here. Note that I and E are iterators and thus might be
521 // invalid for memcpy if they are equal.
522 if (I != E)
523 std::memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
524 }
525
526 /// Double the size of the allocated memory, guaranteeing space for at
527 /// least one more element or MinSize if specified.
528 void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); }
529
530 /// Reserve enough space to add one element, and return the updated element
531 /// pointer in case it was a reference to the storage.
532 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
533 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
534 }
535
536 /// Reserve enough space to add one element, and return the updated element
537 /// pointer in case it was a reference to the storage.
538 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
539 return const_cast<T *>(
540 this->reserveForParamAndGetAddressImpl(this, Elt, N));
541 }
542
543 /// Copy \p V or return a reference, depending on \a ValueParamT.
545
546 void growAndAssign(size_t NumElts, T Elt) {
547 // Elt has been copied in case it's an internal reference, side-stepping
548 // reference invalidation problems without losing the realloc optimization.
549 this->set_size(0);
550 this->grow(NumElts);
551 std::uninitialized_fill_n(this->begin(), NumElts, Elt);
552 this->set_size(NumElts);
553 }
554
555 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
556 // Use push_back with a copy in case Args has an internal reference,
557 // side-stepping reference invalidation problems without losing the realloc
558 // optimization.
559 push_back(T(std::forward<ArgTypes>(Args)...));
560 return this->back();
561 }
562
563public:
565 const T *EltPtr = reserveForParamAndGetAddress(Elt);
566 std::memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
567 this->set_size(this->size() + 1);
568 }
569
570 void pop_back() { this->set_size(this->size() - 1); }
571};
572
573/// This class consists of common code factored out of the SmallVector class to
574/// reduce code duplication based on the SmallVector 'N' template parameter.
575template <typename T>
577 using SuperClass = SmallVectorTemplateBase<T>;
578
579public:
584
585protected:
588
589 // Default ctor - Initialize to empty.
590 explicit SmallVectorImpl(unsigned N)
592
594 this->destroy_range(this->begin(), this->end());
595 if (!this->isSmall())
596 free(this->begin());
597 this->BeginX = RHS.BeginX;
598 this->Size = RHS.Size;
599 this->Capacity = RHS.Capacity;
600 RHS.resetToSmall();
601 }
602
604 // Subclass has already destructed this vector's elements.
605 // If this wasn't grown from the inline copy, deallocate the old space.
606 if (!this->isSmall())
607 free(this->begin());
608 }
609
610public:
612
613 void clear() {
614 this->destroy_range(this->begin(), this->end());
615 this->Size = 0;
616 }
617
618private:
619 // Make set_size() private to avoid misuse in subclasses.
621
622 template <bool ForOverwrite> void resizeImpl(size_type N) {
623 if (N == this->size())
624 return;
625
626 if (N < this->size()) {
627 this->truncate(N);
628 return;
629 }
630
631 this->reserve(N);
632 for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
633 if (ForOverwrite)
634 new (&*I) T;
635 else
636 new (&*I) T();
637 this->set_size(N);
638 }
639
640public:
641 void resize(size_type N) { resizeImpl<false>(N); }
642
643 /// Like resize, but \ref T is POD, the new values won't be initialized.
644 void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
645
646 /// Like resize, but requires that \p N is less than \a size().
648 assert(this->size() >= N && "Cannot increase size with truncate");
649 this->destroy_range(this->begin() + N, this->end());
650 this->set_size(N);
651 }
652
654 if (N == this->size())
655 return;
656
657 if (N < this->size()) {
658 this->truncate(N);
659 return;
660 }
661
662 // N > this->size(). Defer to append.
663 this->append(N - this->size(), NV);
664 }
665
667 if (this->capacity() < N)
668 this->grow(N);
669 }
670
671 void pop_back_n(size_type NumItems) {
672 assert(this->size() >= NumItems);
673 truncate(this->size() - NumItems);
674 }
675
676 [[nodiscard]] T pop_back_val() {
677 T Result = ::std::move(this->back());
678 this->pop_back();
679 return Result;
680 }
681
683
684 /// Add the specified range to the end of the SmallVector.
685 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
686 void append(ItTy in_start, ItTy in_end) {
687 this->assertSafeToAddRange(in_start, in_end);
688 size_type NumInputs = std::distance(in_start, in_end);
689 this->reserve(this->size() + NumInputs);
690 this->uninitialized_copy(in_start, in_end, this->end());
691 this->set_size(this->size() + NumInputs);
692 }
693
694 /// Append \p NumInputs copies of \p Elt to the end.
695 void append(size_type NumInputs, ValueParamT Elt) {
696 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
697 std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr);
698 this->set_size(this->size() + NumInputs);
699 }
700
701 void append(std::initializer_list<T> IL) {
702 append(IL.begin(), IL.end());
703 }
704
705 void append(const SmallVectorImpl &RHS) { append(RHS.begin(), RHS.end()); }
706
707 void assign(size_type NumElts, ValueParamT Elt) {
708 // Note that Elt could be an internal reference.
709 if (NumElts > this->capacity()) {
710 this->growAndAssign(NumElts, Elt);
711 return;
712 }
713
714 // Assign over existing elements.
715 std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt);
716 if (NumElts > this->size())
717 std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt);
718 else if (NumElts < this->size())
719 this->destroy_range(this->begin() + NumElts, this->end());
720 this->set_size(NumElts);
721 }
722
723 // FIXME: Consider assigning over existing elements, rather than clearing &
724 // re-initializing them - for all assign(...) variants.
725
726 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
727 void assign(ItTy in_start, ItTy in_end) {
728 this->assertSafeToReferenceAfterClear(in_start, in_end);
729 clear();
730 append(in_start, in_end);
731 }
732
733 void assign(std::initializer_list<T> IL) {
734 clear();
735 append(IL);
736 }
737
738 void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); }
739
741 // Just cast away constness because this is a non-const member function.
742 iterator I = const_cast<iterator>(CI);
743
744 assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds.");
745
746 iterator N = I;
747 // Shift all elts down one.
748 std::move(I+1, this->end(), I);
749 // Drop the last elt.
750 this->pop_back();
751 return(N);
752 }
753
755 // Just cast away constness because this is a non-const member function.
756 iterator S = const_cast<iterator>(CS);
757 iterator E = const_cast<iterator>(CE);
758
759 assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds.");
760
761 iterator N = S;
762 // Shift all elts down.
763 iterator I = std::move(E, this->end(), S);
764 // Drop the last elts.
765 this->destroy_range(I, this->end());
766 this->set_size(I - this->begin());
767 return(N);
768 }
769
770private:
771 template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) {
772 // Callers ensure that ArgType is derived from T.
773 static_assert(
774 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
775 T>::value,
776 "ArgType must be derived from T!");
777
778 if (I == this->end()) { // Important special case for empty vector.
779 this->push_back(::std::forward<ArgType>(Elt));
780 return this->end()-1;
781 }
782
783 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
784
785 // Grow if necessary.
786 size_t Index = I - this->begin();
787 std::remove_reference_t<ArgType> *EltPtr =
789 I = this->begin() + Index;
790
791 ::new ((void*) this->end()) T(::std::move(this->back()));
792 // Push everything else over.
793 std::move_backward(I, this->end()-1, this->end());
794 this->set_size(this->size() + 1);
795
796 // If we just moved the element we're inserting, be sure to update
797 // the reference (never happens if TakesParamByValue).
798 static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
799 "ArgType must be 'T' when taking by value!");
800 if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end()))
801 ++EltPtr;
802
803 *I = ::std::forward<ArgType>(*EltPtr);
804 return I;
805 }
806
807public:
809 return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
810 }
811
812 iterator insert(iterator I, const T &Elt) {
813 return insert_one_impl(I, this->forward_value_param(Elt));
814 }
815
817 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
818 size_t InsertElt = I - this->begin();
819
820 if (I == this->end()) { // Important special case for empty vector.
821 append(NumToInsert, Elt);
822 return this->begin()+InsertElt;
823 }
824
825 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
826
827 // Ensure there is enough space, and get the (maybe updated) address of
828 // Elt.
829 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
830
831 // Uninvalidate the iterator.
832 I = this->begin()+InsertElt;
833
834 // If there are more elements between the insertion point and the end of the
835 // range than there are being inserted, we can use a simple approach to
836 // insertion. Since we already reserved space, we know that this won't
837 // reallocate the vector.
838 if (size_t(this->end()-I) >= NumToInsert) {
839 T *OldEnd = this->end();
840 append(std::move_iterator<iterator>(this->end() - NumToInsert),
841 std::move_iterator<iterator>(this->end()));
842
843 // Copy the existing elements that get replaced.
844 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
845
846 // If we just moved the element we're inserting, be sure to update
847 // the reference (never happens if TakesParamByValue).
848 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
849 EltPtr += NumToInsert;
850
851 std::fill_n(I, NumToInsert, *EltPtr);
852 return I;
853 }
854
855 // Otherwise, we're inserting more elements than exist already, and we're
856 // not inserting at the end.
857
858 // Move over the elements that we're about to overwrite.
859 T *OldEnd = this->end();
860 this->set_size(this->size() + NumToInsert);
861 size_t NumOverwritten = OldEnd-I;
862 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
863
864 // If we just moved the element we're inserting, be sure to update
865 // the reference (never happens if TakesParamByValue).
866 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
867 EltPtr += NumToInsert;
868
869 // Replace the overwritten part.
870 std::fill_n(I, NumOverwritten, *EltPtr);
871
872 // Insert the non-overwritten middle part.
873 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
874 return I;
875 }
876
877 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
879 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
880 size_t InsertElt = I - this->begin();
881
882 if (I == this->end()) { // Important special case for empty vector.
883 append(From, To);
884 return this->begin()+InsertElt;
885 }
886
887 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
888
889 // Check that the reserve that follows doesn't invalidate the iterators.
890 this->assertSafeToAddRange(From, To);
891
892 size_t NumToInsert = std::distance(From, To);
893
894 // Ensure there is enough space.
895 reserve(this->size() + NumToInsert);
896
897 // Uninvalidate the iterator.
898 I = this->begin()+InsertElt;
899
900 // If there are more elements between the insertion point and the end of the
901 // range than there are being inserted, we can use a simple approach to
902 // insertion. Since we already reserved space, we know that this won't
903 // reallocate the vector.
904 if (size_t(this->end()-I) >= NumToInsert) {
905 T *OldEnd = this->end();
906 append(std::move_iterator<iterator>(this->end() - NumToInsert),
907 std::move_iterator<iterator>(this->end()));
908
909 // Copy the existing elements that get replaced.
910 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
911
912 std::copy(From, To, I);
913 return I;
914 }
915
916 // Otherwise, we're inserting more elements than exist already, and we're
917 // not inserting at the end.
918
919 // Move over the elements that we're about to overwrite.
920 T *OldEnd = this->end();
921 this->set_size(this->size() + NumToInsert);
922 size_t NumOverwritten = OldEnd-I;
923 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
924
925 // Replace the overwritten part.
926 for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
927 *J = *From;
928 ++J; ++From;
929 }
930
931 // Insert the non-overwritten middle part.
932 this->uninitialized_copy(From, To, OldEnd);
933 return I;
934 }
935
936 void insert(iterator I, std::initializer_list<T> IL) {
937 insert(I, IL.begin(), IL.end());
938 }
939
940 template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
941 if (LLVM_UNLIKELY(this->size() >= this->capacity()))
942 return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...);
943
944 ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
945 this->set_size(this->size() + 1);
946 return this->back();
947 }
948
950
952
953 bool operator==(const SmallVectorImpl &RHS) const {
954 if (this->size() != RHS.size()) return false;
955 return std::equal(this->begin(), this->end(), RHS.begin());
956 }
957 bool operator!=(const SmallVectorImpl &RHS) const {
958 return !(*this == RHS);
959 }
960
961 bool operator<(const SmallVectorImpl &RHS) const {
962 return std::lexicographical_compare(this->begin(), this->end(),
963 RHS.begin(), RHS.end());
964 }
965 bool operator>(const SmallVectorImpl &RHS) const { return RHS < *this; }
966 bool operator<=(const SmallVectorImpl &RHS) const { return !(*this > RHS); }
967 bool operator>=(const SmallVectorImpl &RHS) const { return !(*this < RHS); }
968};
969
970template <typename T>
972 if (this == &RHS) return;
973
974 // We can only avoid copying elements if neither vector is small.
975 if (!this->isSmall() && !RHS.isSmall()) {
976 std::swap(this->BeginX, RHS.BeginX);
977 std::swap(this->Size, RHS.Size);
978 std::swap(this->Capacity, RHS.Capacity);
979 return;
980 }
981 this->reserve(RHS.size());
982 RHS.reserve(this->size());
983
984 // Swap the shared elements.
985 size_t NumShared = this->size();
986 if (NumShared > RHS.size()) NumShared = RHS.size();
987 for (size_type i = 0; i != NumShared; ++i)
988 std::swap((*this)[i], RHS[i]);
989
990 // Copy over the extra elts.
991 if (this->size() > RHS.size()) {
992 size_t EltDiff = this->size() - RHS.size();
993 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
994 RHS.set_size(RHS.size() + EltDiff);
995 this->destroy_range(this->begin()+NumShared, this->end());
996 this->set_size(NumShared);
997 } else if (RHS.size() > this->size()) {
998 size_t EltDiff = RHS.size() - this->size();
999 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
1000 this->set_size(this->size() + EltDiff);
1001 this->destroy_range(RHS.begin()+NumShared, RHS.end());
1002 RHS.set_size(NumShared);
1003 }
1004}
1005
1006template <typename T>
1009 // Avoid self-assignment.
1010 if (this == &RHS) return *this;
1011
1012 // If we already have sufficient space, assign the common elements, then
1013 // destroy any excess.
1014 size_t RHSSize = RHS.size();
1015 size_t CurSize = this->size();
1016 if (CurSize >= RHSSize) {
1017 // Assign common elements.
1018 iterator NewEnd;
1019 if (RHSSize)
1020 NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
1021 else
1022 NewEnd = this->begin();
1023
1024 // Destroy excess elements.
1025 this->destroy_range(NewEnd, this->end());
1026
1027 // Trim.
1028 this->set_size(RHSSize);
1029 return *this;
1030 }
1031
1032 // If we have to grow to have enough elements, destroy the current elements.
1033 // This allows us to avoid copying them during the grow.
1034 // FIXME: don't do this if they're efficiently moveable.
1035 if (this->capacity() < RHSSize) {
1036 // Destroy current elements.
1037 this->clear();
1038 CurSize = 0;
1039 this->grow(RHSSize);
1040 } else if (CurSize) {
1041 // Otherwise, use assignment for the already-constructed elements.
1042 std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
1043 }
1044
1045 // Copy construct the new elements in place.
1046 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
1047 this->begin()+CurSize);
1048
1049 // Set end.
1050 this->set_size(RHSSize);
1051 return *this;
1052}
1053
1054template <typename T>
1056 // Avoid self-assignment.
1057 if (this == &RHS) return *this;
1058
1059 // If the RHS isn't small, clear this vector and then steal its buffer.
1060 if (!RHS.isSmall()) {
1061 this->assignRemote(std::move(RHS));
1062 return *this;
1063 }
1064
1065 // If we already have sufficient space, assign the common elements, then
1066 // destroy any excess.
1067 size_t RHSSize = RHS.size();
1068 size_t CurSize = this->size();
1069 if (CurSize >= RHSSize) {
1070 // Assign common elements.
1071 iterator NewEnd = this->begin();
1072 if (RHSSize)
1073 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
1074
1075 // Destroy excess elements and trim the bounds.
1076 this->destroy_range(NewEnd, this->end());
1077 this->set_size(RHSSize);
1078
1079 // Clear the RHS.
1080 RHS.clear();
1081
1082 return *this;
1083 }
1084
1085 // If we have to grow to have enough elements, destroy the current elements.
1086 // This allows us to avoid copying them during the grow.
1087 // FIXME: this may not actually make any sense if we can efficiently move
1088 // elements.
1089 if (this->capacity() < RHSSize) {
1090 // Destroy current elements.
1091 this->clear();
1092 CurSize = 0;
1093 this->grow(RHSSize);
1094 } else if (CurSize) {
1095 // Otherwise, use assignment for the already-constructed elements.
1096 std::move(RHS.begin(), RHS.begin()+CurSize, this->begin());
1097 }
1098
1099 // Move-construct the new elements in place.
1100 this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
1101 this->begin()+CurSize);
1102
1103 // Set end.
1104 this->set_size(RHSSize);
1105
1106 RHS.clear();
1107 return *this;
1108}
1109
1110/// Storage for the SmallVector elements. This is specialized for the N=0 case
1111/// to avoid allocating unnecessary storage.
1112template <typename T, unsigned N>
1114 alignas(T) char InlineElts[N * sizeof(T)];
1115};
1116
1117/// We need the storage to be properly aligned even for small-size of 0 so that
1118/// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is
1119/// well-defined.
1120template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
1121
1122/// Forward declaration of SmallVector so that
1123/// calculateSmallVectorDefaultInlinedElements can reference
1124/// `sizeof(SmallVector<T, 0>)`.
1125template <typename T, unsigned N> class LLVM_GSL_OWNER SmallVector;
1126
1127/// Helper class for calculating the default number of inline elements for
1128/// `SmallVector<T>`.
1129///
1130/// This should be migrated to a constexpr function when our minimum
1131/// compiler support is enough for multi-statement constexpr functions.
1133 // Parameter controlling the default number of inlined elements
1134 // for `SmallVector<T>`.
1135 //
1136 // The default number of inlined elements ensures that
1137 // 1. There is at least one inlined element.
1138 // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless
1139 // it contradicts 1.
1140 static constexpr size_t kPreferredSmallVectorSizeof = 64;
1141
1142 // static_assert that sizeof(T) is not "too big".
1143 //
1144 // Because our policy guarantees at least one inlined element, it is possible
1145 // for an arbitrarily large inlined element to allocate an arbitrarily large
1146 // amount of inline storage. We generally consider it an antipattern for a
1147 // SmallVector to allocate an excessive amount of inline storage, so we want
1148 // to call attention to these cases and make sure that users are making an
1149 // intentional decision if they request a lot of inline storage.
1150 //
1151 // We want this assertion to trigger in pathological cases, but otherwise
1152 // not be too easy to hit. To accomplish that, the cutoff is actually somewhat
1153 // larger than kPreferredSmallVectorSizeof (otherwise,
1154 // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that
1155 // pattern seems useful in practice).
1156 //
1157 // One wrinkle is that this assertion is in theory non-portable, since
1158 // sizeof(T) is in general platform-dependent. However, we don't expect this
1159 // to be much of an issue, because most LLVM development happens on 64-bit
1160 // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for
1161 // 32-bit hosts, dodging the issue. The reverse situation, where development
1162 // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a
1163 // 64-bit host, is expected to be very rare.
1164 static_assert(
1165 sizeof(T) <= 256,
1166 "You are trying to use a default number of inlined elements for "
1167 "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
1168 "explicit number of inlined elements with `SmallVector<T, N>` to make "
1169 "sure you really want that much inline storage.");
1170
1171 // Discount the size of the header itself when calculating the maximum inline
1172 // bytes.
1173 static constexpr size_t PreferredInlineBytes =
1175 static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T);
1176 static constexpr size_t value =
1178};
1179
1180/// This is a 'vector' (really, a variable-sized array), optimized
1181/// for the case when the array is small. It contains some number of elements
1182/// in-place, which allows it to avoid heap allocation when the actual number of
1183/// elements is below that threshold. This allows normal "small" cases to be
1184/// fast without losing generality for large inputs.
1185///
1186/// \note
1187/// In the absence of a well-motivated choice for the number of inlined
1188/// elements \p N, it is recommended to use \c SmallVector<T> (that is,
1189/// omitting the \p N). This will choose a default number of inlined elements
1190/// reasonable for allocation on the stack (for example, trying to keep \c
1191/// sizeof(SmallVector<T>) around 64 bytes).
1192///
1193/// \warning This does not attempt to be exception safe.
1194///
1195/// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
1196template <typename T,
1199 SmallVectorStorage<T, N> {
1200public:
1202
1204 // Destroy the constructed elements in the vector.
1205 this->destroy_range(this->begin(), this->end());
1206 }
1207
1208 explicit SmallVector(size_t Size)
1209 : SmallVectorImpl<T>(N) {
1210 this->resize(Size);
1211 }
1212
1213 SmallVector(size_t Size, const T &Value)
1214 : SmallVectorImpl<T>(N) {
1215 this->assign(Size, Value);
1216 }
1217
1218 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
1220 this->append(S, E);
1221 }
1222
1223 template <typename RangeTy>
1225 : SmallVectorImpl<T>(N) {
1226 this->append(R.begin(), R.end());
1227 }
1228
1229 SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
1230 this->append(IL);
1231 }
1232
1233 template <typename U,
1234 typename = std::enable_if_t<std::is_convertible<U, T>::value>>
1236 this->append(A.begin(), A.end());
1237 }
1238
1240 if (!RHS.empty())
1242 }
1243
1246 return *this;
1247 }
1248
1250 if (!RHS.empty())
1251 SmallVectorImpl<T>::operator=(::std::move(RHS));
1252 }
1253
1255 if (!RHS.empty())
1256 SmallVectorImpl<T>::operator=(::std::move(RHS));
1257 }
1258
1260 if (N) {
1261 SmallVectorImpl<T>::operator=(::std::move(RHS));
1262 return *this;
1263 }
1264 // SmallVectorImpl<T>::operator= does not leverage N==0. Optimize the
1265 // case.
1266 if (this == &RHS)
1267 return *this;
1268 if (RHS.empty()) {
1269 this->destroy_range(this->begin(), this->end());
1270 this->Size = 0;
1271 } else {
1272 this->assignRemote(std::move(RHS));
1273 }
1274 return *this;
1275 }
1276
1278 SmallVectorImpl<T>::operator=(::std::move(RHS));
1279 return *this;
1280 }
1281
1282 SmallVector &operator=(std::initializer_list<T> IL) {
1283 this->assign(IL);
1284 return *this;
1285 }
1286};
1287
1288template <typename T, unsigned N>
1290 return X.capacity_in_bytes();
1291}
1292
1293template <typename RangeType>
1295 std::remove_const_t<std::remove_reference_t<decltype(*std::begin(
1296 std::declval<RangeType &>()))>>;
1297
1298/// Given a range of type R, iterate the entire range and return a
1299/// SmallVector with elements of the vector. This is useful, for example,
1300/// when you want to iterate a range and then sort the results.
1301template <unsigned Size, typename R>
1303 return {std::begin(Range), std::end(Range)};
1304}
1305template <typename R>
1307 return {std::begin(Range), std::end(Range)};
1308}
1309
1310template <typename Out, unsigned Size, typename R>
1312 return {std::begin(Range), std::end(Range)};
1313}
1314
1315template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
1316 return {std::begin(Range), std::end(Range)};
1317}
1318
1319// Explicit instantiations
1320extern template class llvm::SmallVectorBase<uint32_t>;
1321#if SIZE_MAX > UINT32_MAX
1322extern template class llvm::SmallVectorBase<uint64_t>;
1323#endif
1324
1325// Provide DenseMapInfo for SmallVector of a type which has info.
1326template <typename T, unsigned N> struct DenseMapInfo<llvm::SmallVector<T, N>> {
1330
1334
1335 static unsigned getHashValue(const SmallVector<T, N> &V) {
1336 return static_cast<unsigned>(hash_combine_range(V));
1337 }
1338
1339 static bool isEqual(const SmallVector<T, N> &LHS,
1340 const SmallVector<T, N> &RHS) {
1341 return LHS == RHS;
1342 }
1343};
1344
1345} // end namespace llvm
1346
1347namespace std {
1348
1349 /// Implement std::swap in terms of SmallVector swap.
1350 template<typename T>
1351 inline void
1355
1356 /// Implement std::swap in terms of SmallVector swap.
1357 template<typename T, unsigned N>
1358 inline void
1362
1363} // end namespace std
1364
1365#endif // LLVM_ADT_SMALLVECTOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:336
#define LLVM_GSL_OWNER
LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable lifetime warnings.
Definition Compiler.h:421
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:335
This file defines DenseMapInfo traits for DenseMap.
#define offsetof(TYPE, MEMBER)
#define I(x, y, z)
Definition MD5.cpp:58
#define T
#define T1
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
if(PassOpts->AAPipeline)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Value * RHS
Value * LHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
This is all the stuff common to all SmallVectors.
Definition SmallVector.h:53
LLVM_ABI void grow_pod(void *FirstEl, size_t MinSize, size_t TSize)
This is an implementation of the grow() method which only works on POD-like data types and is out of ...
LLVM_ABI void * mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize, size_t &NewCapacity)
This is a helper for grow() that's out of line to reduce code duplication.
void set_allocation_range(void *Begin, size_t N)
Set the array data pointer to Begin and capacity to N.
Definition SmallVector.h:98
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
Definition SmallVector.h:64
void set_size(size_t N)
Set the array size to N, which the current array must have enough capacity for.
Definition SmallVector.h:89
size_t capacity() const
Definition SmallVector.h:80
size_t size() const
Definition SmallVector.h:79
static constexpr size_t SizeTypeMax()
The maximum value of the Size_T used.
Definition SmallVector.h:59
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
void append(const SmallVectorImpl &RHS)
void pop_back_n(size_type NumItems)
void assign(const SmallVectorImpl &RHS)
SmallVectorImpl(const SmallVectorImpl &)=delete
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
bool operator==(const SmallVectorImpl &RHS) const
void reserve(size_type N)
typename SuperClass::reference reference
iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt)
iterator erase(const_iterator CI)
iterator insert(iterator I, ItTy From, ItTy To)
typename SuperClass::const_iterator const_iterator
void assignRemote(SmallVectorImpl &&RHS)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void resize(size_type N, ValueParamT NV)
iterator insert(iterator I, MemoryLocation &&Elt)
bool operator>(const SmallVectorImpl &RHS) const
bool operator<(const SmallVectorImpl &RHS) const
iterator erase(const_iterator CS, const_iterator CE)
bool operator!=(const SmallVectorImpl &RHS) const
void truncate(size_type N)
Like resize, but requires that N is less than size().
void assign(ItTy in_start, ItTy in_end)
void assign(std::initializer_list< T > IL)
SmallVectorImpl(unsigned N)
void swap(SmallVectorImpl &RHS)
typename SuperClass::iterator iterator
bool operator<=(const SmallVectorImpl &RHS) const
typename SuperClass::size_type size_type
void append(std::initializer_list< T > IL)
void append(size_type NumInputs, ValueParamT Elt)
Append NumInputs copies of Elt to the end.
void resize(size_type N)
SmallVectorImpl & operator=(const SmallVectorImpl &RHS)
void insert(iterator I, std::initializer_list< T > IL)
SmallVectorImpl & operator=(SmallVectorImpl &&RHS)
typename SuperClass::ValueParamT ValueParamT
bool operator>=(const SmallVectorImpl &RHS) const
iterator insert(iterator I, const T &Elt)
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 ...
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 ...
std::conditional_t< TakesParamByValue, T, const T & > ValueParamT
Either const T& or T, depending on whether it's cheap enough to take parameters by value.
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
static ValueParamT forward_value_param(ValueParamT V)
Copy V or return a reference, depending on ValueParamT.
T & growAndEmplaceBack(ArgTypes &&... Args)
static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest, std::enable_if_t< std::is_same< std::remove_const_t< T1 >, T2 >::value > *=nullptr)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
static constexpr bool TakesParamByValue
True if it's cheap enough to take parameters by value.
void growAndAssign(size_t NumElts, T Elt)
void grow(size_t MinSize=0)
Double the size of the allocated memory, guaranteeing space for at least one more element or MinSize ...
void moveElementsForGrow(T *NewElts)
Move existing elements over to the new allocation NewElts, the middle section of grow().
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...
static T && forward_value_param(T &&V)
static void destroy_range(T *S, T *E)
T * mallocForGrow(size_t MinSize, size_t &NewCapacity)
Create a new allocation big enough for MinSize and pass back its size in NewCapacity.
static constexpr bool TakesParamByValue
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
void takeAllocationForGrow(T *NewElts, size_t NewCapacity)
Transfer ownership of the allocation, finishing up grow().
void growAndAssign(size_t NumElts, const T &Elt)
static const T & forward_value_param(const T &V)
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...
void grow(size_t MinSize=0)
Grow the allocated memory (without initializing new elements), doubling the size of the allocated mem...
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
T & growAndEmplaceBack(ArgTypes &&... Args)
void push_back(const T &Elt)
bool isSmall() const
Return true if this is a smallvector which has not had dynamic memory allocated for it.
const_iterator end() const
static const T * reserveForParamAndGetAddressImpl(U *This, const T &Elt, size_t N)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
const_reference operator[](size_type idx) const
void resetToSmall()
Put this vector in a state of being small.
bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Return true unless Elt will be invalidated by resizing the vector to NewSize.
std::reverse_iterator< const_iterator > const_reverse_iterator
pointer data()
Return a pointer to the vector's buffer, even if empty().
bool isReferenceToRange(const void *V, const void *First, const void *Last) const
Return true if V is an internal reference to the given range.
void grow_pod(size_t MinSize, size_t TSize)
const_reverse_iterator rbegin() const
const_iterator begin() const
reference operator[](size_type idx)
size_type size_in_bytes() const
bool isReferenceToStorage(const void *V) const
Return true if V is an internal reference to this vector.
const_reference back() const
bool isRangeInStorage(const void *First, const void *Last) const
Return true if First and Last form a valid (possibly empty) range in this vector's storage.
const_reference front() const
void assertSafeToAdd(const void *Elt, size_t N=1)
Check whether Elt will be invalidated by increasing the size of the vector by N.
void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Check whether Elt will be invalidated by resizing the vector to NewSize.
void assertSafeToAddRange(ItTy From, ItTy To)
Check whether any part of the range will be invalidated by growing.
std::reverse_iterator< iterator > reverse_iterator
void assertSafeToReferenceAfterClear(ItTy From, ItTy To)
Check whether any part of the range will be invalidated by clearing.
const_reverse_iterator rend() const
const_pointer data() const
Return a pointer to the vector's buffer, even if empty().
void * getFirstEl() const
Find the address of the first element.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SmallVector(std::initializer_list< T > IL)
SmallVector(SmallVectorImpl< T > &&RHS)
SmallVector(size_t Size)
SmallVector(ArrayRef< U > A)
SmallVector(size_t Size, const T &Value)
SmallVector & operator=(const SmallVector &RHS)
SmallVector(const iterator_range< RangeTy > &R)
SmallVector & operator=(std::initializer_list< T > IL)
SmallVector(ItTy S, ItTy E)
SmallVector(SmallVector &&RHS)
SmallVector & operator=(SmallVector &&RHS)
SmallVector(const SmallVector &RHS)
SmallVector & operator=(SmallVectorImpl< T > &&RHS)
LLVM Value Representation.
Definition Value.h:75
A range adaptor for a pair of iterators.
This is an optimization pass for GlobalISel generic memory operations.
std::enable_if_t< std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::input_iterator_tag >::value > EnableIfConvertibleToInputIterator
Definition SmallVector.h:41
BitVector::size_type capacity_in_bytes(const BitVector &X)
Definition BitVector.h:847
std::remove_const_t< std::remove_reference_t< decltype(*std::begin( std::declval< RangeType & >()))> > ValueTypeFromRangeType
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
std::conditional_t< sizeof(T)< 4 &&sizeof(void *) >=8, uint64_t, uint32_t > SmallVectorSizeType
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:71
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1847
SmallVector< Out, Size > to_vector_of(R &&Range)
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition Hashing.h:466
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
#define N
Helper class for calculating the default number of inline elements for SmallVector<T>.
static bool isEqual(const SmallVector< T, N > &LHS, const SmallVector< T, N > &RHS)
static SmallVector< T, N > getTombstoneKey()
static unsigned getHashValue(const SmallVector< T, N > &V)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Figure out the offset of the first element.
char Base[sizeof(SmallVectorBase< SmallVectorSizeType< T > >)]
Storage for the SmallVector elements.
char InlineElts[N *sizeof(T)]