57 #ifndef __SmallVector_H 58 #define __SmallVector_H 74 template<
class T1,
class T2>
75 inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
76 _Scalar_ptr_iterator_tag _Cat;
80 template<
class T1,
class T2>
81 inline _Scalar_ptr_iterator_tag _Ptr_cat(T1*
const *, T2 **) {
82 _Scalar_ptr_iterator_tag _Cat;
95 template <
typename T>
struct isPodLike {
static const bool value =
false; };
97 template <>
struct isPodLike<bool> {
static const bool value =
true; };
98 template <>
struct isPodLike<char> {
static const bool value =
true; };
99 template <>
struct isPodLike<signed char> {
static const bool value =
true; };
100 template <>
struct isPodLike<unsigned char> {
static const bool value =
true; };
101 template <>
struct isPodLike<int> {
static const bool value =
true; };
102 template <>
struct isPodLike<unsigned> {
static const bool value =
true; };
103 template <>
struct isPodLike<short> {
static const bool value =
true; };
104 template <>
struct isPodLike<unsigned short> {
static const bool value =
true; };
105 template <>
struct isPodLike<long> {
static const bool value =
true; };
106 template <>
struct isPodLike<unsigned long> {
static const bool value =
true; };
107 template <>
struct isPodLike<float> {
static const bool value =
true; };
108 template <>
struct isPodLike<double> {
static const bool value =
true; };
109 template <
typename T>
struct isPodLike<T*> {
static const bool value =
true; };
111 template<
typename T,
typename U>
118 void *BeginX, *
EndX, *CapacityX;
135 : BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {}
140 return BeginX ==
static_cast<const void*
>(&FirstEl);
145 return size_t((
char*)EndX - (
char*)BeginX);
150 return size_t((
char*)CapacityX - (
char*)BeginX);
155 void grow_pod(
size_t MinSizeInBytes,
size_t TSize);
158 bool empty()
const {
return BeginX == EndX; }
162 template <
typename T>
184 iterator
begin() {
return (iterator)this->BeginX; }
185 const_iterator
begin()
const {
return (const_iterator)this->BeginX; }
186 iterator
end() {
return (iterator)this->EndX; }
187 const_iterator
end()
const {
return (const_iterator)this->EndX; }
190 const_iterator
capacity_ptr()
const {
return (const_iterator)this->CapacityX;}
194 reverse_iterator
rbegin() {
return reverse_iterator(end()); }
195 const_reverse_iterator
rbegin()
const{
return const_reverse_iterator(end()); }
196 reverse_iterator
rend() {
return reverse_iterator(begin()); }
197 const_reverse_iterator
rend()
const {
return const_reverse_iterator(begin());}
199 size_type
size()
const {
return end()-begin(); }
200 size_type
max_size()
const {
return size_type(-1) /
sizeof(T); }
204 size_t capacity()
const {
return capacity_ptr() - begin(); }
207 pointer
data() {
return pointer(begin()); }
209 const_pointer
data()
const {
return const_pointer(begin()); }
212 assert(begin() + idx < end());
216 assert(begin() + idx < end());
237 template <
typename T,
bool isPodLike>
251 template<
typename It1,
typename It2>
253 std::uninitialized_copy(I, E, Dest);
258 void grow(
size_t MinSize = 0);
262 template <
typename T,
bool isPodLike>
264 size_t CurCapacity = this->capacity();
265 size_t CurSize = this->size();
266 size_t NewCapacity = 2*CurCapacity + 1;
267 if (NewCapacity < MinSize)
268 NewCapacity = MinSize;
269 T *NewElts =
static_cast<T*
>(malloc(NewCapacity*
sizeof(T)));
272 this->uninitialized_copy(this->begin(), this->end(), NewElts);
275 destroy_range(this->begin(), this->end());
278 if (!this->isSmall())
281 this->setEnd(NewElts+CurSize);
282 this->BeginX = NewElts;
283 this->CapacityX = this->begin()+NewCapacity;
289 template <
typename T>
299 template<
typename It1,
typename It2>
302 std::uninitialized_copy(I, E, Dest);
307 template<
typename T1,
typename T2>
312 memcpy(Dest, I, (E-I)*
sizeof(T));
317 void grow(
size_t MinSize = 0) {
318 this->grow_pod(MinSize*
sizeof(T),
sizeof(T));
326 template <
typename T>
342 this->destroy_range(this->begin(), this->end());
345 if (!this->isSmall())
351 this->destroy_range(this->begin(), this->end());
352 this->EndX = this->BeginX;
356 if (N < this->size()) {
357 this->destroy_range(this->begin()+N, this->end());
358 this->setEnd(this->begin()+N);
359 }
else if (N > this->size()) {
360 if (this->capacity() < N)
362 this->construct_range(this->end(), this->begin()+N, T());
363 this->setEnd(this->begin()+N);
368 if (N < this->size()) {
369 this->destroy_range(this->begin()+N, this->end());
370 this->setEnd(this->begin()+N);
371 }
else if (N > this->size()) {
372 if (this->capacity() < N)
374 construct_range(this->end(), this->begin()+N, NV);
375 this->setEnd(this->begin()+N);
380 if (this->capacity() < N)
385 if (this->EndX < this->CapacityX) {
387 new (this->end()) T(Elt);
388 this->setEnd(this->end()+1);
396 this->setEnd(this->end()-1);
401 T Result = this->back();
410 template<
typename in_iter>
411 void append(in_iter in_start, in_iter in_end) {
412 size_type NumInputs = std::distance(in_start, in_end);
414 if (NumInputs > size_type(this->capacity_ptr()-this->end()))
415 this->grow(this->size()+NumInputs);
420 std::uninitialized_copy(in_start, in_end, this->end());
421 this->setEnd(this->end() + NumInputs);
426 void append(size_type NumInputs,
const T &Elt) {
428 if (NumInputs > size_type(this->capacity_ptr()-this->end()))
429 this->grow(this->size()+NumInputs);
432 std::uninitialized_fill_n(this->end(), NumInputs, Elt);
433 this->setEnd(this->end() + NumInputs);
436 void assign(
unsigned NumElts,
const T &Elt) {
438 if (this->capacity() < NumElts)
440 this->setEnd(this->begin()+NumElts);
441 construct_range(this->begin(), this->end(), Elt);
447 std::copy(I+1, this->end(), I);
453 iterator
erase(iterator S, iterator E) {
456 iterator I = std::copy(E, this->end(), S);
458 this->destroy_range(I, this->end());
463 iterator
insert(iterator I,
const T &Elt) {
464 if (I == this->end()) {
466 return this->end()-1;
469 if (this->EndX < this->CapacityX) {
471 new (this->end()) T(this->back());
472 this->setEnd(this->end()+1);
474 std::copy_backward(I, this->end()-1, this->end());
478 size_t EltNo = I-this->begin();
480 I = this->begin()+EltNo;
484 iterator
insert(iterator I, size_type NumToInsert,
const T &Elt) {
485 if (I == this->end()) {
486 append(NumToInsert, Elt);
487 return this->end()-1;
491 size_t InsertElt = I - this->begin();
494 reserve(static_cast<unsigned>(this->size() + NumToInsert));
497 I = this->begin()+InsertElt;
503 if (
size_t(this->end()-I) >= NumToInsert) {
504 T *OldEnd = this->end();
505 append(this->end()-NumToInsert, this->end());
508 std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
510 std::fill_n(I, NumToInsert, Elt);
518 T *OldEnd = this->end();
519 this->setEnd(this->end() + NumToInsert);
520 size_t NumOverwritten = OldEnd-I;
521 this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
524 std::fill_n(I, NumOverwritten, Elt);
527 std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
531 template<
typename ItTy>
532 iterator
insert(iterator I, ItTy From, ItTy To) {
533 if (I == this->end()) {
535 return this->end()-1;
538 size_t NumToInsert = std::distance(From, To);
540 size_t InsertElt = I - this->begin();
543 reserve(static_cast<unsigned>(this->size() + NumToInsert));
546 I = this->begin()+InsertElt;
552 if (
size_t(this->end()-I) >= NumToInsert) {
553 T *OldEnd = this->end();
554 append(this->end()-NumToInsert, this->end());
557 std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
559 std::copy(From, To, I);
567 T *OldEnd = this->end();
568 this->setEnd(this->end() + NumToInsert);
569 size_t NumOverwritten = OldEnd-I;
570 this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
573 for (; NumOverwritten > 0; --NumOverwritten) {
579 this->uninitialized_copy(From, To, OldEnd);
587 if (this->size() != RHS.
size())
return false;
588 return std::equal(this->begin(), this->end(), RHS.
begin());
591 return !(*
this == RHS);
595 return std::lexicographical_compare(this->begin(), this->end(),
609 assert(N <= this->capacity());
610 this->setEnd(this->begin() + N);
621 template <
typename T>
623 if (
this == &RHS)
return;
626 if (!this->isSmall() && !RHS.
isSmall()) {
632 if (RHS.
size() > this->capacity())
633 this->grow(RHS.
size());
635 RHS.
grow(this->size());
638 size_t NumShared = this->size();
639 if (NumShared > RHS.
size()) NumShared = RHS.
size();
640 for (
unsigned i = 0; i !=
static_cast<unsigned>(NumShared); ++i)
644 if (this->size() > RHS.
size()) {
645 size_t EltDiff = this->size() - RHS.
size();
646 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.
end());
648 this->destroy_range(this->begin()+NumShared, this->end());
649 this->setEnd(this->begin()+NumShared);
650 }
else if (RHS.
size() > this->size()) {
651 size_t EltDiff = RHS.
size() - this->size();
652 this->uninitialized_copy(RHS.
begin()+NumShared, RHS.
end(), this->end());
653 this->setEnd(this->end() + EltDiff);
654 this->destroy_range(RHS.
begin()+NumShared, RHS.
end());
659 template <
typename T>
663 if (
this == &RHS)
return *
this;
667 size_t RHSSize = RHS.
size();
668 size_t CurSize = this->size();
669 if (CurSize >= RHSSize) {
673 NewEnd = std::copy(RHS.
begin(), RHS.
begin()+RHSSize, this->begin());
675 NewEnd = this->begin();
678 this->destroy_range(NewEnd, this->end());
681 this->setEnd(NewEnd);
687 if (this->capacity() < RHSSize) {
689 this->destroy_range(this->begin(), this->end());
690 this->setEnd(this->begin());
693 }
else if (CurSize) {
695 std::copy(RHS.
begin(), RHS.
begin()+CurSize, this->begin());
699 this->uninitialized_copy(RHS.
begin()+CurSize, RHS.
end(),
700 this->begin()+CurSize);
703 this->setEnd(this->begin()+RHSSize);
716 template <
typename T,
unsigned N>
723 MinUs = (
static_cast<unsigned int>(
sizeof(T))*N +
724 static_cast<unsigned int>(
sizeof(U)) - 1) /
725 static_cast<unsigned int>(
sizeof(U)),
730 NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
734 NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(
sizeof(U))/
735 static_cast<unsigned int>(
sizeof(T))
737 U InlineElts[NumInlineEltsElts];
746 this->push_back(Value);
749 template<
typename ItTy>
769 template <
typename T>
778 this->push_back(Value);
781 template<
typename ItTy>
807 template<
typename T,
unsigned N>
iterator erase(iterator S, iterator E)
const_reverse_iterator rbegin() const
SmallVectorTemplateBase< T, isPodLike< T >::value > SuperClass
SmallVectorImpl(unsigned N)
const_reference back() const
const_reference front() const
SmallVectorBase(size_t Size)
const T & const_reference
pointer data()
data - Return a pointer to the vector's buffer, even if empty().
SmallVectorImpl< T >::U U
InlineElts - These are 'N-1' elements that are stored inline in the body of the vector.
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
uninitialized_copy - Copy the range [I, E) onto the uninitialized memory starting with "Dest"...
const_iterator end() const
SmallVector(unsigned Size, const T &Value=T())
const_pointer data() const
data - Return a pointer to the vector's buffer, even if empty().
void swap(Ogre::SmallVector< T, N > &LHS, Ogre::SmallVector< T, N > &RHS)
Implement std::swap in terms of SmallVector swap.
iterator erase(iterator I)
SuperClass::iterator iterator
SmallVectorTemplateBase(size_t Size)
ptrdiff_t difference_type
const_reference operator[](unsigned idx) const
reference operator[](unsigned idx)
iterator insert(iterator I, ItTy From, ItTy To)
void resize(unsigned N, const T &NV)
bool operator!=(const SmallVectorImpl &RHS) const
SmallVector(unsigned Size, const T &Value=T())
size_t capacity_in_bytes() const
capacity_in_bytes - This returns capacity()*sizeof(T).
void push_back(const T &Elt)
SmallVectorImpl - This class consists of common code factored out of the SmallVector class to reduce ...
static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest)
uninitialized_copy - Copy the range [I, E) onto the uninitialized memory starting with "Dest"...
static void construct_range(T *S, T *E, const T &Elt)
void assign(unsigned NumElts, const T &Elt)
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
uninitialized_copy - Copy the range [I, E) onto the uninitialized memory starting with "Dest"...
const_iterator begin() const
bool operator<(const SmallVectorImpl &RHS) const
void set_size(unsigned N)
set_size - Set the array size to
SmallVector(ItTy S, ItTy E)
const SmallVector & operator=(const SmallVector &RHS)
SmallVector(const SmallVector &RHS)
const_reverse_iterator rend() const
bool operator==(const SmallVectorImpl &RHS) const
void swap(Ogre::SmallVectorImpl< T > &LHS, Ogre::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
SmallVectorTemplateCommon(size_t Size)
SuperClass::size_type size_type
size_t capacity() const
capacity - Return the total number of elements in the currently allocated buffer. ...
size_type max_size() const
SmallVector(ItTy S, ItTy E)
void swap(SmallVectorImpl &RHS)
SmallVectorTemplateBase(size_t Size)
SmallVector - This is a 'vector' (really, a variable-sized array), optimized for the case when the ar...
const_iterator capacity_ptr() const
iterator insert(iterator I, const T &Elt)
SmallVectorBase - This is all the non-templated stuff common to all SmallVectors. ...
std::reverse_iterator< const_iterator > const_reverse_iterator
iterator insert(iterator I, size_type NumToInsert, const T &Elt)
static void destroy_range(T *S, T *E)
void grow(size_t MinSize=0)
grow - double the size of the allocated memory, guaranteeing space for at least one more element or M...
void grow(size_t MinSize=0)
grow - double the size of the allocated memory, guaranteeing space for at least one more element or M...
std::reverse_iterator< iterator > reverse_iterator
SmallVector & operator=(const SmallVectorImpl< T > &RHS)
bool isSmall() const
isSmall - Return true if this is a smallvector which has not had dynamic memory allocated for it...
void append(size_type NumInputs, const T &Elt)
append - Add the specified range to the end of the SmallVector.
reverse_iterator rbegin()
SmallVector(const SmallVector &RHS)
void append(in_iter in_start, in_iter in_end)
append - Add the specified range to the end of the SmallVector.
size_t size_in_bytes() const
size_in_bytes - This returns size()*sizeof(T).
static void destroy_range(T *, T *)
SmallVectorTemplateBase<isPodLike = false> - This is where we put method implementations that are des...