mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
add a bunch more operations, including swap, insert, erase, front(), and
bugfixes for operator=. llvm-svn: 29811
This commit is contained in:
parent
b2b6c561f6
commit
19d59ce917
@ -48,8 +48,7 @@ public:
|
|||||||
|
|
||||||
~SmallVectorImpl() {
|
~SmallVectorImpl() {
|
||||||
// Destroy the constructed elements in the vector.
|
// Destroy the constructed elements in the vector.
|
||||||
for (iterator I = Begin, E = End; I != E; ++I)
|
destroy_range(Begin, End);
|
||||||
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 (!isSmall())
|
if (!isSmall())
|
||||||
@ -78,6 +77,13 @@ public:
|
|||||||
return Begin[idx];
|
return Begin[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reference front() {
|
||||||
|
return begin()[0];
|
||||||
|
}
|
||||||
|
const_reference front() const {
|
||||||
|
return begin()[0];
|
||||||
|
}
|
||||||
|
|
||||||
reference back() {
|
reference back() {
|
||||||
return end()[-1];
|
return end()[-1];
|
||||||
}
|
}
|
||||||
@ -102,9 +108,44 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
while (End != Begin) {
|
destroy_range(Begin, End);
|
||||||
End->~T();
|
End = Begin;
|
||||||
--End;
|
}
|
||||||
|
|
||||||
|
void swap(SmallVectorImpl &RHS) {
|
||||||
|
if (this == &RHS) return;
|
||||||
|
|
||||||
|
// We can only avoid copying elements if neither vector is small.
|
||||||
|
if (!isSmall() && !RHS.isSmall()) {
|
||||||
|
std::swap(Begin, RHS.Begin);
|
||||||
|
std::swap(End, RHS.End);
|
||||||
|
std::swap(Capacity, RHS.Capacity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Begin+RHS.size() > Capacity)
|
||||||
|
grow(RHS.size());
|
||||||
|
if (RHS.begin()+size() > RHS.Capacity)
|
||||||
|
RHS.grow(size());
|
||||||
|
|
||||||
|
// Swap the shared elements.
|
||||||
|
unsigned NumShared = size();
|
||||||
|
if (NumShared > RHS.size()) NumShared = RHS.size();
|
||||||
|
for (unsigned i = 0; i != NumShared; ++i)
|
||||||
|
std::swap(Begin[i], RHS[i]);
|
||||||
|
|
||||||
|
// Copy over the extra elts.
|
||||||
|
if (size() > RHS.size()) {
|
||||||
|
unsigned EltDiff = size() - RHS.size();
|
||||||
|
std::uninitialized_copy(Begin+NumShared, End, RHS.End);
|
||||||
|
RHS.End += EltDiff;
|
||||||
|
destroy_range(Begin+NumShared, End);
|
||||||
|
End = Begin+NumShared;
|
||||||
|
} else if (RHS.size() > size()) {
|
||||||
|
unsigned EltDiff = RHS.size() - size();
|
||||||
|
std::uninitialized_copy(RHS.Begin+NumShared, RHS.End, End);
|
||||||
|
End += EltDiff;
|
||||||
|
destroy_range(RHS.Begin+NumShared, RHS.End);
|
||||||
|
RHS.End = RHS.Begin+NumShared;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +172,42 @@ public:
|
|||||||
new (Begin+NumElts-1) T(Elt);
|
new (Begin+NumElts-1) T(Elt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void erase(iterator I) {
|
||||||
|
// Shift all elts down one.
|
||||||
|
std::copy(I+1, End, I);
|
||||||
|
// Drop the last elt.
|
||||||
|
pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase(iterator S, iterator E) {
|
||||||
|
// Shift all elts down.
|
||||||
|
iterator I = std::copy(E, End, S);
|
||||||
|
// Drop the last elts.
|
||||||
|
destroy_range(I, End);
|
||||||
|
End = I;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator insert(iterator I, const T &Elt) {
|
||||||
|
if (I == End) { // Important special case for empty vector.
|
||||||
|
push_back(Elt);
|
||||||
|
return end()-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (End < Capacity) {
|
||||||
|
Retry:
|
||||||
|
new (End) T(back());
|
||||||
|
++End;
|
||||||
|
// Push everything else over.
|
||||||
|
std::copy_backward(I, End-1, End);
|
||||||
|
*I = Elt;
|
||||||
|
return I;
|
||||||
|
}
|
||||||
|
unsigned EltNo = I-Begin;
|
||||||
|
grow();
|
||||||
|
I = Begin+EltNo;
|
||||||
|
goto Retry;
|
||||||
|
}
|
||||||
|
|
||||||
const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
|
const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -143,6 +220,13 @@ private:
|
|||||||
/// grow - double the size of the allocated memory, guaranteeing space for at
|
/// grow - double the size of the allocated memory, guaranteeing space for at
|
||||||
/// least one more element or MinSize if specified.
|
/// least one more element or MinSize if specified.
|
||||||
void grow(unsigned MinSize = 0);
|
void grow(unsigned MinSize = 0);
|
||||||
|
|
||||||
|
void destroy_range(T *S, T *E) {
|
||||||
|
while (S != E) {
|
||||||
|
E->~T();
|
||||||
|
--E;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define this out-of-line to dissuade the C++ compiler from inlining it.
|
// Define this out-of-line to dissuade the C++ compiler from inlining it.
|
||||||
@ -159,8 +243,7 @@ void SmallVectorImpl<T>::grow(unsigned MinSize) {
|
|||||||
std::uninitialized_copy(Begin, End, NewElts);
|
std::uninitialized_copy(Begin, End, NewElts);
|
||||||
|
|
||||||
// Destroy the original elements.
|
// Destroy the original elements.
|
||||||
for (iterator I = Begin, E = End; I != E; ++I)
|
destroy_range(Begin, End);
|
||||||
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 (!isSmall())
|
if (!isSmall())
|
||||||
@ -183,14 +266,13 @@ SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
|
|||||||
unsigned CurSize = size();
|
unsigned CurSize = size();
|
||||||
if (CurSize >= RHSSize) {
|
if (CurSize >= RHSSize) {
|
||||||
// Assign common elements.
|
// Assign common elements.
|
||||||
std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
|
iterator NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
|
||||||
|
|
||||||
// Destroy excess elements.
|
// Destroy excess elements.
|
||||||
for (unsigned i = RHSSize; i != CurSize; ++i)
|
destroy_range(NewEnd, End);
|
||||||
Begin[i].~T();
|
|
||||||
|
|
||||||
// Trim.
|
// Trim.
|
||||||
End = Begin + RHSSize;
|
End = NewEnd;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,8 +280,7 @@ SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
|
|||||||
// This allows us to avoid copying them during the grow.
|
// This allows us to avoid copying them during the grow.
|
||||||
if (unsigned(Capacity-Begin) < RHSSize) {
|
if (unsigned(Capacity-Begin) < RHSSize) {
|
||||||
// Destroy current elements.
|
// Destroy current elements.
|
||||||
for (iterator I = Begin, E = End; I != E; ++I)
|
destroy_range(Begin, End);
|
||||||
I->~T();
|
|
||||||
End = Begin;
|
End = Begin;
|
||||||
CurSize = 0;
|
CurSize = 0;
|
||||||
grow(RHSSize);
|
grow(RHSSize);
|
||||||
@ -255,8 +336,29 @@ public:
|
|||||||
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
|
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
|
||||||
operator=(RHS);
|
operator=(RHS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SmallVector &operator=(const SmallVector &RHS) {
|
||||||
|
SmallVectorImpl<T>::operator=(RHS);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
/// Implement std::swap in terms of SmallVector swap.
|
||||||
|
template<typename T>
|
||||||
|
inline void
|
||||||
|
swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
|
||||||
|
LHS.swap(RHS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implement std::swap in terms of SmallVector swap.
|
||||||
|
template<typename T, unsigned N>
|
||||||
|
inline void
|
||||||
|
swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
|
||||||
|
LHS.swap(RHS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user