File indexing completed on 2026-05-10 08:43:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_ADT_SMALLVECTOR_H
0015 #define LLVM_ADT_SMALLVECTOR_H
0016
0017 #include "llvm/Support/Compiler.h"
0018 #include <algorithm>
0019 #include <cassert>
0020 #include <cstddef>
0021 #include <cstdint>
0022 #include <cstdlib>
0023 #include <cstring>
0024 #include <functional>
0025 #include <initializer_list>
0026 #include <iterator>
0027 #include <limits>
0028 #include <memory>
0029 #include <new>
0030 #include <type_traits>
0031 #include <utility>
0032
0033 namespace llvm {
0034
0035 template <typename T> class ArrayRef;
0036
0037 template <typename IteratorT> class iterator_range;
0038
0039 template <class Iterator>
0040 using EnableIfConvertibleToInputIterator = std::enable_if_t<std::is_convertible<
0041 typename std::iterator_traits<Iterator>::iterator_category,
0042 std::input_iterator_tag>::value>;
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 template <class Size_T> class SmallVectorBase {
0053 protected:
0054 void *BeginX;
0055 Size_T Size = 0, Capacity;
0056
0057
0058 static constexpr size_t SizeTypeMax() {
0059 return std::numeric_limits<Size_T>::max();
0060 }
0061
0062 SmallVectorBase() = delete;
0063 SmallVectorBase(void *FirstEl, size_t TotalCapacity)
0064 : BeginX(FirstEl), Capacity(static_cast<Size_T>(TotalCapacity)) {}
0065
0066
0067
0068
0069 void *mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize,
0070 size_t &NewCapacity);
0071
0072
0073
0074
0075 void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
0076
0077 public:
0078 size_t size() const { return Size; }
0079 size_t capacity() const { return Capacity; }
0080
0081 [[nodiscard]] bool empty() const { return !Size; }
0082
0083 protected:
0084
0085
0086
0087
0088 void set_size(size_t N) {
0089 assert(N <= capacity());
0090 Size = static_cast<Size_T>(N);
0091 }
0092
0093
0094
0095
0096
0097 void set_allocation_range(void *Begin, size_t N) {
0098 assert(N <= SizeTypeMax());
0099 BeginX = Begin;
0100 Capacity = static_cast<Size_T>(N);
0101 }
0102 };
0103
0104 template <class T>
0105 using SmallVectorSizeType =
0106 std::conditional_t<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t,
0107 uint32_t>;
0108
0109
0110 template <class T, typename = void> struct SmallVectorAlignmentAndSize {
0111 alignas(SmallVectorBase<SmallVectorSizeType<T>>) char Base[sizeof(
0112 SmallVectorBase<SmallVectorSizeType<T>>)];
0113 alignas(T) char FirstEl[sizeof(T)];
0114 };
0115
0116
0117
0118
0119 template <typename T, typename = void>
0120 class SmallVectorTemplateCommon
0121 : public SmallVectorBase<SmallVectorSizeType<T>> {
0122 using Base = SmallVectorBase<SmallVectorSizeType<T>>;
0123
0124 protected:
0125
0126
0127
0128 void *getFirstEl() const {
0129 return const_cast<void *>(reinterpret_cast<const void *>(
0130 reinterpret_cast<const char *>(this) +
0131 offsetof(SmallVectorAlignmentAndSize<T>, FirstEl)));
0132 }
0133
0134
0135 SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {}
0136
0137 void grow_pod(size_t MinSize, size_t TSize) {
0138 Base::grow_pod(getFirstEl(), MinSize, TSize);
0139 }
0140
0141
0142
0143 bool isSmall() const { return this->BeginX == getFirstEl(); }
0144
0145
0146 void resetToSmall() {
0147 this->BeginX = getFirstEl();
0148 this->Size = this->Capacity = 0;
0149 }
0150
0151
0152 bool isReferenceToRange(const void *V, const void *First, const void *Last) const {
0153
0154 std::less<> LessThan;
0155 return !LessThan(V, First) && LessThan(V, Last);
0156 }
0157
0158
0159 bool isReferenceToStorage(const void *V) const {
0160 return isReferenceToRange(V, this->begin(), this->end());
0161 }
0162
0163
0164
0165 bool isRangeInStorage(const void *First, const void *Last) const {
0166
0167 std::less<> LessThan;
0168 return !LessThan(First, this->begin()) && !LessThan(Last, First) &&
0169 !LessThan(this->end(), Last);
0170 }
0171
0172
0173
0174 bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
0175
0176 if (LLVM_LIKELY(!isReferenceToStorage(Elt)))
0177 return true;
0178
0179
0180 if (NewSize <= this->size())
0181 return Elt < this->begin() + NewSize;
0182
0183
0184 return NewSize <= this->capacity();
0185 }
0186
0187
0188 void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
0189 assert(isSafeToReferenceAfterResize(Elt, NewSize) &&
0190 "Attempting to reference an element of the vector in an operation "
0191 "that invalidates it");
0192 }
0193
0194
0195
0196 void assertSafeToAdd(const void *Elt, size_t N = 1) {
0197 this->assertSafeToReferenceAfterResize(Elt, this->size() + N);
0198 }
0199
0200
0201 void assertSafeToReferenceAfterClear(const T *From, const T *To) {
0202 if (From == To)
0203 return;
0204 this->assertSafeToReferenceAfterResize(From, 0);
0205 this->assertSafeToReferenceAfterResize(To - 1, 0);
0206 }
0207 template <
0208 class ItTy,
0209 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
0210 bool> = false>
0211 void assertSafeToReferenceAfterClear(ItTy, ItTy) {}
0212
0213
0214 void assertSafeToAddRange(const T *From, const T *To) {
0215 if (From == To)
0216 return;
0217 this->assertSafeToAdd(From, To - From);
0218 this->assertSafeToAdd(To - 1, To - From);
0219 }
0220 template <
0221 class ItTy,
0222 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
0223 bool> = false>
0224 void assertSafeToAddRange(ItTy, ItTy) {}
0225
0226
0227
0228 template <class U>
0229 static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt,
0230 size_t N) {
0231 size_t NewSize = This->size() + N;
0232 if (LLVM_LIKELY(NewSize <= This->capacity()))
0233 return &Elt;
0234
0235 bool ReferencesStorage = false;
0236 int64_t Index = -1;
0237 if (!U::TakesParamByValue) {
0238 if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
0239 ReferencesStorage = true;
0240 Index = &Elt - This->begin();
0241 }
0242 }
0243 This->grow(NewSize);
0244 return ReferencesStorage ? This->begin() + Index : &Elt;
0245 }
0246
0247 public:
0248 using size_type = size_t;
0249 using difference_type = ptrdiff_t;
0250 using value_type = T;
0251 using iterator = T *;
0252 using const_iterator = const T *;
0253
0254 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0255 using reverse_iterator = std::reverse_iterator<iterator>;
0256
0257 using reference = T &;
0258 using const_reference = const T &;
0259 using pointer = T *;
0260 using const_pointer = const T *;
0261
0262 using Base::capacity;
0263 using Base::empty;
0264 using Base::size;
0265
0266
0267 iterator begin() { return (iterator)this->BeginX; }
0268 const_iterator begin() const { return (const_iterator)this->BeginX; }
0269 iterator end() { return begin() + size(); }
0270 const_iterator end() const { return begin() + size(); }
0271
0272
0273 reverse_iterator rbegin() { return reverse_iterator(end()); }
0274 const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
0275 reverse_iterator rend() { return reverse_iterator(begin()); }
0276 const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
0277
0278 size_type size_in_bytes() const { return size() * sizeof(T); }
0279 size_type max_size() const {
0280 return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T));
0281 }
0282
0283 size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
0284
0285
0286 pointer data() { return pointer(begin()); }
0287
0288 const_pointer data() const { return const_pointer(begin()); }
0289
0290 reference operator[](size_type idx) {
0291 assert(idx < size());
0292 return begin()[idx];
0293 }
0294 const_reference operator[](size_type idx) const {
0295 assert(idx < size());
0296 return begin()[idx];
0297 }
0298
0299 reference front() {
0300 assert(!empty());
0301 return begin()[0];
0302 }
0303 const_reference front() const {
0304 assert(!empty());
0305 return begin()[0];
0306 }
0307
0308 reference back() {
0309 assert(!empty());
0310 return end()[-1];
0311 }
0312 const_reference back() const {
0313 assert(!empty());
0314 return end()[-1];
0315 }
0316 };
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326 template <typename T, bool = (std::is_trivially_copy_constructible<T>::value) &&
0327 (std::is_trivially_move_constructible<T>::value) &&
0328 std::is_trivially_destructible<T>::value>
0329 class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
0330 friend class SmallVectorTemplateCommon<T>;
0331
0332 protected:
0333 static constexpr bool TakesParamByValue = false;
0334 using ValueParamT = const T &;
0335
0336 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
0337
0338 static void destroy_range(T *S, T *E) {
0339 while (S != E) {
0340 --E;
0341 E->~T();
0342 }
0343 }
0344
0345
0346
0347 template<typename It1, typename It2>
0348 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
0349 std::uninitialized_move(I, E, Dest);
0350 }
0351
0352
0353
0354 template<typename It1, typename It2>
0355 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
0356 std::uninitialized_copy(I, E, Dest);
0357 }
0358
0359
0360
0361
0362 void grow(size_t MinSize = 0);
0363
0364
0365
0366 T *mallocForGrow(size_t MinSize, size_t &NewCapacity);
0367
0368
0369
0370 void moveElementsForGrow(T *NewElts);
0371
0372
0373 void takeAllocationForGrow(T *NewElts, size_t NewCapacity);
0374
0375
0376
0377 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
0378 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
0379 }
0380
0381
0382
0383 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
0384 return const_cast<T *>(
0385 this->reserveForParamAndGetAddressImpl(this, Elt, N));
0386 }
0387
0388 static T &&forward_value_param(T &&V) { return std::move(V); }
0389 static const T &forward_value_param(const T &V) { return V; }
0390
0391 void growAndAssign(size_t NumElts, const T &Elt) {
0392
0393 size_t NewCapacity;
0394 T *NewElts = mallocForGrow(NumElts, NewCapacity);
0395 std::uninitialized_fill_n(NewElts, NumElts, Elt);
0396 this->destroy_range(this->begin(), this->end());
0397 takeAllocationForGrow(NewElts, NewCapacity);
0398 this->set_size(NumElts);
0399 }
0400
0401 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
0402
0403 size_t NewCapacity;
0404 T *NewElts = mallocForGrow(0, NewCapacity);
0405 ::new ((void *)(NewElts + this->size())) T(std::forward<ArgTypes>(Args)...);
0406 moveElementsForGrow(NewElts);
0407 takeAllocationForGrow(NewElts, NewCapacity);
0408 this->set_size(this->size() + 1);
0409 return this->back();
0410 }
0411
0412 public:
0413 void push_back(const T &Elt) {
0414 const T *EltPtr = reserveForParamAndGetAddress(Elt);
0415 ::new ((void *)this->end()) T(*EltPtr);
0416 this->set_size(this->size() + 1);
0417 }
0418
0419 void push_back(T &&Elt) {
0420 T *EltPtr = reserveForParamAndGetAddress(Elt);
0421 ::new ((void *)this->end()) T(::std::move(*EltPtr));
0422 this->set_size(this->size() + 1);
0423 }
0424
0425 void pop_back() {
0426 this->set_size(this->size() - 1);
0427 this->end()->~T();
0428 }
0429 };
0430
0431
0432 template <typename T, bool TriviallyCopyable>
0433 void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
0434 size_t NewCapacity;
0435 T *NewElts = mallocForGrow(MinSize, NewCapacity);
0436 moveElementsForGrow(NewElts);
0437 takeAllocationForGrow(NewElts, NewCapacity);
0438 }
0439
0440 template <typename T, bool TriviallyCopyable>
0441 T *SmallVectorTemplateBase<T, TriviallyCopyable>::mallocForGrow(
0442 size_t MinSize, size_t &NewCapacity) {
0443 return static_cast<T *>(
0444 SmallVectorBase<SmallVectorSizeType<T>>::mallocForGrow(
0445 this->getFirstEl(), MinSize, sizeof(T), NewCapacity));
0446 }
0447
0448
0449 template <typename T, bool TriviallyCopyable>
0450 void SmallVectorTemplateBase<T, TriviallyCopyable>::moveElementsForGrow(
0451 T *NewElts) {
0452
0453 this->uninitialized_move(this->begin(), this->end(), NewElts);
0454
0455
0456 destroy_range(this->begin(), this->end());
0457 }
0458
0459
0460 template <typename T, bool TriviallyCopyable>
0461 void SmallVectorTemplateBase<T, TriviallyCopyable>::takeAllocationForGrow(
0462 T *NewElts, size_t NewCapacity) {
0463
0464 if (!this->isSmall())
0465 free(this->begin());
0466
0467 this->set_allocation_range(NewElts, NewCapacity);
0468 }
0469
0470
0471
0472
0473
0474 template <typename T>
0475 class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
0476 friend class SmallVectorTemplateCommon<T>;
0477
0478 protected:
0479
0480
0481 static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
0482
0483
0484
0485 using ValueParamT = std::conditional_t<TakesParamByValue, T, const T &>;
0486
0487 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
0488
0489
0490 static void destroy_range(T *, T *) {}
0491
0492
0493
0494 template<typename It1, typename It2>
0495 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
0496
0497 uninitialized_copy(I, E, Dest);
0498 }
0499
0500
0501
0502 template<typename It1, typename It2>
0503 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
0504
0505 std::uninitialized_copy(I, E, Dest);
0506 }
0507
0508
0509
0510 template <typename T1, typename T2>
0511 static void uninitialized_copy(
0512 T1 *I, T1 *E, T2 *Dest,
0513 std::enable_if_t<std::is_same<std::remove_const_t<T1>, T2>::value> * =
0514 nullptr) {
0515
0516
0517
0518
0519 if (I != E)
0520 memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
0521 }
0522
0523
0524
0525 void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); }
0526
0527
0528
0529 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
0530 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
0531 }
0532
0533
0534
0535 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
0536 return const_cast<T *>(
0537 this->reserveForParamAndGetAddressImpl(this, Elt, N));
0538 }
0539
0540
0541 static ValueParamT forward_value_param(ValueParamT V) { return V; }
0542
0543 void growAndAssign(size_t NumElts, T Elt) {
0544
0545
0546 this->set_size(0);
0547 this->grow(NumElts);
0548 std::uninitialized_fill_n(this->begin(), NumElts, Elt);
0549 this->set_size(NumElts);
0550 }
0551
0552 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
0553
0554
0555
0556 push_back(T(std::forward<ArgTypes>(Args)...));
0557 return this->back();
0558 }
0559
0560 public:
0561 void push_back(ValueParamT Elt) {
0562 const T *EltPtr = reserveForParamAndGetAddress(Elt);
0563 memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
0564 this->set_size(this->size() + 1);
0565 }
0566
0567 void pop_back() { this->set_size(this->size() - 1); }
0568 };
0569
0570
0571
0572 template <typename T>
0573 class SmallVectorImpl : public SmallVectorTemplateBase<T> {
0574 using SuperClass = SmallVectorTemplateBase<T>;
0575
0576 public:
0577 using iterator = typename SuperClass::iterator;
0578 using const_iterator = typename SuperClass::const_iterator;
0579 using reference = typename SuperClass::reference;
0580 using size_type = typename SuperClass::size_type;
0581
0582 protected:
0583 using SmallVectorTemplateBase<T>::TakesParamByValue;
0584 using ValueParamT = typename SuperClass::ValueParamT;
0585
0586
0587 explicit SmallVectorImpl(unsigned N)
0588 : SmallVectorTemplateBase<T>(N) {}
0589
0590 void assignRemote(SmallVectorImpl &&RHS) {
0591 this->destroy_range(this->begin(), this->end());
0592 if (!this->isSmall())
0593 free(this->begin());
0594 this->BeginX = RHS.BeginX;
0595 this->Size = RHS.Size;
0596 this->Capacity = RHS.Capacity;
0597 RHS.resetToSmall();
0598 }
0599
0600 ~SmallVectorImpl() {
0601
0602
0603 if (!this->isSmall())
0604 free(this->begin());
0605 }
0606
0607 public:
0608 SmallVectorImpl(const SmallVectorImpl &) = delete;
0609
0610 void clear() {
0611 this->destroy_range(this->begin(), this->end());
0612 this->Size = 0;
0613 }
0614
0615 private:
0616
0617 using SuperClass::set_size;
0618
0619 template <bool ForOverwrite> void resizeImpl(size_type N) {
0620 if (N == this->size())
0621 return;
0622
0623 if (N < this->size()) {
0624 this->truncate(N);
0625 return;
0626 }
0627
0628 this->reserve(N);
0629 for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
0630 if (ForOverwrite)
0631 new (&*I) T;
0632 else
0633 new (&*I) T();
0634 this->set_size(N);
0635 }
0636
0637 public:
0638 void resize(size_type N) { resizeImpl<false>(N); }
0639
0640
0641 void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
0642
0643
0644 void truncate(size_type N) {
0645 assert(this->size() >= N && "Cannot increase size with truncate");
0646 this->destroy_range(this->begin() + N, this->end());
0647 this->set_size(N);
0648 }
0649
0650 void resize(size_type N, ValueParamT NV) {
0651 if (N == this->size())
0652 return;
0653
0654 if (N < this->size()) {
0655 this->truncate(N);
0656 return;
0657 }
0658
0659
0660 this->append(N - this->size(), NV);
0661 }
0662
0663 void reserve(size_type N) {
0664 if (this->capacity() < N)
0665 this->grow(N);
0666 }
0667
0668 void pop_back_n(size_type NumItems) {
0669 assert(this->size() >= NumItems);
0670 truncate(this->size() - NumItems);
0671 }
0672
0673 [[nodiscard]] T pop_back_val() {
0674 T Result = ::std::move(this->back());
0675 this->pop_back();
0676 return Result;
0677 }
0678
0679 void swap(SmallVectorImpl &RHS);
0680
0681
0682 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
0683 void append(ItTy in_start, ItTy in_end) {
0684 this->assertSafeToAddRange(in_start, in_end);
0685 size_type NumInputs = std::distance(in_start, in_end);
0686 this->reserve(this->size() + NumInputs);
0687 this->uninitialized_copy(in_start, in_end, this->end());
0688 this->set_size(this->size() + NumInputs);
0689 }
0690
0691
0692 void append(size_type NumInputs, ValueParamT Elt) {
0693 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
0694 std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr);
0695 this->set_size(this->size() + NumInputs);
0696 }
0697
0698 void append(std::initializer_list<T> IL) {
0699 append(IL.begin(), IL.end());
0700 }
0701
0702 void append(const SmallVectorImpl &RHS) { append(RHS.begin(), RHS.end()); }
0703
0704 void assign(size_type NumElts, ValueParamT Elt) {
0705
0706 if (NumElts > this->capacity()) {
0707 this->growAndAssign(NumElts, Elt);
0708 return;
0709 }
0710
0711
0712 std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt);
0713 if (NumElts > this->size())
0714 std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt);
0715 else if (NumElts < this->size())
0716 this->destroy_range(this->begin() + NumElts, this->end());
0717 this->set_size(NumElts);
0718 }
0719
0720
0721
0722
0723 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
0724 void assign(ItTy in_start, ItTy in_end) {
0725 this->assertSafeToReferenceAfterClear(in_start, in_end);
0726 clear();
0727 append(in_start, in_end);
0728 }
0729
0730 void assign(std::initializer_list<T> IL) {
0731 clear();
0732 append(IL);
0733 }
0734
0735 void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); }
0736
0737 iterator erase(const_iterator CI) {
0738
0739 iterator I = const_cast<iterator>(CI);
0740
0741 assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds.");
0742
0743 iterator N = I;
0744
0745 std::move(I+1, this->end(), I);
0746
0747 this->pop_back();
0748 return(N);
0749 }
0750
0751 iterator erase(const_iterator CS, const_iterator CE) {
0752
0753 iterator S = const_cast<iterator>(CS);
0754 iterator E = const_cast<iterator>(CE);
0755
0756 assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds.");
0757
0758 iterator N = S;
0759
0760 iterator I = std::move(E, this->end(), S);
0761
0762 this->destroy_range(I, this->end());
0763 this->set_size(I - this->begin());
0764 return(N);
0765 }
0766
0767 private:
0768 template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) {
0769
0770 static_assert(
0771 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
0772 T>::value,
0773 "ArgType must be derived from T!");
0774
0775 if (I == this->end()) {
0776 this->push_back(::std::forward<ArgType>(Elt));
0777 return this->end()-1;
0778 }
0779
0780 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
0781
0782
0783 size_t Index = I - this->begin();
0784 std::remove_reference_t<ArgType> *EltPtr =
0785 this->reserveForParamAndGetAddress(Elt);
0786 I = this->begin() + Index;
0787
0788 ::new ((void*) this->end()) T(::std::move(this->back()));
0789
0790 std::move_backward(I, this->end()-1, this->end());
0791 this->set_size(this->size() + 1);
0792
0793
0794
0795 static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
0796 "ArgType must be 'T' when taking by value!");
0797 if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end()))
0798 ++EltPtr;
0799
0800 *I = ::std::forward<ArgType>(*EltPtr);
0801 return I;
0802 }
0803
0804 public:
0805 iterator insert(iterator I, T &&Elt) {
0806 return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
0807 }
0808
0809 iterator insert(iterator I, const T &Elt) {
0810 return insert_one_impl(I, this->forward_value_param(Elt));
0811 }
0812
0813 iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt) {
0814
0815 size_t InsertElt = I - this->begin();
0816
0817 if (I == this->end()) {
0818 append(NumToInsert, Elt);
0819 return this->begin()+InsertElt;
0820 }
0821
0822 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
0823
0824
0825
0826 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
0827
0828
0829 I = this->begin()+InsertElt;
0830
0831
0832
0833
0834
0835 if (size_t(this->end()-I) >= NumToInsert) {
0836 T *OldEnd = this->end();
0837 append(std::move_iterator<iterator>(this->end() - NumToInsert),
0838 std::move_iterator<iterator>(this->end()));
0839
0840
0841 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
0842
0843
0844
0845 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
0846 EltPtr += NumToInsert;
0847
0848 std::fill_n(I, NumToInsert, *EltPtr);
0849 return I;
0850 }
0851
0852
0853
0854
0855
0856 T *OldEnd = this->end();
0857 this->set_size(this->size() + NumToInsert);
0858 size_t NumOverwritten = OldEnd-I;
0859 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
0860
0861
0862
0863 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
0864 EltPtr += NumToInsert;
0865
0866
0867 std::fill_n(I, NumOverwritten, *EltPtr);
0868
0869
0870 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
0871 return I;
0872 }
0873
0874 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
0875 iterator insert(iterator I, ItTy From, ItTy To) {
0876
0877 size_t InsertElt = I - this->begin();
0878
0879 if (I == this->end()) {
0880 append(From, To);
0881 return this->begin()+InsertElt;
0882 }
0883
0884 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
0885
0886
0887 this->assertSafeToAddRange(From, To);
0888
0889 size_t NumToInsert = std::distance(From, To);
0890
0891
0892 reserve(this->size() + NumToInsert);
0893
0894
0895 I = this->begin()+InsertElt;
0896
0897
0898
0899
0900
0901 if (size_t(this->end()-I) >= NumToInsert) {
0902 T *OldEnd = this->end();
0903 append(std::move_iterator<iterator>(this->end() - NumToInsert),
0904 std::move_iterator<iterator>(this->end()));
0905
0906
0907 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
0908
0909 std::copy(From, To, I);
0910 return I;
0911 }
0912
0913
0914
0915
0916
0917 T *OldEnd = this->end();
0918 this->set_size(this->size() + NumToInsert);
0919 size_t NumOverwritten = OldEnd-I;
0920 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
0921
0922
0923 for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
0924 *J = *From;
0925 ++J; ++From;
0926 }
0927
0928
0929 this->uninitialized_copy(From, To, OldEnd);
0930 return I;
0931 }
0932
0933 void insert(iterator I, std::initializer_list<T> IL) {
0934 insert(I, IL.begin(), IL.end());
0935 }
0936
0937 template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
0938 if (LLVM_UNLIKELY(this->size() >= this->capacity()))
0939 return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...);
0940
0941 ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
0942 this->set_size(this->size() + 1);
0943 return this->back();
0944 }
0945
0946 SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
0947
0948 SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
0949
0950 bool operator==(const SmallVectorImpl &RHS) const {
0951 if (this->size() != RHS.size()) return false;
0952 return std::equal(this->begin(), this->end(), RHS.begin());
0953 }
0954 bool operator!=(const SmallVectorImpl &RHS) const {
0955 return !(*this == RHS);
0956 }
0957
0958 bool operator<(const SmallVectorImpl &RHS) const {
0959 return std::lexicographical_compare(this->begin(), this->end(),
0960 RHS.begin(), RHS.end());
0961 }
0962 bool operator>(const SmallVectorImpl &RHS) const { return RHS < *this; }
0963 bool operator<=(const SmallVectorImpl &RHS) const { return !(*this > RHS); }
0964 bool operator>=(const SmallVectorImpl &RHS) const { return !(*this < RHS); }
0965 };
0966
0967 template <typename T>
0968 void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
0969 if (this == &RHS) return;
0970
0971
0972 if (!this->isSmall() && !RHS.isSmall()) {
0973 std::swap(this->BeginX, RHS.BeginX);
0974 std::swap(this->Size, RHS.Size);
0975 std::swap(this->Capacity, RHS.Capacity);
0976 return;
0977 }
0978 this->reserve(RHS.size());
0979 RHS.reserve(this->size());
0980
0981
0982 size_t NumShared = this->size();
0983 if (NumShared > RHS.size()) NumShared = RHS.size();
0984 for (size_type i = 0; i != NumShared; ++i)
0985 std::swap((*this)[i], RHS[i]);
0986
0987
0988 if (this->size() > RHS.size()) {
0989 size_t EltDiff = this->size() - RHS.size();
0990 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
0991 RHS.set_size(RHS.size() + EltDiff);
0992 this->destroy_range(this->begin()+NumShared, this->end());
0993 this->set_size(NumShared);
0994 } else if (RHS.size() > this->size()) {
0995 size_t EltDiff = RHS.size() - this->size();
0996 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
0997 this->set_size(this->size() + EltDiff);
0998 this->destroy_range(RHS.begin()+NumShared, RHS.end());
0999 RHS.set_size(NumShared);
1000 }
1001 }
1002
1003 template <typename T>
1004 SmallVectorImpl<T> &SmallVectorImpl<T>::
1005 operator=(const SmallVectorImpl<T> &RHS) {
1006
1007 if (this == &RHS) return *this;
1008
1009
1010
1011 size_t RHSSize = RHS.size();
1012 size_t CurSize = this->size();
1013 if (CurSize >= RHSSize) {
1014
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
1022 this->destroy_range(NewEnd, this->end());
1023
1024
1025 this->set_size(RHSSize);
1026 return *this;
1027 }
1028
1029
1030
1031
1032 if (this->capacity() < RHSSize) {
1033
1034 this->clear();
1035 CurSize = 0;
1036 this->grow(RHSSize);
1037 } else if (CurSize) {
1038
1039 std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
1040 }
1041
1042
1043 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
1044 this->begin()+CurSize);
1045
1046
1047 this->set_size(RHSSize);
1048 return *this;
1049 }
1050
1051 template <typename T>
1052 SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
1053
1054 if (this == &RHS) return *this;
1055
1056
1057 if (!RHS.isSmall()) {
1058 this->assignRemote(std::move(RHS));
1059 return *this;
1060 }
1061
1062
1063
1064 size_t RHSSize = RHS.size();
1065 size_t CurSize = this->size();
1066 if (CurSize >= RHSSize) {
1067
1068 iterator NewEnd = this->begin();
1069 if (RHSSize)
1070 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
1071
1072
1073 this->destroy_range(NewEnd, this->end());
1074 this->set_size(RHSSize);
1075
1076
1077 RHS.clear();
1078
1079 return *this;
1080 }
1081
1082
1083
1084
1085
1086 if (this->capacity() < RHSSize) {
1087
1088 this->clear();
1089 CurSize = 0;
1090 this->grow(RHSSize);
1091 } else if (CurSize) {
1092
1093 std::move(RHS.begin(), RHS.begin()+CurSize, this->begin());
1094 }
1095
1096
1097 this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
1098 this->begin()+CurSize);
1099
1100
1101 this->set_size(RHSSize);
1102
1103 RHS.clear();
1104 return *this;
1105 }
1106
1107
1108
1109 template <typename T, unsigned N>
1110 struct SmallVectorStorage {
1111 alignas(T) char InlineElts[N * sizeof(T)];
1112 };
1113
1114
1115
1116
1117 template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
1118
1119
1120
1121
1122 template <typename T, unsigned N> class LLVM_GSL_OWNER SmallVector;
1123
1124
1125
1126
1127
1128
1129 template <typename T> struct CalculateSmallVectorDefaultInlinedElements {
1130
1131
1132
1133
1134
1135
1136
1137 static constexpr size_t kPreferredSmallVectorSizeof = 64;
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
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
1169
1170 static constexpr size_t PreferredInlineBytes =
1171 kPreferredSmallVectorSizeof - sizeof(SmallVector<T, 0>);
1172 static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T);
1173 static constexpr size_t value =
1174 NumElementsThatFit == 0 ? 1 : NumElementsThatFit;
1175 };
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193 template <typename T,
1194 unsigned N = CalculateSmallVectorDefaultInlinedElements<T>::value>
1195 class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl<T>,
1196 SmallVectorStorage<T, N> {
1197 public:
1198 SmallVector() : SmallVectorImpl<T>(N) {}
1199
1200 ~SmallVector() {
1201
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>>
1216 SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
1217 this->append(S, E);
1218 }
1219
1220 template <typename RangeTy>
1221 explicit SmallVector(const iterator_range<RangeTy> &R)
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>>
1232 explicit SmallVector(ArrayRef<U> A) : SmallVectorImpl<T>(N) {
1233 this->append(A.begin(), A.end());
1234 }
1235
1236 SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
1237 if (!RHS.empty())
1238 SmallVectorImpl<T>::operator=(RHS);
1239 }
1240
1241 SmallVector &operator=(const SmallVector &RHS) {
1242 SmallVectorImpl<T>::operator=(RHS);
1243 return *this;
1244 }
1245
1246 SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
1247 if (!RHS.empty())
1248 SmallVectorImpl<T>::operator=(::std::move(RHS));
1249 }
1250
1251 SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) {
1252 if (!RHS.empty())
1253 SmallVectorImpl<T>::operator=(::std::move(RHS));
1254 }
1255
1256 SmallVector &operator=(SmallVector &&RHS) {
1257 if (N) {
1258 SmallVectorImpl<T>::operator=(::std::move(RHS));
1259 return *this;
1260 }
1261
1262
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
1274 SmallVector &operator=(SmallVectorImpl<T> &&RHS) {
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
1285 template <typename T, unsigned N>
1286 inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
1287 return X.capacity_in_bytes();
1288 }
1289
1290 template <typename RangeType>
1291 using ValueTypeFromRangeType =
1292 std::remove_const_t<std::remove_reference_t<decltype(*std::begin(
1293 std::declval<RangeType &>()))>>;
1294
1295
1296
1297
1298 template <unsigned Size, typename R>
1299 SmallVector<ValueTypeFromRangeType<R>, Size> to_vector(R &&Range) {
1300 return {std::begin(Range), std::end(Range)};
1301 }
1302 template <typename R>
1303 SmallVector<ValueTypeFromRangeType<R>> to_vector(R &&Range) {
1304 return {std::begin(Range), std::end(Range)};
1305 }
1306
1307 template <typename Out, unsigned Size, typename R>
1308 SmallVector<Out, Size> to_vector_of(R &&Range) {
1309 return {std::begin(Range), std::end(Range)};
1310 }
1311
1312 template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
1313 return {std::begin(Range), std::end(Range)};
1314 }
1315
1316
1317 extern template class llvm::SmallVectorBase<uint32_t>;
1318 #if SIZE_MAX > UINT32_MAX
1319 extern template class llvm::SmallVectorBase<uint64_t>;
1320 #endif
1321
1322 }
1323
1324 namespace std {
1325
1326
1327 template<typename T>
1328 inline void
1329 swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
1330 LHS.swap(RHS);
1331 }
1332
1333
1334 template<typename T, unsigned N>
1335 inline void
1336 swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
1337 LHS.swap(RHS);
1338 }
1339
1340 }
1341
1342 #endif