14 #ifndef LLVM_ADT_SMALLVECTOR_H
15 #define LLVM_ADT_SMALLVECTOR_H
27 #include <initializer_list>
31 #include <type_traits>
47 void grow_pod(
void *FirstEl,
size_t MinSizeInBytes,
size_t TSize);
66 template <
typename T,
typename =
void>
81 void grow_pod(
size_t MinSizeInBytes,
size_t TSize) {
88 return BeginX ==
static_cast<const void*
>(&FirstEl);
178 template <
typename T,
bool isPodLike>
192 template<
typename It1,
typename It2>
194 std::uninitialized_copy(std::make_move_iterator(I),
195 std::make_move_iterator(E), Dest);
200 template<
typename It1,
typename It2>
202 std::uninitialized_copy(I, E, Dest);
208 void grow(
size_t MinSize = 0);
214 ::new ((
void*) this->
end())
T(Elt);
221 ::new ((
void*) this->
end())
T(::std::move(Elt));
232 template <
typename T,
bool isPodLike>
234 size_t CurCapacity = this->capacity();
235 size_t CurSize = this->size();
237 size_t NewCapacity = size_t(
NextPowerOf2(CurCapacity+2));
238 if (NewCapacity < MinSize)
239 NewCapacity = MinSize;
240 T *NewElts =
static_cast<T*
>(malloc(NewCapacity*
sizeof(
T)));
243 this->uninitialized_move(this->
begin(), this->
end(), NewElts);
246 destroy_range(this->
begin(), this->
end());
249 if (!this->isSmall())
252 this->setEnd(NewElts+CurSize);
253 this->BeginX = NewElts;
254 this->CapacityX = this->
begin()+NewCapacity;
260 template <
typename T>
270 template<
typename It1,
typename It2>
278 template<
typename It1,
typename It2>
281 std::uninitialized_copy(I, E, Dest);
286 template <
typename T1,
typename T2>
289 typename std::enable_if<std::is_same<
typename std::remove_const<T1>::type,
290 T2>::value>::type * =
nullptr) {
296 memcpy(Dest, I, (E - I) *
sizeof(
T));
301 void grow(
size_t MinSize = 0) {
309 memcpy(this->
end(), &Elt,
sizeof(
T));
320 template <
typename T>
321 class SmallVectorImpl :
public SmallVectorTemplateBase<T, isPodLike<T>::value> {
322 typedef SmallVectorTemplateBase<T, isPodLike<T>::value >
SuperClass;
353 if (N < this->
size()) {
356 }
else if (N > this->
size()) {
359 for (
auto I = this->
end(),
E = this->
begin() + N;
I !=
E; ++
I)
366 if (N < this->
size()) {
369 }
else if (N > this->
size()) {
372 std::uninitialized_fill(this->
end(), this->
begin()+N, NV);
383 T Result = ::std::move(this->
back());
391 template<
typename in_iter>
392 void append(in_iter in_start, in_iter in_end) {
393 size_type NumInputs = std::distance(in_start, in_end);
410 std::uninitialized_fill_n(this->
end(), NumInputs, Elt);
414 void append(std::initializer_list<T> IL) {
415 append(IL.begin(), IL.end());
423 std::uninitialized_fill(this->
begin(), this->
end(), Elt);
426 void assign(std::initializer_list<T> IL) {
435 assert(I >= this->
begin() &&
"Iterator to erase is out of bounds.");
436 assert(I < this->
end() &&
"Erasing at past-the-end iterator.");
440 std::move(I+1, this->
end(), I);
451 assert(S >= this->
begin() &&
"Range to erase is out of bounds.");
452 assert(S <= E &&
"Trying to erase invalid range.");
453 assert(E <= this->
end() &&
"Trying to erase past the end.");
465 if (I == this->
end()) {
467 return this->
end()-1;
470 assert(I >= this->
begin() &&
"Insertion iterator is out of bounds.");
471 assert(I <= this->
end() &&
"Inserting past the end of the vector.");
474 size_t EltNo = I-this->
begin();
476 I = this->
begin()+EltNo;
479 ::new ((
void*) this->
end())
T(::std::move(this->
back()));
481 std::move_backward(I, this->
end()-1, this->
end());
487 if (I <= EltPtr && EltPtr < this->
EndX)
490 *I = ::std::move(*EltPtr);
495 if (I == this->
end()) {
497 return this->
end()-1;
500 assert(I >= this->
begin() &&
"Insertion iterator is out of bounds.");
501 assert(I <= this->
end() &&
"Inserting past the end of the vector.");
504 size_t EltNo = I-this->
begin();
506 I = this->
begin()+EltNo;
508 ::new ((
void*) this->
end())
T(std::move(this->
back()));
510 std::move_backward(I, this->
end()-1, this->
end());
515 const T *EltPtr = &Elt;
516 if (I <= EltPtr && EltPtr < this->
EndX)
525 size_t InsertElt = I - this->
begin();
527 if (I == this->
end()) {
529 return this->
begin()+InsertElt;
532 assert(I >= this->
begin() &&
"Insertion iterator is out of bounds.");
533 assert(I <= this->
end() &&
"Inserting past the end of the vector.");
539 I = this->
begin()+InsertElt;
545 if (
size_t(this->
end()-I) >= NumToInsert) {
546 T *OldEnd = this->
end();
547 append(std::move_iterator<iterator>(this->
end() - NumToInsert),
548 std::move_iterator<iterator>(this->
end()));
551 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
553 std::fill_n(I, NumToInsert, Elt);
561 T *OldEnd = this->
end();
563 size_t NumOverwritten = OldEnd-
I;
567 std::fill_n(I, NumOverwritten, Elt);
570 std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
574 template<
typename ItTy>
577 size_t InsertElt = I - this->
begin();
579 if (I == this->
end()) {
581 return this->
begin()+InsertElt;
584 assert(I >= this->
begin() &&
"Insertion iterator is out of bounds.");
585 assert(I <= this->
end() &&
"Inserting past the end of the vector.");
587 size_t NumToInsert = std::distance(From, To);
593 I = this->
begin()+InsertElt;
599 if (
size_t(this->
end()-I) >= NumToInsert) {
600 T *OldEnd = this->
end();
601 append(std::move_iterator<iterator>(this->
end() - NumToInsert),
602 std::move_iterator<iterator>(this->
end()));
605 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
607 std::copy(From, To, I);
615 T *OldEnd = this->
end();
617 size_t NumOverwritten = OldEnd-
I;
621 for (
T *J = I; NumOverwritten > 0; --NumOverwritten) {
632 insert(I, IL.begin(), IL.end());
638 ::new ((
void *)this->
end())
T(std::forward<ArgTypes>(
Args)...);
647 if (this->
size() != RHS.size())
return false;
651 return !(*
this == RHS);
655 return std::lexicographical_compare(this->
begin(), this->
end(),
656 RHS.begin(), RHS.end());
674 template <
typename T>
676 if (
this == &RHS)
return;
679 if (!this->isSmall() && !RHS.isSmall()) {
682 std::swap(this->CapacityX, RHS.CapacityX);
685 if (RHS.size() > this->capacity())
686 this->grow(RHS.size());
687 if (this->size() > RHS.capacity())
688 RHS.grow(this->size());
691 size_t NumShared = this->size();
692 if (NumShared > RHS.size()) NumShared = RHS.size();
697 if (this->size() > RHS.size()) {
698 size_t EltDiff = this->size() - RHS.size();
699 this->uninitialized_copy(this->
begin()+NumShared, this->
end(), RHS.end());
700 RHS.setEnd(RHS.end()+EltDiff);
701 this->destroy_range(this->
begin()+NumShared, this->
end());
702 this->setEnd(this->
begin()+NumShared);
703 }
else if (RHS.size() > this->size()) {
704 size_t EltDiff = RHS.size() - this->size();
705 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->
end());
706 this->setEnd(this->
end() + EltDiff);
707 this->destroy_range(RHS.begin()+NumShared, RHS.end());
708 RHS.setEnd(RHS.begin()+NumShared);
712 template <
typename T>
716 if (
this == &RHS)
return *
this;
720 size_t RHSSize = RHS.size();
721 size_t CurSize = this->size();
722 if (CurSize >= RHSSize) {
726 NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->
begin());
728 NewEnd = this->
begin();
731 this->destroy_range(NewEnd, this->
end());
734 this->setEnd(NewEnd);
741 if (this->capacity() < RHSSize) {
743 this->destroy_range(this->
begin(), this->
end());
744 this->setEnd(this->
begin());
747 }
else if (CurSize) {
749 std::copy(RHS.begin(), RHS.begin()+CurSize, this->
begin());
753 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
754 this->
begin()+CurSize);
757 this->setEnd(this->
begin()+RHSSize);
761 template <
typename T>
764 if (
this == &RHS)
return *
this;
767 if (!RHS.isSmall()) {
768 this->destroy_range(this->
begin(), this->
end());
769 if (!this->isSmall()) free(this->
begin());
770 this->BeginX = RHS.BeginX;
771 this->EndX = RHS.EndX;
772 this->CapacityX = RHS.CapacityX;
779 size_t RHSSize = RHS.size();
780 size_t CurSize = this->size();
781 if (CurSize >= RHSSize) {
785 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
788 this->destroy_range(NewEnd, this->
end());
789 this->setEnd(NewEnd);
801 if (this->capacity() < RHSSize) {
803 this->destroy_range(this->
begin(), this->
end());
804 this->setEnd(this->
begin());
807 }
else if (CurSize) {
809 std::move(RHS.begin(), RHS.begin()+CurSize, this->
begin());
813 this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
814 this->
begin()+CurSize);
817 this->setEnd(this->
begin()+RHSSize);
827 template <
typename T,
unsigned N>
842 template <
typename T,
unsigned N>
856 template<
typename ItTy>
861 template <
typename RangeTy>
907 template<
typename T,
unsigned N>
924 template<
typename T,
unsigned N>
932 #endif // LLVM_ADT_SMALLVECTOR_H
SuperClass::iterator iterator
std::reverse_iterator< iterator > reverse_iterator
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
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 ...
DiagnosticInfoOptimizationBase::Argument NV
size_t capacity() const
Return the total number of elements in the currently allocated buffer.
LLVM_ATTRIBUTE_ALWAYS_INLINE reference operator[](size_type idx)
#define LLVM_UNLIKELY(EXPR)
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator end() const
const SmallVector & operator=(SmallVector &&RHS)
static size_t capacity_in_bytes(const BitVector &X)
iterator insert(iterator I, const T &Elt)
iterator insert(iterator I, size_type NumToInsert, const T &Elt)
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...
const_iterator begin(StringRef path)
Get begin iterator over path.
void append(size_type NumInputs, const T &Elt)
Add the specified range to the end of the SmallVector.
size_t capacity_in_bytes() const
capacity_in_bytes - This returns capacity()*sizeof(T).
void reserve(size_type N)
const T & const_reference
SmallVectorTemplateBase(size_t Size)
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...
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void resize(size_type N, const T &NV)
LLVM_NODISCARD bool empty() const
LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator begin() const
void assign(size_type NumElts, const T &Elt)
const_reverse_iterator rend() const
SmallVectorTemplateBase(size_t Size)
SmallVector(SmallVectorImpl< T > &&RHS)
const SmallVector & operator=(const SmallVector &RHS)
ptrdiff_t difference_type
SmallVector(SmallVector &&RHS)
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
SmallVectorTemplateBase<isPodLike = false> - This is where we put method implementations that are desig...
const_reference front() const
bool operator==(const SmallVectorImpl &RHS) const
void swap(SmallVectorImpl &RHS)
const_reference back() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
void grow(size_t MinSize=0)
Grow the allocated memory (without initializing new elements), doubling the size of the allocated mem...
bool operator!=(const SmallVectorImpl &RHS) const
SmallVectorImpl(unsigned N)
bool operator<(const SmallVectorImpl &RHS) const
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
LLVM_ATTRIBUTE_ALWAYS_INLINE const_reference operator[](size_type idx) const
SmallVectorBase(void *FirstEl, size_t Size)
void assign(std::initializer_list< T > IL)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
uint64_t NextPowerOf2(uint64_t A)
NextPowerOf2 - Returns the next power of two (in 64-bits) that is strictly greater than A...
iterator erase(const_iterator CI)
SmallVector(const iterator_range< RangeTy > &R)
const_iterator capacity_ptr() const
isPodLike - This is a type trait that is used to determine whether a given type can be copied around ...
const SmallVector & operator=(SmallVectorImpl< T > &&RHS)
SuperClass::const_iterator const_iterator
SmallVector(ItTy S, ItTy E)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool isSmall() const
Return true if this is a smallvector which has not had dynamic memory allocated for it...
void grow(size_t MinSize=0)
Double the size of the allocated memory, guaranteeing space for at least one more element or MinSize ...
std::reverse_iterator< const_iterator > const_reverse_iterator
iterator insert(iterator I, ItTy From, ItTy To)
SmallVectorTemplateCommon< T >::U InlineElts[N-1]
LLVM_NODISCARD T pop_back_val()
SmallVector(std::initializer_list< T > IL)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A range adaptor for a pair of iterators.
void append(std::initializer_list< T > IL)
SmallVectorImpl & operator=(const SmallVectorImpl &RHS)
iterator insert(iterator I, T &&Elt)
SuperClass::size_type size_type
void insert(iterator I, std::initializer_list< T > IL)
static void destroy_range(T *S, T *E)
iterator erase(const_iterator CS, const_iterator CE)
This is the part of SmallVectorTemplateBase which does not depend on whether the type T is a POD...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void set_size(size_type N)
Set the array size to N, which the current array must have enough capacity for.
void emplace_back(ArgTypes &&...Args)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest, typename std::enable_if< std::is_same< typename std::remove_const< T1 >::type, T2 >::value >::type *=nullptr)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
This is all the non-templated stuff common to all SmallVectors.
size_t size_in_bytes() const
This returns size()*sizeof(T).
SmallVectorTemplateCommon(size_t Size)
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
SmallVector(const SmallVector &RHS)
reverse_iterator rbegin()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
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 ...
void grow_pod(size_t MinSizeInBytes, size_t TSize)
static void destroy_range(T *, T *)
void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize)
This is an implementation of the grow() method which only works on POD-like data types and is out of ...
Storage for the SmallVector elements which aren't contained in SmallVectorTemplateCommon.
size_type max_size() const
const SmallVector & operator=(std::initializer_list< T > IL)
void resetToSmall()
Put this vector in a state of being small.
const_pointer data() const
Return a pointer to the vector's buffer, even if empty().
SmallVector(size_t Size, const T &Value=T())
const_reverse_iterator rbegin() const