aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-12-16 08:34:40 +0000
committerChris Lattner <sabre@nondot.org>2009-12-16 08:34:40 +0000
commit99ea87a48a3a891dbf5f4cb89179610a5f3f84cf (patch)
treea814a850950d619a4342f48e6282a21ef3e09508
parent6bc2b8b215240e564b8f255e45e429823c2004f3 (diff)
factor out the grow() method for all pod implementations into one
common function. It is still an inline method, which will be fixed next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91526 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/SmallVector.h113
1 files changed, 76 insertions, 37 deletions
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 55634a02db..0e076c8beb 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -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());