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