diff options
Diffstat (limited to 'LibOVR/Src/Kernel/OVR_Deque.h')
-rw-r--r-- | LibOVR/Src/Kernel/OVR_Deque.h | 172 |
1 files changed, 96 insertions, 76 deletions
diff --git a/LibOVR/Src/Kernel/OVR_Deque.h b/LibOVR/Src/Kernel/OVR_Deque.h index ca242ad..8e57091 100644 --- a/LibOVR/Src/Kernel/OVR_Deque.h +++ b/LibOVR/Src/Kernel/OVR_Deque.h @@ -27,9 +27,11 @@ limitations under the License. #ifndef OVR_Deque_h #define OVR_Deque_h +#include "OVR_ContainerAllocator.h" + namespace OVR{ -template <class Elem> +template <class Elem, class Allocator = ContainerAllocator<Elem> > class Deque { public: @@ -48,8 +50,12 @@ public: virtual const Elem& PeekBack (int count = 0) const; // Returns count-th Item from the end virtual const Elem& PeekFront (int count = 0) const; // Returns count-th Item from the beginning - virtual inline UPInt GetSize (void) const; // Returns Number of Elements - virtual inline UPInt GetCapacity(void) const; // Returns the maximum possible number of elements + virtual inline size_t GetSize (void) const; // Returns Number of Elements + OVR_FORCE_INLINE int GetSizeI (void) const + { + return (int)GetSize(); + } + virtual inline size_t GetCapacity(void) const; // Returns the maximum possible number of elements virtual void Clear (void); // Remove all elements virtual inline bool IsEmpty () const; virtual inline bool IsFull () const; @@ -66,29 +72,33 @@ protected: private: Deque& operator= (const Deque& q) { }; // forbidden - Deque(const Deque<Elem> &OtherDeque) { }; + Deque(const Deque<Elem, Allocator> &OtherDeque) { }; }; -template <class Elem> -class InPlaceMutableDeque : public Deque<Elem> +template <class Elem, class Allocator = ContainerAllocator<Elem> > +class InPlaceMutableDeque : public Deque<Elem, Allocator> { + typedef Deque<Elem, Allocator> BaseType; + public: - InPlaceMutableDeque( int capacity = Deque<Elem>::DefaultCapacity ) : Deque<Elem>( capacity ) {} + InPlaceMutableDeque( int capacity = BaseType::DefaultCapacity ) : BaseType( capacity ) {} virtual ~InPlaceMutableDeque() {}; - using Deque<Elem>::PeekBack; - using Deque<Elem>::PeekFront; + using BaseType::PeekBack; + using BaseType::PeekFront; virtual Elem& PeekBack (int count = 0); // Returns count-th Item from the end virtual Elem& PeekFront (int count = 0); // Returns count-th Item from the beginning }; // Same as Deque, but allows to write more elements than maximum capacity // Old elements are lost as they are overwritten with the new ones -template <class Elem> -class CircularBuffer : public InPlaceMutableDeque<Elem> +template <class Elem, class Allocator = ContainerAllocator<Elem> > +class CircularBuffer : public InPlaceMutableDeque<Elem, Allocator> { + typedef InPlaceMutableDeque<Elem, Allocator> BaseType; + public: - CircularBuffer(int MaxSize = Deque<Elem>::DefaultCapacity) : InPlaceMutableDeque<Elem>(MaxSize) { }; + CircularBuffer(int MaxSize = BaseType::DefaultCapacity) : BaseType(MaxSize) { }; // The following methods are inline as a workaround for a VS bug causing erroneous C4505 warnings // See: http://stackoverflow.com/questions/3051992/compiler-warning-at-c-template-base-class @@ -99,42 +109,54 @@ public: //---------------------------------------------------------------------------------- // Deque Constructor function -template <class Elem> -Deque<Elem>::Deque(int capacity) : +template <class Elem, class Allocator> +Deque<Elem, Allocator>::Deque(int capacity) : Capacity( capacity ), Beginning(0), End(0), ElemCount(0) { - Data = (Elem*) OVR_ALLOC(Capacity * sizeof(Elem)); - ConstructArray<Elem>(Data, Capacity); + Data = (Elem*) Allocator::Alloc(Capacity * sizeof(Elem)); } // Deque Destructor function -template <class Elem> -Deque<Elem>::~Deque(void) +template <class Elem, class Allocator> +Deque<Elem, Allocator>::~Deque(void) { - DestructArray<Elem>(Data, Capacity); - OVR_FREE(Data); + Clear(); + Allocator::Free(Data); } -template <class Elem> -void Deque<Elem>::Clear() +template <class Elem, class Allocator> +void Deque<Elem, Allocator>::Clear() { + if (!IsEmpty()) + { + if (Beginning < End) + { + // no wrap-around + Allocator::DestructArray(Data + Beginning, End - Beginning); + } + else + { + // wrap-around + Allocator::DestructArray(Data + Beginning, Capacity - Beginning); + Allocator::DestructArray(Data, End); + } + } + Beginning = 0; End = 0; ElemCount = 0; - - DestructArray<Elem>(Data, Capacity); - ConstructArray<Elem>(Data, Capacity); } // Push functions -template <class Elem> -void Deque<Elem>::PushBack(const Elem &Item) +template <class Elem, class Allocator> +void Deque<Elem, Allocator>::PushBack(const Elem &Item) { // Error Check: Make sure we aren't // exceeding our maximum storage space OVR_ASSERT( ElemCount < Capacity ); - Data[ End++ ] = Item; + Allocator::Construct(Data + End, Item); + ++End; ++ElemCount; // Check for wrap-around @@ -142,32 +164,31 @@ void Deque<Elem>::PushBack(const Elem &Item) End -= Capacity; } -template <class Elem> -void Deque<Elem>::PushFront(const Elem &Item) +template <class Elem, class Allocator> +void Deque<Elem, Allocator>::PushFront(const Elem &Item) { // Error Check: Make sure we aren't // exceeding our maximum storage space OVR_ASSERT( ElemCount < Capacity ); - Beginning--; + --Beginning; // Check for wrap-around if (Beginning < 0) Beginning += Capacity; - Data[ Beginning ] = Item; + Allocator::Construct(Data + Beginning, Item); ++ElemCount; } // Pop functions -template <class Elem> -Elem Deque<Elem>::PopFront(void) +template <class Elem, class Allocator> +Elem Deque<Elem, Allocator>::PopFront(void) { // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( ElemCount > 0 ); Elem ReturnValue = Data[ Beginning ]; - Destruct<Elem>(&Data[ Beginning ]); - Construct<Elem>(&Data[ Beginning ]); + Allocator::Destruct(Data + Beginning); ++Beginning; --ElemCount; @@ -179,13 +200,13 @@ Elem Deque<Elem>::PopFront(void) return ReturnValue; } -template <class Elem> -Elem Deque<Elem>::PopBack(void) +template <class Elem, class Allocator> +Elem Deque<Elem, Allocator>::PopBack(void) { // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( ElemCount > 0 ); - End--; + --End; --ElemCount; // Check for wrap-around @@ -193,15 +214,14 @@ Elem Deque<Elem>::PopBack(void) End += Capacity; Elem ReturnValue = Data[ End ]; - Destruct<Elem>(&Data[ End ]); - Construct<Elem>(&Data[ End ]); + Allocator::Destruct(Data + End); return ReturnValue; } // Peek functions -template <class Elem> -const Elem& Deque<Elem>::PeekFront(int count) const +template <class Elem, class Allocator> +const Elem& Deque<Elem, Allocator>::PeekFront(int count) const { // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( ElemCount > count ); @@ -212,8 +232,8 @@ const Elem& Deque<Elem>::PeekFront(int count) const return Data[ idx ]; } -template <class Elem> -const Elem& Deque<Elem>::PeekBack(int count) const +template <class Elem, class Allocator> +const Elem& Deque<Elem, Allocator>::PeekBack(int count) const { // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( ElemCount > count ); @@ -225,70 +245,70 @@ const Elem& Deque<Elem>::PeekBack(int count) const } // Mutable Peek functions -template <class Elem> -Elem& InPlaceMutableDeque<Elem>::PeekFront(int count) +template <class Elem, class Allocator> +Elem& InPlaceMutableDeque<Elem, Allocator>::PeekFront(int count) { // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( Deque<Elem>::ElemCount > count ); + OVR_ASSERT( BaseType::ElemCount > count ); - int idx = Deque<Elem>::Beginning + count; - if (idx >= Deque<Elem>::Capacity) - idx -= Deque<Elem>::Capacity; - return Deque<Elem>::Data[ idx ]; + int idx = BaseType::Beginning + count; + if (idx >= BaseType::Capacity) + idx -= BaseType::Capacity; + return BaseType::Data[ idx ]; } -template <class Elem> -Elem& InPlaceMutableDeque<Elem>::PeekBack(int count) +template <class Elem, class Allocator> +Elem& InPlaceMutableDeque<Elem, Allocator>::PeekBack(int count) { // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( Deque<Elem>::ElemCount > count ); + OVR_ASSERT( BaseType::ElemCount > count ); - int idx = Deque<Elem>::End - count - 1; + int idx = BaseType::End - count - 1; if (idx < 0) - idx += Deque<Elem>::Capacity; - return Deque<Elem>::Data[ idx ]; + idx += BaseType::Capacity; + return BaseType::Data[ idx ]; } -template <class Elem> -inline UPInt Deque<Elem>::GetCapacity(void) const +template <class Elem, class Allocator> +inline size_t Deque<Elem, Allocator>::GetCapacity(void) const { - return Deque<Elem>::Capacity; + return Capacity; } -template <class Elem> -inline UPInt Deque<Elem>::GetSize(void) const +template <class Elem, class Allocator> +inline size_t Deque<Elem, Allocator>::GetSize(void) const { - return Deque<Elem>::ElemCount; + return ElemCount; } -template <class Elem> -inline bool Deque<Elem>::IsEmpty(void) const +template <class Elem, class Allocator> +inline bool Deque<Elem, Allocator>::IsEmpty(void) const { - return Deque<Elem>::ElemCount==0; + return ElemCount == 0; } -template <class Elem> -inline bool Deque<Elem>::IsFull(void) const +template <class Elem, class Allocator> +inline bool Deque<Elem, Allocator>::IsFull(void) const { - return Deque<Elem>::ElemCount==Deque<Elem>::Capacity; + return ElemCount == Capacity; } // ******* CircularBuffer<Elem> ******* // Push functions -template <class Elem> -void CircularBuffer<Elem>::PushBack(const Elem &Item) +template <class Elem, class Allocator> +void CircularBuffer<Elem, Allocator>::PushBack(const Elem &Item) { if (this->IsFull()) this->PopFront(); - Deque<Elem>::PushBack(Item); + BaseType::PushBack(Item); } -template <class Elem> -void CircularBuffer<Elem>::PushFront(const Elem &Item) +template <class Elem, class Allocator> +void CircularBuffer<Elem, Allocator>::PushFront(const Elem &Item) { if (this->IsFull()) this->PopBack(); - Deque<Elem>::PushFront(Item); + BaseType::PushFront(Item); } }; |