LLVM 23.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 (void)From;
215 (void)To;
216 }
217
218 /// Check whether any part of the range will be invalidated by growing.
219 template <class ItTy> void assertSafeToAddRange(ItTy From, ItTy To) {
220 if constexpr (std::is_pointer_v<ItTy> &&
221 std::is_same_v<std::remove_cv_t<std::remove_pointer_t<ItTy>>,
222 T>) {
223 if (From == To)
224 return;
225 this->assertSafeToAdd(From, To - From);
226 this->assertSafeToAdd(To - 1, To - From);
227 }
228 (void)From;
229 (void)To;
230 }
231
232 /// Reserve enough space to add one element, and return the updated element
233 /// pointer in case it was a reference to the storage.
234 template <class U>
235 static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt,
236 size_t N) {
237 size_t NewSize = This->size() + N;
238 if (LLVM_LIKELY(NewSize <= This->capacity()))
239 return &Elt;
240
241 bool ReferencesStorage = false;
242 int64_t Index = -1;
243 if (!U::TakesParamByValue) {
244 if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
245 ReferencesStorage = true;
246 Index = &Elt - This->begin();
247 }
248 }
249 This->grow(NewSize);
250 return ReferencesStorage ? This->begin() + Index : &Elt;
251 }
252
253public:
254 using size_type = size_t;
256 using value_type = T;
257 using iterator = T *;
258 using const_iterator = const T *;
259
260 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
261 using reverse_iterator = std::reverse_iterator<iterator>;
262
263 using reference = T &;
264 using const_reference = const T &;
265 using pointer = T *;
266 using const_pointer = const T *;
267
268 using Base::capacity;
269 using Base::empty;
270 using Base::size;
271
272 // forward iterator creation methods.
273 iterator begin() { return (iterator)this->BeginX; }
274 const_iterator begin() const { return (const_iterator)this->BeginX; }
275 iterator end() { return begin() + size(); }
276 const_iterator end() const { return begin() + size(); }
277
278 // reverse iterator creation methods.
283
284 size_type size_in_bytes() const { return size() * sizeof(T); }
286 return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T));
287 }
288
289 size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
290
291 /// Return a pointer to the vector's buffer, even if empty().
292 pointer data() { return pointer(begin()); }
293 /// Return a pointer to the vector's buffer, even if empty().
294 const_pointer data() const { return const_pointer(begin()); }
295
297 assert(idx < size());
298 return begin()[idx];
299 }
301 assert(idx < size());
302 return begin()[idx];
303 }
304
306 assert(!empty());
307 return begin()[0];
308 }
310 assert(!empty());
311 return begin()[0];
312 }
313
315 assert(!empty());
316 return end()[-1];
317 }
319 assert(!empty());
320 return end()[-1];
321 }
322};
323
324/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put
325/// method implementations that are designed to work with non-trivial T's.
326///
327/// We approximate is_trivially_copyable with trivial move/copy construction and
328/// trivial destruction. While the standard doesn't specify that you're allowed
329/// copy these types with memcpy, there is no way for the type to observe this.
330/// This catches the important case of std::pair<POD, POD>, which is not
331/// trivially assignable.
332template <typename T, bool = (std::is_trivially_copy_constructible<T>::value) &&
333 (std::is_trivially_move_constructible<T>::value) &&
334 std::is_trivially_destructible<T>::value>
336 friend class SmallVectorTemplateCommon<T>;
337
338protected:
339 static constexpr bool TakesParamByValue = false;
340 using ValueParamT = const T &;
341
343
344 static void destroy_range(T *S, T *E) {
345 while (S != E) {
346 --E;
347 E->~T();
348 }
349 }
350
351 /// Move the range [I, E) into the uninitialized memory starting with "Dest",
352 /// constructing elements as needed.
353 template<typename It1, typename It2>
354 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
355 std::uninitialized_move(I, E, Dest);
356 }
357
358 /// Copy the range [I, E) onto the uninitialized memory starting with "Dest",
359 /// constructing elements as needed.
360 template<typename It1, typename It2>
361 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
362 std::uninitialized_copy(I, E, Dest);
363 }
364
365 /// Grow the allocated memory (without initializing new elements), doubling
366 /// the size of the allocated memory. Guarantees space for at least one more
367 /// element, or MinSize more elements if specified.
368 void grow(size_t MinSize = 0);
369
370 /// Create a new allocation big enough for \p MinSize and pass back its size
371 /// in \p NewCapacity. This is the first section of \a grow().
372 T *mallocForGrow(size_t MinSize, size_t &NewCapacity);
373
374 /// Move existing elements over to the new allocation \p NewElts, the middle
375 /// section of \a grow().
376 void moveElementsForGrow(T *NewElts);
377
378 /// Transfer ownership of the allocation, finishing up \a grow().
379 void takeAllocationForGrow(T *NewElts, size_t NewCapacity);
380
381 /// Reserve enough space to add one element, and return the updated element
382 /// pointer in case it was a reference to the storage.
383 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
384 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
385 }
386
387 /// Reserve enough space to add one element, and return the updated element
388 /// pointer in case it was a reference to the storage.
389 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
390 return const_cast<T *>(
391 this->reserveForParamAndGetAddressImpl(this, Elt, N));
392 }
393
394 static T &&forward_value_param(T &&V) { return std::move(V); }
395 static const T &forward_value_param(const T &V) { return V; }
396
397 void growAndAssign(size_t NumElts, const T &Elt) {
398 // Grow manually in case Elt is an internal reference.
399 size_t NewCapacity;
400 T *NewElts = mallocForGrow(NumElts, NewCapacity);
401 std::uninitialized_fill_n(NewElts, NumElts, Elt);
402 this->destroy_range(this->begin(), this->end());
403 takeAllocationForGrow(NewElts, NewCapacity);
404 this->set_size(NumElts);
405 }
406
407 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
408 // Grow manually in case one of Args is an internal reference.
409 size_t NewCapacity;
410 T *NewElts = mallocForGrow(0, NewCapacity);
411 ::new ((void *)(NewElts + this->size())) T(std::forward<ArgTypes>(Args)...);
412 moveElementsForGrow(NewElts);
413 takeAllocationForGrow(NewElts, NewCapacity);
414 this->set_size(this->size() + 1);
415 return this->back();
416 }
417
418public:
419 void push_back(const T &Elt) {
420 const T *EltPtr = reserveForParamAndGetAddress(Elt);
421 ::new ((void *)this->end()) T(*EltPtr);
422 this->set_size(this->size() + 1);
423 }
424
425 void push_back(T &&Elt) {
426 T *EltPtr = reserveForParamAndGetAddress(Elt);
427 ::new ((void *)this->end()) T(::std::move(*EltPtr));
428 this->set_size(this->size() + 1);
429 }
430
431 void pop_back() {
432 this->set_size(this->size() - 1);
433 this->end()->~T();
434 }
435};
436
437// Define this out-of-line to dissuade the C++ compiler from inlining it.
438template <typename T, bool TriviallyCopyable>
440 size_t NewCapacity;
441 T *NewElts = mallocForGrow(MinSize, NewCapacity);
442 moveElementsForGrow(NewElts);
443 takeAllocationForGrow(NewElts, NewCapacity);
444}
445
446template <typename T, bool TriviallyCopyable>
448 size_t MinSize, size_t &NewCapacity) {
449 return static_cast<T *>(
451 this->getFirstEl(), MinSize, sizeof(T), NewCapacity));
452}
453
454// Define this out-of-line to dissuade the C++ compiler from inlining it.
455template <typename T, bool TriviallyCopyable>
457 T *NewElts) {
458 // Move the elements over.
459 this->uninitialized_move(this->begin(), this->end(), NewElts);
460
461 // Destroy the original elements.
462 destroy_range(this->begin(), this->end());
463}
464
465// Define this out-of-line to dissuade the C++ compiler from inlining it.
466template <typename T, bool TriviallyCopyable>
468 T *NewElts, size_t NewCapacity) {
469 // If this wasn't grown from the inline copy, deallocate the old space.
470 if (!this->isSmall())
471 free(this->begin());
472
473 this->set_allocation_range(NewElts, NewCapacity);
474}
475
476/// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put
477/// method implementations that are designed to work with trivially copyable
478/// T's. This allows using memcpy in place of copy/move construction and
479/// skipping destruction.
480template <typename T>
482 friend class SmallVectorTemplateCommon<T>;
483
484protected:
485 /// True if it's cheap enough to take parameters by value. Doing so avoids
486 /// overhead related to mitigations for reference invalidation.
487 static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
488
489 /// Either const T& or T, depending on whether it's cheap enough to take
490 /// parameters by value.
491 using ValueParamT = std::conditional_t<TakesParamByValue, T, const T &>;
492
494
495 // No need to do a destroy loop for POD's.
496 static void destroy_range(T *, T *) {}
497
498 /// Move the range [I, E) onto the uninitialized memory
499 /// starting with "Dest", constructing elements into it as needed.
500 template<typename It1, typename It2>
501 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
502 // Just do a copy.
503 uninitialized_copy(I, E, Dest);
504 }
505
506 /// Copy the range [I, E) onto the uninitialized memory
507 /// starting with "Dest", constructing elements into it as needed.
508 template <typename It1, typename It2>
509 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
510 if constexpr (std::is_pointer_v<It1> && std::is_pointer_v<It2> &&
511 std::is_same_v<
512 std::remove_const_t<std::remove_pointer_t<It1>>,
513 std::remove_pointer_t<It2>>) {
514 // Use memcpy for PODs iterated by pointers (which includes SmallVector
515 // iterators): std::uninitialized_copy optimizes to memmove, but we can
516 // use memcpy here. Note that I and E are iterators and thus might be
517 // invalid for memcpy if they are equal.
518 if (I != E)
519 std::memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
520 } else {
521 // Arbitrary iterator types; just use the basic implementation.
522 std::uninitialized_copy(I, E, Dest);
523 }
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
740 template <typename U,
741 typename = std::enable_if_t<std::is_convertible_v<U, T>>>
743 assign(AR.begin(), AR.end());
744 }
745
747 // Just cast away constness because this is a non-const member function.
748 iterator I = const_cast<iterator>(CI);
749
750 assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds.");
751
752 iterator N = I;
753 // Shift all elts down one.
754 std::move(I+1, this->end(), I);
755 // Drop the last elt.
756 this->pop_back();
757 return(N);
758 }
759
761 // Just cast away constness because this is a non-const member function.
762 iterator S = const_cast<iterator>(CS);
763 iterator E = const_cast<iterator>(CE);
764
765 assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds.");
766
767 iterator N = S;
768 // Shift all elts down.
769 iterator I = std::move(E, this->end(), S);
770 // Drop the last elts.
771 this->destroy_range(I, this->end());
772 this->set_size(I - this->begin());
773 return(N);
774 }
775
776private:
777 template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) {
778 // Callers ensure that ArgType is derived from T.
779 static_assert(
780 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
781 T>::value,
782 "ArgType must be derived from T!");
783
784 if (I == this->end()) { // Important special case for empty vector.
785 this->push_back(::std::forward<ArgType>(Elt));
786 return this->end()-1;
787 }
788
789 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
790
791 // Grow if necessary.
792 size_t Index = I - this->begin();
793 std::remove_reference_t<ArgType> *EltPtr =
795 I = this->begin() + Index;
796
797 ::new ((void*) this->end()) T(::std::move(this->back()));
798 // Push everything else over.
799 std::move_backward(I, this->end()-1, this->end());
800 this->set_size(this->size() + 1);
801
802 // If we just moved the element we're inserting, be sure to update
803 // the reference (never happens if TakesParamByValue).
804 static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
805 "ArgType must be 'T' when taking by value!");
806 if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end()))
807 ++EltPtr;
808
809 *I = ::std::forward<ArgType>(*EltPtr);
810 return I;
811 }
812
813public:
815 return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
816 }
817
818 iterator insert(iterator I, const T &Elt) {
819 return insert_one_impl(I, this->forward_value_param(Elt));
820 }
821
823 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
824 size_t InsertElt = I - this->begin();
825
826 if (I == this->end()) { // Important special case for empty vector.
827 append(NumToInsert, Elt);
828 return this->begin()+InsertElt;
829 }
830
831 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
832
833 // Ensure there is enough space, and get the (maybe updated) address of
834 // Elt.
835 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
836
837 // Uninvalidate the iterator.
838 I = this->begin()+InsertElt;
839
840 // If there are more elements between the insertion point and the end of the
841 // range than there are being inserted, we can use a simple approach to
842 // insertion. Since we already reserved space, we know that this won't
843 // reallocate the vector.
844 if (size_t(this->end()-I) >= NumToInsert) {
845 T *OldEnd = this->end();
846 append(std::move_iterator<iterator>(this->end() - NumToInsert),
847 std::move_iterator<iterator>(this->end()));
848
849 // Copy the existing elements that get replaced.
850 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
851
852 // If we just moved the element we're inserting, be sure to update
853 // the reference (never happens if TakesParamByValue).
854 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
855 EltPtr += NumToInsert;
856
857 std::fill_n(I, NumToInsert, *EltPtr);
858 return I;
859 }
860
861 // Otherwise, we're inserting more elements than exist already, and we're
862 // not inserting at the end.
863
864 // Move over the elements that we're about to overwrite.
865 T *OldEnd = this->end();
866 this->set_size(this->size() + NumToInsert);
867 size_t NumOverwritten = OldEnd-I;
868 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
869
870 // If we just moved the element we're inserting, be sure to update
871 // the reference (never happens if TakesParamByValue).
872 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
873 EltPtr += NumToInsert;
874
875 // Replace the overwritten part.
876 std::fill_n(I, NumOverwritten, *EltPtr);
877
878 // Insert the non-overwritten middle part.
879 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
880 return I;
881 }
882
883 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
885 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
886 size_t InsertElt = I - this->begin();
887
888 if (I == this->end()) { // Important special case for empty vector.
889 append(From, To);
890 return this->begin()+InsertElt;
891 }
892
893 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
894
895 // Check that the reserve that follows doesn't invalidate the iterators.
896 this->assertSafeToAddRange(From, To);
897
898 size_t NumToInsert = std::distance(From, To);
899
900 // Ensure there is enough space.
901 reserve(this->size() + NumToInsert);
902
903 // Uninvalidate the iterator.
904 I = this->begin()+InsertElt;
905
906 // If there are more elements between the insertion point and the end of the
907 // range than there are being inserted, we can use a simple approach to
908 // insertion. Since we already reserved space, we know that this won't
909 // reallocate the vector.
910 if (size_t(this->end()-I) >= NumToInsert) {
911 T *OldEnd = this->end();
912 append(std::move_iterator<iterator>(this->end() - NumToInsert),
913 std::move_iterator<iterator>(this->end()));
914
915 // Copy the existing elements that get replaced.
916 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
917
918 std::copy(From, To, I);
919 return I;
920 }
921
922 // Otherwise, we're inserting more elements than exist already, and we're
923 // not inserting at the end.
924
925 // Move over the elements that we're about to overwrite.
926 T *OldEnd = this->end();
927 this->set_size(this->size() + NumToInsert);
928 size_t NumOverwritten = OldEnd-I;
929 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
930
931 // Replace the overwritten part.
932 for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
933 *J = *From;
934 ++J; ++From;
935 }
936
937 // Insert the non-overwritten middle part.
938 this->uninitialized_copy(From, To, OldEnd);
939 return I;
940 }
941
942 void insert(iterator I, std::initializer_list<T> IL) {
943 insert(I, IL.begin(), IL.end());
944 }
945
946 template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
947 if (LLVM_UNLIKELY(this->size() >= this->capacity()))
948 return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...);
949
950 ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
951 this->set_size(this->size() + 1);
952 return this->back();
953 }
954
956
958
959 bool operator==(const SmallVectorImpl &RHS) const {
960 if (this->size() != RHS.size()) return false;
961 return std::equal(this->begin(), this->end(), RHS.begin());
962 }
963 bool operator!=(const SmallVectorImpl &RHS) const {
964 return !(*this == RHS);
965 }
966
967 bool operator<(const SmallVectorImpl &RHS) const {
968 return std::lexicographical_compare(this->begin(), this->end(),
969 RHS.begin(), RHS.end());
970 }
971 bool operator>(const SmallVectorImpl &RHS) const { return RHS < *this; }
972 bool operator<=(const SmallVectorImpl &RHS) const { return !(*this > RHS); }
973 bool operator>=(const SmallVectorImpl &RHS) const { return !(*this < RHS); }
974};
975
976template <typename T>
978 if (this == &RHS) return;
979
980 // We can only avoid copying elements if neither vector is small.
981 if (!this->isSmall() && !RHS.isSmall()) {
982 std::swap(this->BeginX, RHS.BeginX);
983 std::swap(this->Size, RHS.Size);
984 std::swap(this->Capacity, RHS.Capacity);
985 return;
986 }
987 this->reserve(RHS.size());
988 RHS.reserve(this->size());
989
990 // Swap the shared elements.
991 size_t NumShared = this->size();
992 if (NumShared > RHS.size()) NumShared = RHS.size();
993 for (size_type i = 0; i != NumShared; ++i)
994 std::swap((*this)[i], RHS[i]);
995
996 // Copy over the extra elts.
997 if (this->size() > RHS.size()) {
998 size_t EltDiff = this->size() - RHS.size();
999 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
1000 RHS.set_size(RHS.size() + EltDiff);
1001 this->destroy_range(this->begin()+NumShared, this->end());
1002 this->set_size(NumShared);
1003 } else if (RHS.size() > this->size()) {
1004 size_t EltDiff = RHS.size() - this->size();
1005 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
1006 this->set_size(this->size() + EltDiff);
1007 this->destroy_range(RHS.begin()+NumShared, RHS.end());
1008 RHS.set_size(NumShared);
1009 }
1010}
1011
1012template <typename T>
1015 // Avoid self-assignment.
1016 if (this == &RHS) return *this;
1017
1018 // If we already have sufficient space, assign the common elements, then
1019 // destroy any excess.
1020 size_t RHSSize = RHS.size();
1021 size_t CurSize = this->size();
1022 if (CurSize >= RHSSize) {
1023 // Assign common elements.
1024 iterator NewEnd;
1025 if (RHSSize)
1026 NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
1027 else
1028 NewEnd = this->begin();
1029
1030 // Destroy excess elements.
1031 this->destroy_range(NewEnd, this->end());
1032
1033 // Trim.
1034 this->set_size(RHSSize);
1035 return *this;
1036 }
1037
1038 // If we have to grow to have enough elements, destroy the current elements.
1039 // This allows us to avoid copying them during the grow.
1040 // FIXME: don't do this if they're efficiently moveable.
1041 if (this->capacity() < RHSSize) {
1042 // Destroy current elements.
1043 this->clear();
1044 CurSize = 0;
1045 this->grow(RHSSize);
1046 } else if (CurSize) {
1047 // Otherwise, use assignment for the already-constructed elements.
1048 std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
1049 }
1050
1051 // Copy construct the new elements in place.
1052 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
1053 this->begin()+CurSize);
1054
1055 // Set end.
1056 this->set_size(RHSSize);
1057 return *this;
1058}
1059
1060template <typename T>
1062 // Avoid self-assignment.
1063 if (this == &RHS) return *this;
1064
1065 // If the RHS isn't small, clear this vector and then steal its buffer.
1066 if (!RHS.isSmall()) {
1067 this->assignRemote(std::move(RHS));
1068 return *this;
1069 }
1070
1071 // If we already have sufficient space, assign the common elements, then
1072 // destroy any excess.
1073 size_t RHSSize = RHS.size();
1074 size_t CurSize = this->size();
1075 if (CurSize >= RHSSize) {
1076 // Assign common elements.
1077 iterator NewEnd = this->begin();
1078 if (RHSSize)
1079 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
1080
1081 // Destroy excess elements and trim the bounds.
1082 this->destroy_range(NewEnd, this->end());
1083 this->set_size(RHSSize);
1084
1085 // Clear the RHS.
1086 RHS.clear();
1087
1088 return *this;
1089 }
1090
1091 // If we have to grow to have enough elements, destroy the current elements.
1092 // This allows us to avoid copying them during the grow.
1093 // FIXME: this may not actually make any sense if we can efficiently move
1094 // elements.
1095 if (this->capacity() < RHSSize) {
1096 // Destroy current elements.
1097 this->clear();
1098 CurSize = 0;
1099 this->grow(RHSSize);
1100 } else if (CurSize) {
1101 // Otherwise, use assignment for the already-constructed elements.
1102 std::move(RHS.begin(), RHS.begin()+CurSize, this->begin());
1103 }
1104
1105 // Move-construct the new elements in place.
1106 this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
1107 this->begin()+CurSize);
1108
1109 // Set end.
1110 this->set_size(RHSSize);
1111
1112 RHS.clear();
1113 return *this;
1114}
1115
1116/// Storage for the SmallVector elements. This is specialized for the N=0 case
1117/// to avoid allocating unnecessary storage.
1118template <typename T, unsigned N>
1120 alignas(T) char InlineElts[N * sizeof(T)];
1121};
1122
1123/// We need the storage to be properly aligned even for small-size of 0 so that
1124/// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is
1125/// well-defined.
1126template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
1127
1128/// Forward declaration of SmallVector so that
1129/// calculateSmallVectorDefaultInlinedElements can reference
1130/// `sizeof(SmallVector<T, 0>)`.
1131template <typename T, unsigned N> class LLVM_GSL_OWNER SmallVector;
1132
1133/// Helper class for calculating the default number of inline elements for
1134/// `SmallVector<T>`.
1135///
1136/// This should be migrated to a constexpr function when our minimum
1137/// compiler support is enough for multi-statement constexpr functions.
1139 // Parameter controlling the default number of inlined elements
1140 // for `SmallVector<T>`.
1141 //
1142 // The default number of inlined elements ensures that
1143 // 1. There is at least one inlined element.
1144 // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless
1145 // it contradicts 1.
1146 static constexpr size_t kPreferredSmallVectorSizeof = 64;
1147
1148 // static_assert that sizeof(T) is not "too big".
1149 //
1150 // Because our policy guarantees at least one inlined element, it is possible
1151 // for an arbitrarily large inlined element to allocate an arbitrarily large
1152 // amount of inline storage. We generally consider it an antipattern for a
1153 // SmallVector to allocate an excessive amount of inline storage, so we want
1154 // to call attention to these cases and make sure that users are making an
1155 // intentional decision if they request a lot of inline storage.
1156 //
1157 // We want this assertion to trigger in pathological cases, but otherwise
1158 // not be too easy to hit. To accomplish that, the cutoff is actually somewhat
1159 // larger than kPreferredSmallVectorSizeof (otherwise,
1160 // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that
1161 // pattern seems useful in practice).
1162 //
1163 // One wrinkle is that this assertion is in theory non-portable, since
1164 // sizeof(T) is in general platform-dependent. However, we don't expect this
1165 // to be much of an issue, because most LLVM development happens on 64-bit
1166 // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for
1167 // 32-bit hosts, dodging the issue. The reverse situation, where development
1168 // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a
1169 // 64-bit host, is expected to be very rare.
1170 static_assert(
1171 sizeof(T) <= 256,
1172 "You are trying to use a default number of inlined elements for "
1173 "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
1174 "explicit number of inlined elements with `SmallVector<T, N>` to make "
1175 "sure you really want that much inline storage.");
1176
1177 // Discount the size of the header itself when calculating the maximum inline
1178 // bytes.
1179 static constexpr size_t PreferredInlineBytes =
1181 static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T);
1182 static constexpr size_t value =
1184};
1185
1186/// This is a 'vector' (really, a variable-sized array), optimized
1187/// for the case when the array is small. It contains some number of elements
1188/// in-place, which allows it to avoid heap allocation when the actual number of
1189/// elements is below that threshold. This allows normal "small" cases to be
1190/// fast without losing generality for large inputs.
1191///
1192/// \note
1193/// In the absence of a well-motivated choice for the number of inlined
1194/// elements \p N, it is recommended to use \c SmallVector<T> (that is,
1195/// omitting the \p N). This will choose a default number of inlined elements
1196/// reasonable for allocation on the stack (for example, trying to keep \c
1197/// sizeof(SmallVector<T>) around 64 bytes).
1198///
1199/// \warning This does not attempt to be exception safe.
1200///
1201/// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
1202template <typename T,
1205 SmallVectorStorage<T, N> {
1206public:
1208
1210 // Destroy the constructed elements in the vector.
1211 this->destroy_range(this->begin(), this->end());
1212 }
1213
1214 explicit SmallVector(size_t Size)
1215 : SmallVectorImpl<T>(N) {
1216 this->resize(Size);
1217 }
1218
1219 SmallVector(size_t Size, const T &Value)
1220 : SmallVectorImpl<T>(N) {
1221 this->assign(Size, Value);
1222 }
1223
1224 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
1226 this->append(S, E);
1227 }
1228
1229 template <typename RangeTy>
1231 : SmallVectorImpl<T>(N) {
1232 this->append(R.begin(), R.end());
1233 }
1234
1235 SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
1236 this->append(IL);
1237 }
1238
1239 template <typename U,
1240 typename = std::enable_if_t<std::is_convertible_v<U, T>>>
1242 this->append(A.begin(), A.end());
1243 }
1244
1246 if (!RHS.empty())
1248 }
1249
1252 return *this;
1253 }
1254
1256 if (!RHS.empty())
1257 SmallVectorImpl<T>::operator=(::std::move(RHS));
1258 }
1259
1261 if (!RHS.empty())
1262 SmallVectorImpl<T>::operator=(::std::move(RHS));
1263 }
1264
1266 if (N) {
1267 SmallVectorImpl<T>::operator=(::std::move(RHS));
1268 return *this;
1269 }
1270 // SmallVectorImpl<T>::operator= does not leverage N==0. Optimize the
1271 // case.
1272 if (this == &RHS)
1273 return *this;
1274 if (RHS.empty()) {
1275 this->destroy_range(this->begin(), this->end());
1276 this->Size = 0;
1277 } else {
1278 this->assignRemote(std::move(RHS));
1279 }
1280 return *this;
1281 }
1282
1284 SmallVectorImpl<T>::operator=(::std::move(RHS));
1285 return *this;
1286 }
1287
1288 SmallVector &operator=(std::initializer_list<T> IL) {
1289 this->assign(IL);
1290 return *this;
1291 }
1292};
1293
1294template <typename T, unsigned N>
1296 return X.capacity_in_bytes();
1297}
1298
1299template <typename RangeType>
1301 std::remove_const_t<detail::ValueOfRange<RangeType>>;
1302
1303/// Given a range of type R, iterate the entire range and return a
1304/// SmallVector with elements of the vector. This is useful, for example,
1305/// when you want to iterate a range and then sort the results.
1306template <unsigned Size, typename R>
1310template <typename R>
1314
1315template <typename Out, unsigned Size, typename R>
1319
1320template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
1321 return {adl_begin(Range), adl_end(Range)};
1322}
1323
1324// Explicit instantiations
1325extern template class llvm::SmallVectorBase<uint32_t>;
1326#if SIZE_MAX > UINT32_MAX
1327extern template class llvm::SmallVectorBase<uint64_t>;
1328#endif
1329
1330// Provide DenseMapInfo for SmallVector of a type which has info.
1331template <typename T, unsigned N> struct DenseMapInfo<llvm::SmallVector<T, N>> {
1335
1339
1340 static unsigned getHashValue(const SmallVector<T, N> &V) {
1341 return static_cast<unsigned>(hash_combine_range(V));
1342 }
1343
1344 static bool isEqual(const SmallVector<T, N> &LHS,
1345 const SmallVector<T, N> &RHS) {
1346 return LHS == RHS;
1347 }
1348};
1349
1350} // end namespace llvm
1351
1352namespace std {
1353
1354 /// Implement std::swap in terms of SmallVector swap.
1355 template<typename T>
1356 inline void
1360
1361 /// Implement std::swap in terms of SmallVector swap.
1362 template<typename T, unsigned N>
1363 inline void
1367
1368} // end namespace std
1369
1370#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:57
#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:40
iterator end() const
Definition ArrayRef.h:131
iterator begin() const
Definition ArrayRef.h:130
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.
Definition Types.h:26
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:847
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:74
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:1915
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)]