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