diff options
Diffstat (limited to 'LibOVR/Src/Kernel/OVR_Deque.h')
-rw-r--r-- | LibOVR/Src/Kernel/OVR_Deque.h | 180 |
1 files changed, 100 insertions, 80 deletions
diff --git a/LibOVR/Src/Kernel/OVR_Deque.h b/LibOVR/Src/Kernel/OVR_Deque.h index ca242ad..951ed84 100644 --- a/LibOVR/Src/Kernel/OVR_Deque.h +++ b/LibOVR/Src/Kernel/OVR_Deque.h @@ -5,16 +5,16 @@ Content : Deque container Created : Nov. 15, 2013 Authors : Dov Katz -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.1 +http://www.oculusvr.com/licenses/LICENSE-3.2 Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, @@ -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; @@ -65,30 +71,34 @@ protected: int ElemCount; private: - Deque& operator= (const Deque& q) { }; // forbidden - Deque(const Deque<Elem> &OtherDeque) { }; + OVR_NON_COPYABLE(Deque); }; -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) { }; + virtual ~CircularBuffer(){} // 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); } }; |