diff options
author | Dan Gohman <gohman@apple.com> | 2008-10-16 00:15:24 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-10-16 00:15:24 +0000 |
commit | 611c36c226adfd2b4a3297e240be3b1e19e48e5f (patch) | |
tree | 90f1fdbdb77d44ba7d0fdc221e6c6aef793a36b9 /include/llvm/ADT/SmallVector.h | |
parent | f16ac7d41fa00ae7d7a3f694621c5c41ee3c697a (diff) | |
download | external_llvm-611c36c226adfd2b4a3297e240be3b1e19e48e5f.zip external_llvm-611c36c226adfd2b4a3297e240be3b1e19e48e5f.tar.gz external_llvm-611c36c226adfd2b4a3297e240be3b1e19e48e5f.tar.bz2 |
Implement a SmallVector insert method that can insert multiple
copies of a value, and add several additional utilities to make
SmallVector better conform to the Container concept.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57616 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/ADT/SmallVector.h')
-rw-r--r-- | include/llvm/ADT/SmallVector.h | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index a1373e2..9ece43f 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -91,6 +91,7 @@ public: } typedef size_t size_type; + typedef ptrdiff_t difference_type; typedef T value_type; typedef T* iterator; typedef const T* const_iterator; @@ -100,9 +101,12 @@ public: typedef T& reference; typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; bool empty() const { return Begin == End; } size_type size() const { return End-Begin; } + size_type max_size() const { return size_type(-1) / sizeof(T); } // forward iterator creation methods. iterator begin() { return Begin; } @@ -208,6 +212,18 @@ public: End += NumInputs; } + /// append - Add the specified range to the end of the SmallVector. + /// + void append(size_type NumInputs, const T &Elt) { + // Grow allocated space if needed. + if (End+NumInputs > Capacity) + grow(size()+NumInputs); + + // Copy the new elements over. + std::uninitialized_fill_n(End, NumInputs, Elt); + End += NumInputs; + } + void assign(unsigned NumElts, const T &Elt) { clear(); if (unsigned(Capacity-Begin) < NumElts) @@ -255,6 +271,52 @@ public: I = Begin+EltNo; goto Retry; } + + iterator insert(iterator I, size_type NumToInsert, const T &Elt) { + if (I == End) { // Important special case for empty vector. + append(NumToInsert, Elt); + return end()-1; + } + + // Convert iterator to elt# to avoid invalidating iterator when we reserve() + size_t InsertElt = I-begin(); + + // Ensure there is enough space. + reserve(static_cast<unsigned>(size() + NumToInsert)); + + // Uninvalidate the iterator. + I = begin()+InsertElt; + + // If we already have this many elements in the collection, append the + // dest elements at the end, then copy over the appropriate elements. Since + // we already reserved space, we know that this won't reallocate the vector. + if (size() >= NumToInsert) { + T *OldEnd = End; + append(End-NumToInsert, End); + + // Copy the existing elements that get replaced. + std::copy(I, OldEnd-NumToInsert, I+NumToInsert); + + std::fill_n(I, NumToInsert, Elt); + return I; + } + + // Otherwise, we're inserting more elements than exist already, and we're + // not inserting at the end. + + // Copy over the elements that we're about to overwrite. + T *OldEnd = End; + End += NumToInsert; + size_t NumOverwritten = OldEnd-I; + std::uninitialized_copy(I, OldEnd, End-NumOverwritten); + + // Replace the overwritten part. + std::fill_n(I, NumOverwritten, Elt); + + // Insert the non-overwritten middle part. + std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt); + return I; + } template<typename ItTy> iterator insert(iterator I, ItTy From, ItTy To) { |