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