mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 14:20:29 +00:00
factor out the grow() method for all pod implementations into one
common function. It is still an inline method, which will be fixed next. llvm-svn: 91526
This commit is contained in:
parent
f6bcc2747e
commit
7ea3176b0c
@ -80,9 +80,42 @@ protected:
|
||||
return BeginX == static_cast<const void*>(&FirstEl);
|
||||
}
|
||||
|
||||
/// size_in_bytes - This returns size()*sizeof(T).
|
||||
size_t size_in_bytes() const {
|
||||
return size_t((char*)EndX - (char*)BeginX);
|
||||
}
|
||||
|
||||
/// capacity_in_bytes - This returns capacity()*sizeof(T).
|
||||
size_t capacity_in_bytes() const {
|
||||
return size_t((char*)CapacityX - (char*)BeginX);
|
||||
}
|
||||
|
||||
inline void grow_pod(size_t MinSizeInBytes, size_t TSize);
|
||||
|
||||
public:
|
||||
bool empty() const { return BeginX == EndX; }
|
||||
};
|
||||
|
||||
inline void SmallVectorBase::grow_pod(size_t MinSizeInBytes, size_t TSize) {
|
||||
size_t CurSizeBytes = size_in_bytes();
|
||||
size_t NewCapacityInBytes = 2 * capacity_in_bytes();
|
||||
if (NewCapacityInBytes < MinSizeInBytes)
|
||||
NewCapacityInBytes = MinSizeInBytes;
|
||||
void *NewElts = operator new(NewCapacityInBytes);
|
||||
|
||||
// Copy the elements over.
|
||||
memcpy(NewElts, this->BeginX, CurSizeBytes);
|
||||
|
||||
// If this wasn't grown from the inline copy, deallocate the old space.
|
||||
if (!this->isSmall())
|
||||
operator delete(this->BeginX);
|
||||
|
||||
this->EndX = (char*)NewElts+CurSizeBytes;
|
||||
this->BeginX = NewElts;
|
||||
this->CapacityX = (char*)this->BeginX + NewCapacityInBytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
class SmallVectorTemplateCommon : public SmallVectorBase {
|
||||
@ -178,8 +211,37 @@ public:
|
||||
std::uninitialized_copy(I, E, Dest);
|
||||
}
|
||||
|
||||
/// grow - double the size of the allocated memory, guaranteeing space for at
|
||||
/// least one more element or MinSize if specified.
|
||||
void grow(size_t MinSize = 0);
|
||||
};
|
||||
|
||||
// Define this out-of-line to dissuade the C++ compiler from inlining it.
|
||||
template <typename T, bool isPodLike>
|
||||
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
|
||||
size_t CurCapacity = this->capacity();
|
||||
size_t CurSize = this->size();
|
||||
size_t NewCapacity = 2*CurCapacity;
|
||||
if (NewCapacity < MinSize)
|
||||
NewCapacity = MinSize;
|
||||
T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T)));
|
||||
|
||||
// Copy the elements over.
|
||||
uninitialized_copy(this->begin(), this->end(), NewElts);
|
||||
|
||||
// Destroy the original elements.
|
||||
destroy_range(this->begin(), this->end());
|
||||
|
||||
// If this wasn't grown from the inline copy, deallocate the old space.
|
||||
if (!this->isSmall())
|
||||
operator delete(this->begin());
|
||||
|
||||
setEnd(NewElts+CurSize);
|
||||
this->BeginX = NewElts;
|
||||
this->CapacityX = this->begin()+NewCapacity;
|
||||
}
|
||||
|
||||
|
||||
/// SmallVectorTemplateBase<isPodLike = true> - This is where we put method
|
||||
/// implementations that are designed to work with POD-like T's.
|
||||
template <typename T>
|
||||
@ -198,6 +260,12 @@ public:
|
||||
// is better.
|
||||
memcpy(&*Dest, &*I, (E-I)*sizeof(T));
|
||||
}
|
||||
|
||||
/// grow - double the size of the allocated memory, guaranteeing space for at
|
||||
/// least one more element or MinSize if specified.
|
||||
void grow(size_t MinSize = 0) {
|
||||
this->grow_pod(MinSize*sizeof(T), sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -237,7 +305,7 @@ public:
|
||||
this->setEnd(this->begin()+N);
|
||||
} else if (N > this->size()) {
|
||||
if (this->capacity() < N)
|
||||
grow(N);
|
||||
this->grow(N);
|
||||
this->construct_range(this->end(), this->begin()+N, T());
|
||||
this->setEnd(this->begin()+N);
|
||||
}
|
||||
@ -249,7 +317,7 @@ public:
|
||||
setEnd(this->begin()+N);
|
||||
} else if (N > this->size()) {
|
||||
if (this->capacity() < N)
|
||||
grow(N);
|
||||
this->grow(N);
|
||||
construct_range(this->end(), this->begin()+N, NV);
|
||||
setEnd(this->begin()+N);
|
||||
}
|
||||
@ -257,7 +325,7 @@ public:
|
||||
|
||||
void reserve(unsigned N) {
|
||||
if (this->capacity() < N)
|
||||
grow(N);
|
||||
this->grow(N);
|
||||
}
|
||||
|
||||
void push_back(const T &Elt) {
|
||||
@ -292,7 +360,7 @@ public:
|
||||
size_type NumInputs = std::distance(in_start, in_end);
|
||||
// Grow allocated space if needed.
|
||||
if (NumInputs > size_type(this->capacity_ptr()-this->end()))
|
||||
grow(this->size()+NumInputs);
|
||||
this->grow(this->size()+NumInputs);
|
||||
|
||||
// Copy the new elements over.
|
||||
// TODO: NEED To compile time dispatch on whether in_iter is a random access
|
||||
@ -306,7 +374,7 @@ public:
|
||||
void append(size_type NumInputs, const T &Elt) {
|
||||
// Grow allocated space if needed.
|
||||
if (NumInputs > size_type(this->capacity_ptr()-this->end()))
|
||||
grow(this->size()+NumInputs);
|
||||
this->grow(this->size()+NumInputs);
|
||||
|
||||
// Copy the new elements over.
|
||||
std::uninitialized_fill_n(this->end(), NumInputs, Elt);
|
||||
@ -316,7 +384,7 @@ public:
|
||||
void assign(unsigned NumElts, const T &Elt) {
|
||||
clear();
|
||||
if (this->capacity() < NumElts)
|
||||
grow(NumElts);
|
||||
this->grow(NumElts);
|
||||
setEnd(this->begin()+NumElts);
|
||||
construct_range(this->begin(), this->end(), Elt);
|
||||
}
|
||||
@ -488,10 +556,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
/// grow - double the size of the allocated memory, guaranteeing space for at
|
||||
/// least one more element or MinSize if specified.
|
||||
void grow(size_t MinSize = 0);
|
||||
|
||||
static void construct_range(T *S, T *E, const T &Elt) {
|
||||
for (; S != E; ++S)
|
||||
new (S) T(Elt);
|
||||
@ -499,31 +563,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// Define this out-of-line to dissuade the C++ compiler from inlining it.
|
||||
template <typename T>
|
||||
void SmallVectorImpl<T>::grow(size_t MinSize) {
|
||||
size_t CurCapacity = this->capacity();
|
||||
size_t CurSize = this->size();
|
||||
size_t NewCapacity = 2*CurCapacity;
|
||||
if (NewCapacity < MinSize)
|
||||
NewCapacity = MinSize;
|
||||
T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T)));
|
||||
|
||||
// Copy the elements over.
|
||||
uninitialized_copy(this->begin(), this->end(), NewElts);
|
||||
|
||||
// Destroy the original elements.
|
||||
destroy_range(this->begin(), this->end());
|
||||
|
||||
// If this wasn't grown from the inline copy, deallocate the old space.
|
||||
if (!this->isSmall())
|
||||
operator delete(this->begin());
|
||||
|
||||
setEnd(NewElts+CurSize);
|
||||
this->BeginX = NewElts;
|
||||
this->CapacityX = this->begin()+NewCapacity;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
|
||||
if (this == &RHS) return;
|
||||
@ -536,7 +575,7 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
|
||||
return;
|
||||
}
|
||||
if (RHS.size() > this->capacity())
|
||||
grow(RHS.size());
|
||||
this->grow(RHS.size());
|
||||
if (this->size() > RHS.capacity())
|
||||
RHS.grow(this->size());
|
||||
|
||||
@ -595,7 +634,7 @@ const SmallVectorImpl<T> &SmallVectorImpl<T>::
|
||||
destroy_range(this->begin(), this->end());
|
||||
setEnd(this->begin());
|
||||
CurSize = 0;
|
||||
grow(RHSSize);
|
||||
this->grow(RHSSize);
|
||||
} else if (CurSize) {
|
||||
// Otherwise, use assignment for the already-constructed elements.
|
||||
std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
|
||||
|
Loading…
Reference in New Issue
Block a user