aboutsummaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/Kernel/OVR_Deque.h
diff options
context:
space:
mode:
Diffstat (limited to 'LibOVR/Src/Kernel/OVR_Deque.h')
-rw-r--r--LibOVR/Src/Kernel/OVR_Deque.h172
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);
}
};