mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-22 04:22:57 +02:00
Split SmallVector into SmallVector and SmallVectorImpl, which allows us to
eliminate code duplication due to the 'N' parameter. llvm-svn: 29634
This commit is contained in:
parent
2428c13b4e
commit
6c9bcb32a3
@ -20,63 +20,39 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
|
/// SmallVectorImpl - This class consists of common code factored out of the
|
||||||
/// for the case when the array is small. It contains some number of elements
|
/// SmallVector class to reduce code duplication based on the SmallVector 'N'
|
||||||
/// in-place, which allows it to avoid heap allocation when the actual number of
|
/// template parameter.
|
||||||
/// elements is below that threshold. This allows normal "small" cases to be
|
template <typename T>
|
||||||
/// fast without losing generality for large inputs.
|
class SmallVectorImpl {
|
||||||
///
|
T *Begin, *End, *Capacity;
|
||||||
/// Note that this does not attempt to be exception safe.
|
|
||||||
///
|
|
||||||
template <typename T, unsigned N>
|
|
||||||
class SmallVector {
|
|
||||||
// Allocate raw space for N elements of type T. If T has a ctor or dtor, we
|
// Allocate raw space for N elements of type T. If T has a ctor or dtor, we
|
||||||
// don't want it to be automatically run, so we need to represent the space as
|
// don't want it to be automatically run, so we need to represent the space as
|
||||||
// something else. An array of char would work great, but might not be
|
// something else. An array of char would work great, but might not be
|
||||||
// aligned sufficiently. Instead, we either use GCC extensions, or some
|
// aligned sufficiently. Instead, we either use GCC extensions, or some
|
||||||
// number of union instances for the space, which guarantee maximal alignment.
|
// number of union instances for the space, which guarantee maximal alignment.
|
||||||
|
protected:
|
||||||
union U {
|
union U {
|
||||||
double D;
|
double D;
|
||||||
long double LD;
|
long double LD;
|
||||||
long long L;
|
long long L;
|
||||||
void *P;
|
void *P;
|
||||||
};
|
} FirstEl;
|
||||||
|
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
|
||||||
/// InlineElts - These are the 'N' elements that are stored inline in the body
|
|
||||||
/// of the vector
|
|
||||||
U InlineElts[(sizeof(T)*N+sizeof(U)-1)/sizeof(U)];
|
|
||||||
T *Begin, *End, *Capacity;
|
|
||||||
public:
|
public:
|
||||||
// Default ctor - Initialize to empty.
|
// Default ctor - Initialize to empty.
|
||||||
SmallVector() : Begin((T*)InlineElts), End(Begin), Capacity(Begin+N) {
|
SmallVectorImpl(unsigned N)
|
||||||
|
: Begin((T*)&FirstEl), End((T*)&FirstEl), Capacity((T*)&FirstEl+N) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ItTy>
|
~SmallVectorImpl() {
|
||||||
SmallVector(ItTy S, ItTy E)
|
|
||||||
: Begin((T*)InlineElts), End(Begin), Capacity(Begin+N) {
|
|
||||||
append(S, E);
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallVector(const SmallVector &RHS) {
|
|
||||||
unsigned RHSSize = RHS.size();
|
|
||||||
Begin = (T*)InlineElts;
|
|
||||||
|
|
||||||
// Doesn't fit in the small case? Allocate space.
|
|
||||||
if (RHSSize > N) {
|
|
||||||
End = Capacity = Begin;
|
|
||||||
grow(RHSSize);
|
|
||||||
}
|
|
||||||
End = Begin+RHSSize;
|
|
||||||
Capacity = Begin+N;
|
|
||||||
std::uninitialized_copy(RHS.begin(), RHS.end(), Begin);
|
|
||||||
}
|
|
||||||
~SmallVector() {
|
|
||||||
// Destroy the constructed elements in the vector.
|
// Destroy the constructed elements in the vector.
|
||||||
for (iterator I = Begin, E = End; I != E; ++I)
|
for (iterator I = Begin, E = End; I != E; ++I)
|
||||||
I->~T();
|
I->~T();
|
||||||
|
|
||||||
// If this wasn't grown from the inline copy, deallocate the old space.
|
// If this wasn't grown from the inline copy, deallocate the old space.
|
||||||
if ((void*)Begin != (void*)InlineElts)
|
if (!isSmall())
|
||||||
delete[] (char*)Begin;
|
delete[] (char*)Begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +131,7 @@ public:
|
|||||||
new (Begin+NumElts-1) T(Elt);
|
new (Begin+NumElts-1) T(Elt);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SmallVector &operator=(const SmallVector &RHS) {
|
const SmallVectorImpl &operator=(const SmallVectorImpl &RHS) {
|
||||||
// Avoid self-assignment.
|
// Avoid self-assignment.
|
||||||
if (this == &RHS) return *this;
|
if (this == &RHS) return *this;
|
||||||
|
|
||||||
@ -201,7 +177,7 @@ private:
|
|||||||
/// isSmall - Return true if this is a smallvector which has not had dynamic
|
/// isSmall - Return true if this is a smallvector which has not had dynamic
|
||||||
/// memory allocated for it.
|
/// memory allocated for it.
|
||||||
bool isSmall() const {
|
bool isSmall() const {
|
||||||
return (void*)Begin == (void*)InlineElts;
|
return (void*)Begin == (void*)&FirstEl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// grow - double the size of the allocated memory, guaranteeing space for at
|
/// grow - double the size of the allocated memory, guaranteeing space for at
|
||||||
@ -231,6 +207,35 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
|
||||||
|
/// for the case when the array is small. It contains some number of elements
|
||||||
|
/// in-place, which allows it to avoid heap allocation when the actual number of
|
||||||
|
/// elements is below that threshold. This allows normal "small" cases to be
|
||||||
|
/// fast without losing generality for large inputs.
|
||||||
|
///
|
||||||
|
/// Note that this does not attempt to be exception safe.
|
||||||
|
///
|
||||||
|
template <typename T, unsigned N>
|
||||||
|
class SmallVector : public SmallVectorImpl<T> {
|
||||||
|
/// InlineElts - These are 'N-1' elements that are stored inline in the body
|
||||||
|
/// of the vector. The extra '1' element is stored in SmallVectorImpl.
|
||||||
|
typedef typename SmallVectorImpl<T>::U U;
|
||||||
|
U InlineElts[(sizeof(T)*N+sizeof(U)-1)/sizeof(U) - 1];
|
||||||
|
public:
|
||||||
|
SmallVector() : SmallVectorImpl<T>(N) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ItTy>
|
||||||
|
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
|
||||||
|
append(S, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
|
||||||
|
operator=(RHS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user