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

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