14#ifndef LLVM_ADT_SMALLVECTOR_H
15#define LLVM_ADT_SMALLVECTOR_H
26#include <initializer_list>
40template <
class Iterator>
42 typename std::iterator_traits<Iterator>::iterator_category,
43 std::input_iterator_tag>
::value>;
60 return std::numeric_limits<Size_T>::max();
91 Size =
static_cast<Size_T
>(
N);
107 std::conditional_t<
sizeof(
T) < 4 &&
sizeof(
void *) >= 8,
uint64_t,
120template <
typename T,
typename =
void>
130 return const_cast<void *
>(
reinterpret_cast<const void *
>(
131 reinterpret_cast<const char *
>(
this) +
155 std::less<> LessThan;
156 return !LessThan(V,
First) && LessThan(V,
Last);
168 std::less<> LessThan;
170 !LessThan(this->
end(), Last);
181 if (NewSize <= this->
size())
182 return Elt < this->
begin() + NewSize;
191 "Attempting to reference an element of the vector in an operation "
192 "that invalidates it");
210 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>,
T *>
::value,
223 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>,
T *>
::value,
232 size_t NewSize = This->size() +
N;
236 bool ReferencesStorage =
false;
238 if (!U::TakesParamByValue) {
240 ReferencesStorage =
true;
241 Index = &Elt - This->begin();
245 return ReferencesStorage ? This->begin() +
Index : &Elt;
327template <
typename T,
bool = (std::is_trivially_copy_constructible<T>::value) &&
328 (std::is_trivially_move_constructible<T>::value) &&
329 std::is_trivially_destructible<T>::value>
348 template<
typename It1,
typename It2>
350 std::uninitialized_move(
I,
E, Dest);
355 template<
typename It1,
typename It2>
357 std::uninitialized_copy(
I,
E, Dest);
385 return const_cast<T *
>(
396 std::uninitialized_fill_n(NewElts, NumElts, Elt);
406 ::new ((
void *)(NewElts + this->
size()))
T(std::forward<ArgTypes>(Args)...);
416 ::new ((
void *)this->
end())
T(*EltPtr);
422 ::new ((
void *)this->
end())
T(::std::move(*EltPtr));
433template <
typename T,
bool TriviallyCopyable>
436 T *NewElts = mallocForGrow(MinSize, NewCapacity);
437 moveElementsForGrow(NewElts);
438 takeAllocationForGrow(NewElts, NewCapacity);
441template <
typename T,
bool TriviallyCopyable>
443 size_t MinSize,
size_t &NewCapacity) {
444 return static_cast<T *
>(
446 this->getFirstEl(), MinSize,
sizeof(
T), NewCapacity));
450template <
typename T,
bool TriviallyCopyable>
454 this->uninitialized_move(this->begin(), this->end(), NewElts);
457 destroy_range(this->begin(), this->end());
461template <
typename T,
bool TriviallyCopyable>
463 T *NewElts,
size_t NewCapacity) {
465 if (!this->isSmall())
468 this->set_allocation_range(NewElts, NewCapacity);
486 using ValueParamT = std::conditional_t<TakesParamByValue, T, const T &>;
495 template<
typename It1,
typename It2>
503 template<
typename It1,
typename It2>
506 std::uninitialized_copy(
I,
E, Dest);
511 template <
typename T1,
typename T2>
514 std::enable_if_t<std::is_same<std::remove_const_t<T1>, T2>
::value> * =
521 std::memcpy(
reinterpret_cast<void *
>(Dest),
I, (
E -
I) *
sizeof(
T));
537 return const_cast<T *
>(
549 std::uninitialized_fill_n(this->
begin(), NumElts, Elt);
557 push_back(
T(std::forward<ArgTypes>(Args)...));
564 std::memcpy(
reinterpret_cast<void *
>(this->
end()), EltPtr,
sizeof(
T));
620 template <
bool ForOverwrite>
void resizeImpl(
size_type N) {
621 if (
N == this->size())
624 if (N < this->size()) {
630 for (
auto I = this->
end(),
E = this->
begin() + N;
I !=
E; ++
I)
646 assert(this->
size() >=
N &&
"Cannot increase size with truncate");
652 if (
N == this->
size())
655 if (N < this->
size()) {
675 T Result = ::std::move(this->
back());
683 template <
typename ItTy,
typename = EnableIfConvertibleToInputIterator<ItTy>>
686 size_type NumInputs = std::distance(in_start, in_end);
695 std::uninitialized_fill_n(this->
end(), NumInputs, *EltPtr);
699 void append(std::initializer_list<T> IL) {
700 append(IL.begin(), IL.end());
713 std::fill_n(this->
begin(), std::min(NumElts, this->
size()), Elt);
714 if (NumElts > this->
size())
715 std::uninitialized_fill_n(this->
end(), NumElts - this->
size(), Elt);
716 else if (NumElts < this->
size())
724 template <
typename ItTy,
typename = EnableIfConvertibleToInputIterator<ItTy>>
731 void assign(std::initializer_list<T> IL) {
746 std::move(
I+1, this->
end(), I);
772 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
774 "ArgType must be derived from T!");
776 if (
I == this->
end()) {
777 this->
push_back(::std::forward<ArgType>(Elt));
778 return this->
end()-1;
785 std::remove_reference_t<ArgType> *EltPtr =
791 std::move_backward(
I, this->
end()-1, this->
end());
797 "ArgType must be '
T' when taking by
value!");
801 *
I = ::
std::forward<ArgType>(*EltPtr);
816 size_t InsertElt =
I - this->
begin();
818 if (I == this->
end()) {
820 return this->
begin()+InsertElt;
830 I = this->
begin()+InsertElt;
836 if (
size_t(this->
end()-I) >= NumToInsert) {
837 T *OldEnd = this->
end();
838 append(std::move_iterator<iterator>(this->
end() - NumToInsert),
839 std::move_iterator<iterator>(this->
end()));
842 std::move_backward(
I, OldEnd-NumToInsert, OldEnd);
847 EltPtr += NumToInsert;
849 std::fill_n(
I, NumToInsert, *EltPtr);
857 T *OldEnd = this->
end();
859 size_t NumOverwritten = OldEnd-
I;
865 EltPtr += NumToInsert;
868 std::fill_n(
I, NumOverwritten, *EltPtr);
871 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
875 template <
typename ItTy,
typename = EnableIfConvertibleToInputIterator<ItTy>>
878 size_t InsertElt =
I - this->
begin();
880 if (I == this->
end()) {
882 return this->
begin()+InsertElt;
890 size_t NumToInsert = std::distance(
From, To);
896 I = this->
begin()+InsertElt;
902 if (
size_t(this->
end()-I) >= NumToInsert) {
903 T *OldEnd = this->
end();
904 append(std::move_iterator<iterator>(this->
end() - NumToInsert),
905 std::move_iterator<iterator>(this->
end()));
908 std::move_backward(
I, OldEnd-NumToInsert, OldEnd);
910 std::copy(
From, To,
I);
918 T *OldEnd = this->
end();
920 size_t NumOverwritten = OldEnd-
I;
924 for (
T *J =
I; NumOverwritten > 0; --NumOverwritten) {
935 insert(
I, IL.begin(), IL.end());
942 ::new ((
void *)this->
end())
T(std::forward<ArgTypes>(Args)...);
952 if (this->
size() !=
RHS.size())
return false;
956 return !(*
this ==
RHS);
960 return std::lexicographical_compare(this->
begin(), this->
end(),
970 if (
this == &
RHS)
return;
983 size_t NumShared = this->
size();
984 if (NumShared >
RHS.size()) NumShared =
RHS.size();
985 for (
size_type i = 0; i != NumShared; ++i)
989 if (this->
size() >
RHS.size()) {
990 size_t EltDiff = this->
size() -
RHS.size();
992 RHS.set_size(
RHS.size() + EltDiff);
995 }
else if (
RHS.size() > this->size()) {
996 size_t EltDiff =
RHS.size() - this->
size();
1000 RHS.set_size(NumShared);
1004template <
typename T>
1008 if (
this == &
RHS)
return *
this;
1012 size_t RHSSize =
RHS.size();
1013 size_t CurSize = this->
size();
1014 if (CurSize >= RHSSize) {
1018 NewEnd = std::copy(
RHS.begin(),
RHS.begin()+RHSSize, this->begin());
1020 NewEnd = this->
begin();
1037 this->
grow(RHSSize);
1038 }
else if (CurSize) {
1040 std::copy(
RHS.begin(),
RHS.begin()+CurSize, this->begin());
1045 this->begin()+CurSize);
1052template <
typename T>
1055 if (
this == &
RHS)
return *
this;
1058 if (!
RHS.isSmall()) {
1065 size_t RHSSize =
RHS.size();
1066 size_t CurSize = this->
size();
1067 if (CurSize >= RHSSize) {
1071 NewEnd = std::move(
RHS.begin(),
RHS.end(), NewEnd);
1091 this->
grow(RHSSize);
1092 }
else if (CurSize) {
1094 std::move(
RHS.begin(),
RHS.begin()+CurSize, this->begin());
1099 this->begin()+CurSize);
1110template <
typename T,
unsigned N>
1112 alignas(
T)
char InlineElts[
N *
sizeof(
T)];
1138 static constexpr size_t kPreferredSmallVectorSizeof = 64;
1164 "You are trying to use a default number of inlined elements for "
1165 "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
1166 "explicit number of inlined elements with `SmallVector<T, N>` to make "
1167 "sure you really want that much inline storage.");
1171 static constexpr size_t PreferredInlineBytes =
1173 static constexpr size_t NumElementsThatFit = PreferredInlineBytes /
sizeof(
T);
1175 NumElementsThatFit == 0 ? 1 : NumElementsThatFit;
1194template <
typename T,
1203 this->destroy_range(this->begin(), this->end());
1216 template <
typename ItTy,
typename = EnableIfConvertibleToInputIterator<ItTy>>
1221 template <
typename RangeTy>
1224 this->append(R.begin(), R.end());
1231 template <
typename U,
1232 typename = std::enable_if_t<std::is_convertible<U, T>::value>>
1234 this->append(
A.begin(),
A.end());
1267 this->destroy_range(this->begin(), this->end());
1270 this->assignRemote(std::move(
RHS));
1286template <
typename T,
unsigned N>
1288 return X.capacity_in_bytes();
1291template <
typename RangeType>
1293 std::remove_const_t<std::remove_reference_t<
decltype(*std::begin(
1294 std::declval<RangeType &>()))>>;
1299template <
unsigned Size,
typename R>
1303template <
typename R>
1308template <
typename Out,
unsigned Size,
typename R>
1319#if SIZE_MAX > UINT32_MAX
1348 template<
typename T>
1355 template<
typename T,
unsigned N>
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define offsetof(TYPE, MEMBER)
BlockVerifier::State From
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
#define LLVM_GSL_OWNER
LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable lifetime warnings.
#define LLVM_LIKELY(EXPR)
Given that RA is a live value
This file defines DenseMapInfo traits for DenseMap.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is all the stuff common to all SmallVectors.
LLVM_ABI void grow_pod(void *FirstEl, size_t MinSize, size_t TSize)
This is an implementation of the grow() method which only works on POD-like data types and is out of ...
LLVM_ABI void * mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize, size_t &NewCapacity)
This is a helper for grow() that's out of line to reduce code duplication.
void set_allocation_range(void *Begin, size_t N)
Set the array data pointer to Begin and capacity to N.
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
void set_size(size_t N)
Set the array size to N, which the current array must have enough capacity for.
static constexpr size_t SizeTypeMax()
The maximum value of the Size_T used.
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, T &&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.
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.
SmallVectorTemplateBase(size_t Size)
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...
void push_back(ValueParamT Elt)
static void destroy_range(T *, T *)
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 ...
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 ...
SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put method implementations that...
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
SmallVectorTemplateBase(size_t Size)
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)
This is the part of SmallVectorTemplateBase which does not depend on whether the type T is a POD.
void assertSafeToAddRange(ItTy, ItTy)
bool isSmall() const
Return true if this is a smallvector which has not had dynamic memory allocated for it.
const_iterator end() const
reverse_iterator rbegin()
static const T * reserveForParamAndGetAddressImpl(U *This, const T &Elt, size_t N)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
SmallVectorTemplateCommon(size_t Size)
void assertSafeToAddRange(const T *From, const T *To)
Check whether any part of the range will be invalidated by growing.
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_t capacity_in_bytes() const
size_type size_in_bytes() const
size_type max_size() 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.
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(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.
A range adaptor for a pair of iterators.
This is an optimization pass for GlobalISel generic memory operations.
std::conditional_t< sizeof(T)< 4 &&sizeof(void *) >=8, uint64_t, uint32_t > SmallVectorSizeType
BitVector::size_type capacity_in_bytes(const BitVector &X)
std::enable_if_t< std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::input_iterator_tag >::value > EnableIfConvertibleToInputIterator
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::remove_const_t< std::remove_reference_t< decltype(*std::begin(std::declval< RangeType & >()))> > ValueTypeFromRangeType
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
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.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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 SmallVector< T, N > getEmptyKey()
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.