14#ifndef LLVM_ADT_SMALLVECTOR_H 
   15#define LLVM_ADT_SMALLVECTOR_H 
   27#include <initializer_list> 
   41template <
class Iterator>
 
   43    typename std::iterator_traits<Iterator>::iterator_category,
 
   44    std::input_iterator_tag>::value>;
 
   61    return std::numeric_limits<Size_T>::max();
 
 
   92    Size = 
static_cast<Size_T
>(
N);
 
 
 
  108    std::conditional_t<
sizeof(
T) < 4 && 
sizeof(
void *) >= 8, 
uint64_t,
 
  121template <
typename T, 
typename = 
void>
 
  131    return const_cast<void *
>(
reinterpret_cast<const void *
>(
 
  132        reinterpret_cast<const char *
>(
this) +
 
 
  156    std::less<> LessThan;
 
  157    return !LessThan(V, 
First) && LessThan(V, 
Last);
 
 
  169    std::less<> LessThan;
 
  171           !LessThan(this->
end(), Last);
 
 
  182    if (NewSize <= this->
size())
 
  183      return Elt < this->
begin() + NewSize;
 
 
  192           "Attempting to reference an element of the vector in an operation " 
  193           "that invalidates it");
 
 
  203  template <
class ItTy>
 
  205    if constexpr (std::is_pointer_v<ItTy> &&
 
  207                      std::remove_const_t<std::remove_pointer_t<ItTy>>,
 
  208                      std::remove_const_t<T>>) {
 
 
  218    if constexpr (std::is_pointer_v<ItTy> &&
 
  219                  std::is_same_v<std::remove_cv_t<std::remove_pointer_t<ItTy>>,
 
 
  235    size_t NewSize = This->size() + 
N;
 
  239    bool ReferencesStorage = 
false;
 
  241    if (!U::TakesParamByValue) {
 
  243        ReferencesStorage = 
true;
 
  244        Index = &Elt - This->begin();
 
  248    return ReferencesStorage ? This->begin() + Index : &Elt;
 
 
 
  330template <
typename T, 
bool = (std::is_trivially_copy_constructible<T>::value) &&
 
  331                             (std::is_trivially_move_constructible<T>::value) &&
 
  332                             std::is_trivially_destructible<T>::value>
 
  351  template<
typename It1, 
typename It2>
 
  353    std::uninitialized_move(
I, 
E, Dest);
 
 
  358  template<
typename It1, 
typename It2>
 
  360    std::uninitialized_copy(
I, 
E, Dest);
 
 
  388    return const_cast<T *
>(
 
 
  399    std::uninitialized_fill_n(NewElts, NumElts, Elt);
 
 
  409    ::new ((
void *)(NewElts + this->
size())) 
T(std::forward<ArgTypes>(Args)...);
 
 
  419    ::new ((
void *)this->
end()) 
T(*EltPtr);
 
 
  425    ::new ((
void *)this->
end()) 
T(::std::move(*EltPtr));
 
 
  436template <
typename T, 
bool TriviallyCopyable>
 
  444template <
typename T, 
bool TriviallyCopyable>
 
  446    size_t MinSize, 
size_t &NewCapacity) {
 
  447  return static_cast<T *
>(
 
  449          this->
getFirstEl(), MinSize, 
sizeof(
T), NewCapacity));
 
 
  453template <
typename T, 
bool TriviallyCopyable>
 
  464template <
typename T, 
bool TriviallyCopyable>
 
  466    T *NewElts, 
size_t NewCapacity) {
 
 
 
  489  using ValueParamT = std::conditional_t<TakesParamByValue, T, const T &>;
 
  498  template<
typename It1, 
typename It2>
 
  506  template <
typename It1, 
typename It2>
 
  508    if constexpr (std::is_pointer_v<It1> && std::is_pointer_v<It2> &&
 
  510                      std::remove_const_t<std::remove_pointer_t<It1>>,
 
  511                      std::remove_pointer_t<It2>>) {
 
  517        std::memcpy(
reinterpret_cast<void *
>(Dest), 
I, (
E - 
I) * 
sizeof(
T));
 
  520      std::uninitialized_copy(
I, 
E, Dest);
 
 
  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())
 
  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())
 
 
  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) {
 
 
  738  template <
typename U,
 
  739            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
 
  752    std::move(
I+1, this->
end(), I);
 
 
  778        std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
 
  780        "ArgType must be derived from T!");
 
  782    if (
I == this->
end()) {  
 
  783      this->
push_back(::std::forward<ArgType>(Elt));
 
  784      return this->
end()-1;
 
  790    size_t Index = 
I - this->
begin();
 
  791    std::remove_reference_t<ArgType> *EltPtr =
 
  793    I = this->
begin() + Index;
 
  797    std::move_backward(
I, this->
end()-1, this->
end());
 
  803                  "ArgType must be 'T' when taking by value!");
 
  807    *
I = ::
std::forward<ArgType>(*EltPtr);
 
  822    size_t InsertElt = 
I - this->
begin();
 
  824    if (I == this->
end()) {  
 
  826      return this->
begin()+InsertElt;
 
  836    I = this->
begin()+InsertElt;
 
  842    if (
size_t(this->
end()-I) >= NumToInsert) {
 
  843      T *OldEnd = this->
end();
 
  844      append(std::move_iterator<iterator>(this->
end() - NumToInsert),
 
  845             std::move_iterator<iterator>(this->
end()));
 
  848      std::move_backward(
I, OldEnd-NumToInsert, OldEnd);
 
  853        EltPtr += NumToInsert;
 
  855      std::fill_n(
I, NumToInsert, *EltPtr);
 
  863    T *OldEnd = this->
end();
 
  865    size_t NumOverwritten = OldEnd-
I;
 
  871      EltPtr += NumToInsert;
 
  874    std::fill_n(
I, NumOverwritten, *EltPtr);
 
  877    std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
 
 
  881  template <
typename ItTy, 
typename = EnableIfConvertibleToInputIterator<ItTy>>
 
  884    size_t InsertElt = 
I - this->
begin();
 
  886    if (I == this->
end()) {  
 
  888      return this->
begin()+InsertElt;
 
  896    size_t NumToInsert = std::distance(From, To);
 
  902    I = this->
begin()+InsertElt;
 
  908    if (
size_t(this->
end()-I) >= NumToInsert) {
 
  909      T *OldEnd = this->
end();
 
  910      append(std::move_iterator<iterator>(this->
end() - NumToInsert),
 
  911             std::move_iterator<iterator>(this->
end()));
 
  914      std::move_backward(
I, OldEnd-NumToInsert, OldEnd);
 
  916      std::copy(From, To, 
I);
 
  924    T *OldEnd = this->
end();
 
  926    size_t NumOverwritten = OldEnd-
I;
 
  930    for (
T *J = 
I; NumOverwritten > 0; --NumOverwritten) {
 
 
  941    insert(
I, IL.begin(), IL.end());
 
 
  948    ::new ((
void *)this->
end()) 
T(std::forward<ArgTypes>(Args)...);
 
 
  958    if (this->
size() != RHS.
size()) 
return false;
 
 
  962    return !(*
this == 
RHS);
 
 
  966    return std::lexicographical_compare(this->
begin(), this->
end(),
 
 
 
  976  if (
this == &
RHS) 
return;
 
  989  size_t NumShared = this->
size();
 
  990  if (NumShared > 
RHS.size()) NumShared = 
RHS.size();
 
  991  for (
size_type i = 0; i != NumShared; ++i)
 
  996    size_t EltDiff = this->
size() - RHS.
size();
 
  998    RHS.set_size(
RHS.size() + EltDiff);
 
 1001  } 
else if (
RHS.size() > this->size()) {
 
 1002    size_t EltDiff = 
RHS.size() - this->
size();
 
 1006    RHS.set_size(NumShared);
 
 
 1010template <
typename T>
 
 1014  if (
this == &
RHS) 
return *
this;
 
 1018  size_t RHSSize = 
RHS.size();
 
 1019  size_t CurSize = this->
size();
 
 1020  if (CurSize >= RHSSize) {
 
 1024      NewEnd = std::copy(
RHS.begin(), 
RHS.begin()+RHSSize, this->begin());
 
 1026      NewEnd = this->
begin();
 
 1043    this->
grow(RHSSize);
 
 1044  } 
else if (CurSize) {
 
 1046    std::copy(
RHS.begin(), 
RHS.begin()+CurSize, this->begin());
 
 1051                           this->begin()+CurSize);
 
 
 1058template <
typename T>
 
 1061  if (
this == &
RHS) 
return *
this;
 
 1064  if (!
RHS.isSmall()) {
 
 1071  size_t RHSSize = 
RHS.size();
 
 1072  size_t CurSize = this->
size();
 
 1073  if (CurSize >= RHSSize) {
 
 1077      NewEnd = std::move(
RHS.begin(), 
RHS.end(), NewEnd);
 
 1097    this->
grow(RHSSize);
 
 1098  } 
else if (CurSize) {
 
 1100    std::move(
RHS.begin(), 
RHS.begin()+CurSize, this->begin());
 
 1105                           this->begin()+CurSize);
 
 
 1116template <
typename T, 
unsigned N>
 
 1170      "You are trying to use a default number of inlined elements for " 
 1171      "`SmallVector<T>` but `sizeof(T)` is really big! Please use an " 
 1172      "explicit number of inlined elements with `SmallVector<T, N>` to make " 
 1173      "sure you really want that much inline storage.");
 
 
 1200template <
typename T,
 
 1222  template <
typename ItTy, 
typename = EnableIfConvertibleToInputIterator<ItTy>>
 
 1227  template <
typename RangeTy>
 
 1230    this->
append(R.begin(), R.end());
 
 
 1237  template <
typename U,
 
 1238            typename = std::enable_if_t<std::is_convertible_v<U, T>>>
 
 
 1292template <
typename T, 
unsigned N>
 
 1294  return X.capacity_in_bytes();
 
 
 1297template <
typename RangeType>
 
 1299    std::remove_const_t<detail::ValueOfRange<RangeType>>;
 
 1304template <
unsigned Size, 
typename R>
 
 1308template <
typename R>
 
 1313template <
typename Out, 
unsigned Size, 
typename R>
 
 1324#if SIZE_MAX > UINT32_MAX 
 1353  template<
typename T>
 
 1360  template<
typename T, 
unsigned N>
 
 
 
 
 
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)
#define LLVM_GSL_OWNER
LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable lifetime warnings.
#define LLVM_LIKELY(EXPR)
This file defines DenseMapInfo traits for DenseMap.
#define offsetof(TYPE, MEMBER)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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.
SmallVectorSizeType< T > Capacity
SmallVectorSizeType< T > Size
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, MemoryLocation &&Elt)
bool operator>(const SmallVectorImpl &RHS) const
bool operator<(const SmallVectorImpl &RHS) const
iterator erase(const_iterator CS, const_iterator CE)
bool operator!=(const SmallVectorImpl &RHS) const
void truncate(size_type N)
Like resize, but requires that N is less than size().
void assign(ItTy in_start, ItTy in_end)
void assign(std::initializer_list< T > IL)
void assign(ArrayRef< U > AR)
SmallVectorImpl(unsigned N)
void swap(SmallVectorImpl &RHS)
typename SuperClass::iterator iterator
bool operator<=(const SmallVectorImpl &RHS) const
typename SuperClass::size_type size_type
void append(std::initializer_list< T > IL)
void append(size_type NumInputs, ValueParamT Elt)
Append NumInputs copies of Elt to the end.
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 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
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)
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...
const T & const_reference
SmallVectorTemplateCommon(size_t Size)
const_reference operator[](size_type idx) const
void resetToSmall()
Put this vector in a state of being small.
bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Return true unless Elt will be invalidated by resizing the vector to NewSize.
std::reverse_iterator< const_iterator > const_reverse_iterator
pointer data()
Return a pointer to the vector's buffer, even if empty().
bool isReferenceToRange(const void *V, const void *First, const void *Last) const
Return true if V is an internal reference to the given range.
void grow_pod(size_t MinSize, size_t TSize)
const_reverse_iterator rbegin() const
const_iterator begin() const
reference operator[](size_type idx)
size_t capacity_in_bytes() const
size_type size_in_bytes() const
ptrdiff_t difference_type
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.
void assertSafeToAddRange(ItTy From, ItTy To)
Check whether any part of the range will be invalidated by growing.
std::reverse_iterator< iterator > reverse_iterator
void assertSafeToReferenceAfterClear(ItTy From, ItTy To)
Check whether any part of the range will be invalidated by clearing.
const_reverse_iterator rend() const
const_pointer data() const
Return a pointer to the vector's buffer, even if empty().
void * getFirstEl() const
Find the address of the first element.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SmallVector(std::initializer_list< T > IL)
SmallVector(SmallVectorImpl< T > &&RHS)
SmallVector(ArrayRef< U > A)
SmallVector(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::remove_const_t< detail::ValueOfRange< RangeType > > ValueTypeFromRangeType
constexpr auto adl_begin(RangeT &&range) -> decltype(adl_detail::begin_impl(std::forward< RangeT >(range)))
Returns the begin iterator to range using std::begin and function found through Argument-Dependent Lo...
std::enable_if_t< std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::input_iterator_tag >::value > EnableIfConvertibleToInputIterator
BitVector::size_type capacity_in_bytes(const BitVector &X)
constexpr auto adl_end(RangeT &&range) -> decltype(adl_detail::end_impl(std::forward< RangeT >(range)))
Returns the end iterator to range using std::end and functions found through Argument-Dependent Looku...
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.
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 constexpr size_t kPreferredSmallVectorSizeof
static constexpr size_t value
static constexpr size_t NumElementsThatFit
static constexpr size_t PreferredInlineBytes
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.
char InlineElts[N *sizeof(T)]