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