summaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/Kernel/OVR_Array.h
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-06-19 17:03:28 +0200
committerSven Gothel <[email protected]>2014-06-19 17:03:28 +0200
commitd9a584844a60542519d813b5dc1a62428f14a0ae (patch)
tree942c10a5ebcd0aab65e9d6facb59778468f39d3b /LibOVR/Src/Kernel/OVR_Array.h
Add OculusSDK 0.3.2 Linux Source Code w/o Samples, docs or binaries (libs or tools)
Diffstat (limited to 'LibOVR/Src/Kernel/OVR_Array.h')
-rw-r--r--LibOVR/Src/Kernel/OVR_Array.h833
1 files changed, 833 insertions, 0 deletions
diff --git a/LibOVR/Src/Kernel/OVR_Array.h b/LibOVR/Src/Kernel/OVR_Array.h
new file mode 100644
index 0000000..7a715ba
--- /dev/null
+++ b/LibOVR/Src/Kernel/OVR_Array.h
@@ -0,0 +1,833 @@
+/************************************************************************************
+
+PublicHeader: OVR.h
+Filename : OVR_Array.h
+Content : Template implementation for Array
+Created : September 19, 2012
+Notes :
+
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.1 (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
+
+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,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+#ifndef OVR_Array_h
+#define OVR_Array_h
+
+#include "OVR_ContainerAllocator.h"
+
+namespace OVR {
+
+//-----------------------------------------------------------------------------------
+// ***** ArrayDefaultPolicy
+//
+// Default resize behavior. No minimal capacity, Granularity=4,
+// Shrinking as needed. ArrayConstPolicy actually is the same as
+// ArrayDefaultPolicy, but parametrized with constants.
+// This struct is used only in order to reduce the template "matroska".
+struct ArrayDefaultPolicy
+{
+ ArrayDefaultPolicy() : Capacity(0) {}
+ ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {}
+
+ UPInt GetMinCapacity() const { return 0; }
+ UPInt GetGranularity() const { return 4; }
+ bool NeverShrinking() const { return 0; }
+
+ UPInt GetCapacity() const { return Capacity; }
+ void SetCapacity(UPInt capacity) { Capacity = capacity; }
+private:
+ UPInt Capacity;
+};
+
+
+//-----------------------------------------------------------------------------------
+// ***** ArrayConstPolicy
+//
+// Statically parametrized resizing behavior:
+// MinCapacity, Granularity, and Shrinking flag.
+template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false>
+struct ArrayConstPolicy
+{
+ typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType;
+
+ ArrayConstPolicy() : Capacity(0) {}
+ ArrayConstPolicy(const SelfType&) : Capacity(0) {}
+
+ UPInt GetMinCapacity() const { return MinCapacity; }
+ UPInt GetGranularity() const { return Granularity; }
+ bool NeverShrinking() const { return NeverShrink; }
+
+ UPInt GetCapacity() const { return Capacity; }
+ void SetCapacity(UPInt capacity) { Capacity = capacity; }
+private:
+ UPInt Capacity;
+};
+
+//-----------------------------------------------------------------------------------
+// ***** ArrayDataBase
+//
+// Basic operations with array data: Reserve, Resize, Free, ArrayPolicy.
+// For internal use only: ArrayData,ArrayDataCC and others.
+template<class T, class Allocator, class SizePolicy>
+struct ArrayDataBase
+{
+ typedef T ValueType;
+ typedef Allocator AllocatorType;
+ typedef SizePolicy SizePolicyType;
+ typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType;
+
+ ArrayDataBase()
+ : Data(0), Size(0), Policy() {}
+
+ ArrayDataBase(const SizePolicy& p)
+ : Data(0), Size(0), Policy(p) {}
+
+ ~ArrayDataBase()
+ {
+ Allocator::DestructArray(Data, Size);
+ Allocator::Free(Data);
+ }
+
+ UPInt GetCapacity() const
+ {
+ return Policy.GetCapacity();
+ }
+
+ void ClearAndRelease()
+ {
+ Allocator::DestructArray(Data, Size);
+ Allocator::Free(Data);
+ Data = 0;
+ Size = 0;
+ Policy.SetCapacity(0);
+ }
+
+ void Reserve(UPInt newCapacity)
+ {
+ if (Policy.NeverShrinking() && newCapacity < GetCapacity())
+ return;
+
+ if (newCapacity < Policy.GetMinCapacity())
+ newCapacity = Policy.GetMinCapacity();
+
+ // Resize the buffer.
+ if (newCapacity == 0)
+ {
+ if (Data)
+ {
+ Allocator::Free(Data);
+ Data = 0;
+ }
+ Policy.SetCapacity(0);
+ }
+ else
+ {
+ UPInt gran = Policy.GetGranularity();
+ newCapacity = (newCapacity + gran - 1) / gran * gran;
+ if (Data)
+ {
+ if (Allocator::IsMovable())
+ {
+ Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity);
+ }
+ else
+ {
+ T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
+ UPInt i, s;
+ s = (Size < newCapacity) ? Size : newCapacity;
+ for (i = 0; i < s; ++i)
+ {
+ Allocator::Construct(&newData[i], Data[i]);
+ Allocator::Destruct(&Data[i]);
+ }
+ for (i = s; i < Size; ++i)
+ {
+ Allocator::Destruct(&Data[i]);
+ }
+ Allocator::Free(Data);
+ Data = newData;
+ }
+ }
+ else
+ {
+ Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
+ //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this?
+ }
+ Policy.SetCapacity(newCapacity);
+ // OVR_ASSERT(Data); // need to throw (or something) on alloc failure!
+ }
+ }
+
+ // This version of Resize DOES NOT construct the elements.
+ // It's done to optimize PushBack, which uses a copy constructor
+ // instead of the default constructor and assignment
+ void ResizeNoConstruct(UPInt newSize)
+ {
+ UPInt oldSize = Size;
+
+ if (newSize < oldSize)
+ {
+ Allocator::DestructArray(Data + newSize, oldSize - newSize);
+ if (newSize < (Policy.GetCapacity() >> 1))
+ {
+ Reserve(newSize);
+ }
+ }
+ else if(newSize >= Policy.GetCapacity())
+ {
+ Reserve(newSize + (newSize >> 2));
+ }
+ //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable
+ // array may use this array and may traverse it during Reserve (in the case, if
+ // collection occurs because of heap limit exceeded).
+ Size = newSize;
+ }
+
+ ValueType* Data;
+ UPInt Size;
+ SizePolicy Policy;
+};
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** ArrayData
+//
+// General purpose array data.
+// For internal use only in Array, ArrayLH, ArrayPOD and so on.
+template<class T, class Allocator, class SizePolicy>
+struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
+{
+ typedef T ValueType;
+ typedef Allocator AllocatorType;
+ typedef SizePolicy SizePolicyType;
+ typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
+ typedef ArrayData <T, Allocator, SizePolicy> SelfType;
+
+ ArrayData()
+ : BaseType() { }
+
+ ArrayData(UPInt size)
+ : BaseType() { Resize(size); }
+
+ ArrayData(const SelfType& a)
+ : BaseType(a.Policy) { Append(a.Data, a.Size); }
+
+
+ void Resize(UPInt newSize)
+ {
+ UPInt oldSize = this->Size;
+ BaseType::ResizeNoConstruct(newSize);
+ if(newSize > oldSize)
+ Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize);
+ }
+
+ void PushBack(const ValueType& val)
+ {
+ BaseType::ResizeNoConstruct(this->Size + 1);
+ Allocator::Construct(this->Data + this->Size - 1, val);
+ }
+
+ template<class S>
+ void PushBackAlt(const S& val)
+ {
+ BaseType::ResizeNoConstruct(this->Size + 1);
+ Allocator::ConstructAlt(this->Data + this->Size - 1, val);
+ }
+
+ // Append the given data to the array.
+ void Append(const ValueType other[], UPInt count)
+ {
+ if (count)
+ {
+ UPInt oldSize = this->Size;
+ BaseType::ResizeNoConstruct(this->Size + count);
+ Allocator::ConstructArray(this->Data + oldSize, count, other);
+ }
+ }
+};
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** ArrayDataCC
+//
+// A modification of ArrayData that always copy-constructs new elements
+// using a specified DefaultValue. For internal use only in ArrayCC.
+template<class T, class Allocator, class SizePolicy>
+struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
+{
+ typedef T ValueType;
+ typedef Allocator AllocatorType;
+ typedef SizePolicy SizePolicyType;
+ typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
+ typedef ArrayDataCC <T, Allocator, SizePolicy> SelfType;
+
+ ArrayDataCC(const ValueType& defval)
+ : BaseType(), DefaultValue(defval) { }
+
+ ArrayDataCC(const ValueType& defval, UPInt size)
+ : BaseType(), DefaultValue(defval) { Resize(size); }
+
+ ArrayDataCC(const SelfType& a)
+ : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); }
+
+
+ void Resize(UPInt newSize)
+ {
+ UPInt oldSize = this->Size;
+ BaseType::ResizeNoConstruct(newSize);
+ if(newSize > oldSize)
+ Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue);
+ }
+
+ void PushBack(const ValueType& val)
+ {
+ BaseType::ResizeNoConstruct(this->Size + 1);
+ Allocator::Construct(this->Data + this->Size - 1, val);
+ }
+
+ template<class S>
+ void PushBackAlt(const S& val)
+ {
+ BaseType::ResizeNoConstruct(this->Size + 1);
+ Allocator::ConstructAlt(this->Data + this->Size - 1, val);
+ }
+
+ // Append the given data to the array.
+ void Append(const ValueType other[], UPInt count)
+ {
+ if (count)
+ {
+ UPInt oldSize = this->Size;
+ BaseType::ResizeNoConstruct(this->Size + count);
+ Allocator::ConstructArray(this->Data + oldSize, count, other);
+ }
+ }
+
+ ValueType DefaultValue;
+};
+
+
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** ArrayBase
+//
+// Resizable array. The behavior can be POD (suffix _POD) and
+// Movable (no suffix) depending on the allocator policy.
+// In case of _POD the constructors and destructors are not called.
+//
+// Arrays can't handle non-movable objects! Don't put anything in here
+// that can't be moved around by bitwise copy.
+//
+// The addresses of elements are not persistent! Don't keep the address
+// of an element; the array contents will move around as it gets resized.
+template<class ArrayData>
+class ArrayBase
+{
+public:
+ typedef typename ArrayData::ValueType ValueType;
+ typedef typename ArrayData::AllocatorType AllocatorType;
+ typedef typename ArrayData::SizePolicyType SizePolicyType;
+ typedef ArrayBase<ArrayData> SelfType;
+
+
+#undef new
+ OVR_MEMORY_REDEFINE_NEW(ArrayBase)
+// Redefine operator 'new' if necessary.
+#if defined(OVR_DEFINE_NEW)
+#define new OVR_DEFINE_NEW
+#endif
+
+
+ ArrayBase()
+ : Data() {}
+ ArrayBase(UPInt size)
+ : Data(size) {}
+ ArrayBase(const SelfType& a)
+ : Data(a.Data) {}
+
+ ArrayBase(const ValueType& defval)
+ : Data(defval) {}
+ ArrayBase(const ValueType& defval, UPInt size)
+ : Data(defval, size) {}
+
+ SizePolicyType* GetSizePolicy() const { return Data.Policy; }
+ void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; }
+
+ bool NeverShrinking()const { return Data.Policy.NeverShrinking(); }
+ UPInt GetSize() const { return Data.Size; }
+ bool IsEmpty() const { return Data.Size == 0; }
+ UPInt GetCapacity() const { return Data.GetCapacity(); }
+ UPInt GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); }
+
+ void ClearAndRelease() { Data.ClearAndRelease(); }
+ void Clear() { Data.Resize(0); }
+ void Resize(UPInt newSize) { Data.Resize(newSize); }
+
+ // Reserve can only increase the capacity
+ void Reserve(UPInt newCapacity)
+ {
+ if (newCapacity > Data.GetCapacity())
+ Data.Reserve(newCapacity);
+ }
+
+ // Basic access.
+ ValueType& At(UPInt index)
+ {
+ OVR_ASSERT(index < Data.Size);
+ return Data.Data[index];
+ }
+ const ValueType& At(UPInt index) const
+ {
+ OVR_ASSERT(index < Data.Size);
+ return Data.Data[index];
+ }
+
+ ValueType ValueAt(UPInt index) const
+ {
+ OVR_ASSERT(index < Data.Size);
+ return Data.Data[index];
+ }
+
+ // Basic access.
+ ValueType& operator [] (UPInt index)
+ {
+ OVR_ASSERT(index < Data.Size);
+ return Data.Data[index];
+ }
+ const ValueType& operator [] (UPInt index) const
+ {
+ OVR_ASSERT(index < Data.Size);
+ return Data.Data[index];
+ }
+
+ // Raw pointer to the data. Use with caution!
+ const ValueType* GetDataPtr() const { return Data.Data; }
+ ValueType* GetDataPtr() { return Data.Data; }
+
+ // Insert the given element at the end of the array.
+ void PushBack(const ValueType& val)
+ {
+ // DO NOT pass elements of your own vector into
+ // push_back()! Since we're using references,
+ // resize() may munge the element storage!
+ // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]);
+ Data.PushBack(val);
+ }
+
+ template<class S>
+ void PushBackAlt(const S& val)
+ {
+ Data.PushBackAlt(val);
+ }
+
+ // Remove the last element.
+ void PopBack(UPInt count = 1)
+ {
+ OVR_ASSERT(Data.Size >= count);
+ Data.Resize(Data.Size - count);
+ }
+
+ ValueType& PushDefault()
+ {
+ Data.PushBack(ValueType());
+ return Back();
+ }
+
+ ValueType Pop()
+ {
+ ValueType t = Back();
+ PopBack();
+ return t;
+ }
+
+
+ // Access the first element.
+ ValueType& Front() { return At(0); }
+ const ValueType& Front() const { return At(0); }
+
+ // Access the last element.
+ ValueType& Back() { return At(Data.Size - 1); }
+ const ValueType& Back() const { return At(Data.Size - 1); }
+
+ // Array copy. Copies the contents of a into this array.
+ const SelfType& operator = (const SelfType& a)
+ {
+ Resize(a.GetSize());
+ for (UPInt i = 0; i < Data.Size; i++) {
+ *(Data.Data + i) = a[i];
+ }
+ return *this;
+ }
+
+ // Removing multiple elements from the array.
+ void RemoveMultipleAt(UPInt index, UPInt num)
+ {
+ OVR_ASSERT(index + num <= Data.Size);
+ if (Data.Size == num)
+ {
+ Clear();
+ }
+ else
+ {
+ AllocatorType::DestructArray(Data.Data + index, num);
+ AllocatorType::CopyArrayForward(
+ Data.Data + index,
+ Data.Data + index + num,
+ Data.Size - num - index);
+ Data.Size -= num;
+ }
+ }
+
+ // Removing an element from the array is an expensive operation!
+ // It compacts only after removing the last element.
+ // If order of elements in the array is not important then use
+ // RemoveAtUnordered, that could be much faster than the regular
+ // RemoveAt.
+ void RemoveAt(UPInt index)
+ {
+ OVR_ASSERT(index < Data.Size);
+ if (Data.Size == 1)
+ {
+ Clear();
+ }
+ else
+ {
+ AllocatorType::Destruct(Data.Data + index);
+ AllocatorType::CopyArrayForward(
+ Data.Data + index,
+ Data.Data + index + 1,
+ Data.Size - 1 - index);
+ --Data.Size;
+ }
+ }
+
+ // Removes an element from the array without respecting of original order of
+ // elements for better performance. Do not use on array where order of elements
+ // is important, otherwise use it instead of regular RemoveAt().
+ void RemoveAtUnordered(UPInt index)
+ {
+ OVR_ASSERT(index < Data.Size);
+ if (Data.Size == 1)
+ {
+ Clear();
+ }
+ else
+ {
+ // copy the last element into the 'index' position
+ // and decrement the size (instead of moving all elements
+ // in [index + 1 .. size - 1] range).
+ const UPInt lastElemIndex = Data.Size - 1;
+ if (index < lastElemIndex)
+ {
+ AllocatorType::Destruct(Data.Data + index);
+ AllocatorType::Construct(Data.Data + index, Data.Data[lastElemIndex]);
+ }
+ AllocatorType::Destruct(Data.Data + lastElemIndex);
+ --Data.Size;
+ }
+ }
+
+ // Insert the given object at the given index shifting all the elements up.
+ void InsertAt(UPInt index, const ValueType& val = ValueType())
+ {
+ OVR_ASSERT(index <= Data.Size);
+
+ Data.Resize(Data.Size + 1);
+ if (index < Data.Size - 1)
+ {
+ AllocatorType::CopyArrayBackward(
+ Data.Data + index + 1,
+ Data.Data + index,
+ Data.Size - 1 - index);
+ }
+ AllocatorType::Construct(Data.Data + index, val);
+ }
+
+ // Insert the given object at the given index shifting all the elements up.
+ void InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType())
+ {
+ OVR_ASSERT(index <= Data.Size);
+
+ Data.Resize(Data.Size + num);
+ if (index < Data.Size - num)
+ {
+ AllocatorType::CopyArrayBackward(
+ Data.Data + index + num,
+ Data.Data + index,
+ Data.Size - num - index);
+ }
+ for (UPInt i = 0; i < num; ++i)
+ AllocatorType::Construct(Data.Data + index + i, val);
+ }
+
+ // Append the given data to the array.
+ void Append(const SelfType& other)
+ {
+ Append(other.Data.Data, other.GetSize());
+ }
+
+ // Append the given data to the array.
+ void Append(const ValueType other[], UPInt count)
+ {
+ Data.Append(other, count);
+ }
+
+ class Iterator
+ {
+ SelfType* pArray;
+ SPInt CurIndex;
+
+ public:
+ Iterator() : pArray(0), CurIndex(-1) {}
+ Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
+
+ bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
+ bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
+
+ Iterator& operator++()
+ {
+ if (pArray)
+ {
+ if (CurIndex < (SPInt)pArray->GetSize())
+ ++CurIndex;
+ }
+ return *this;
+ }
+ Iterator operator++(int)
+ {
+ Iterator it(*this);
+ operator++();
+ return it;
+ }
+ Iterator& operator--()
+ {
+ if (pArray)
+ {
+ if (CurIndex >= 0)
+ --CurIndex;
+ }
+ return *this;
+ }
+ Iterator operator--(int)
+ {
+ Iterator it(*this);
+ operator--();
+ return it;
+ }
+ Iterator operator+(int delta) const
+ {
+ return Iterator(pArray, CurIndex + delta);
+ }
+ Iterator operator-(int delta) const
+ {
+ return Iterator(pArray, CurIndex - delta);
+ }
+ SPInt operator-(const Iterator& right) const
+ {
+ OVR_ASSERT(pArray == right.pArray);
+ return CurIndex - right.CurIndex;
+ }
+ ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
+ ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
+ ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
+
+ bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
+
+ void Remove()
+ {
+ if (!IsFinished())
+ pArray->RemoveAt(CurIndex);
+ }
+
+ SPInt GetIndex() const { return CurIndex; }
+ };
+
+ Iterator Begin() { return Iterator(this); }
+ Iterator End() { return Iterator(this, (SPInt)GetSize()); }
+ Iterator Last() { return Iterator(this, (SPInt)GetSize() - 1); }
+
+ class ConstIterator
+ {
+ const SelfType* pArray;
+ SPInt CurIndex;
+
+ public:
+ ConstIterator() : pArray(0), CurIndex(-1) {}
+ ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
+
+ bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
+ bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
+
+ ConstIterator& operator++()
+ {
+ if (pArray)
+ {
+ if (CurIndex < (int)pArray->GetSize())
+ ++CurIndex;
+ }
+ return *this;
+ }
+ ConstIterator operator++(int)
+ {
+ ConstIterator it(*this);
+ operator++();
+ return it;
+ }
+ ConstIterator& operator--()
+ {
+ if (pArray)
+ {
+ if (CurIndex >= 0)
+ --CurIndex;
+ }
+ return *this;
+ }
+ ConstIterator operator--(int)
+ {
+ ConstIterator it(*this);
+ operator--();
+ return it;
+ }
+ ConstIterator operator+(int delta) const
+ {
+ return ConstIterator(pArray, CurIndex + delta);
+ }
+ ConstIterator operator-(int delta) const
+ {
+ return ConstIterator(pArray, CurIndex - delta);
+ }
+ SPInt operator-(const ConstIterator& right) const
+ {
+ OVR_ASSERT(pArray == right.pArray);
+ return CurIndex - right.CurIndex;
+ }
+ const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
+ const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
+ const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
+
+ bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
+
+ SPInt GetIndex() const { return CurIndex; }
+ };
+ ConstIterator Begin() const { return ConstIterator(this); }
+ ConstIterator End() const { return ConstIterator(this, (SPInt)GetSize()); }
+ ConstIterator Last() const { return ConstIterator(this, (SPInt)GetSize() - 1); }
+
+protected:
+ ArrayData Data;
+};
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** Array
+//
+// General purpose array for movable objects that require explicit
+// construction/destruction.
+template<class T, class SizePolicy=ArrayDefaultPolicy>
+class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> >
+{
+public:
+ typedef T ValueType;
+ typedef ContainerAllocator<T> AllocatorType;
+ typedef SizePolicy SizePolicyType;
+ typedef Array<T, SizePolicy> SelfType;
+ typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
+
+ Array() : BaseType() {}
+ Array(UPInt size) : BaseType(size) {}
+ Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
+ Array(const SelfType& a) : BaseType(a) {}
+ const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
+};
+
+// ***** ArrayPOD
+//
+// General purpose array for movable objects that DOES NOT require
+// construction/destruction. Constructors and destructors are not called!
+// Global heap is in use.
+template<class T, class SizePolicy=ArrayDefaultPolicy>
+class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> >
+{
+public:
+ typedef T ValueType;
+ typedef ContainerAllocator_POD<T> AllocatorType;
+ typedef SizePolicy SizePolicyType;
+ typedef ArrayPOD<T, SizePolicy> SelfType;
+ typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
+
+ ArrayPOD() : BaseType() {}
+ ArrayPOD(UPInt size) : BaseType(size) {}
+ ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
+ ArrayPOD(const SelfType& a) : BaseType(a) {}
+ const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
+};
+
+
+// ***** ArrayCPP
+//
+// General purpose, fully C++ compliant array. Can be used with non-movable data.
+// Global heap is in use.
+template<class T, class SizePolicy=ArrayDefaultPolicy>
+class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> >
+{
+public:
+ typedef T ValueType;
+ typedef ContainerAllocator_CPP<T> AllocatorType;
+ typedef SizePolicy SizePolicyType;
+ typedef ArrayCPP<T, SizePolicy> SelfType;
+ typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
+
+ ArrayCPP() : BaseType() {}
+ ArrayCPP(UPInt size) : BaseType(size) {}
+ ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
+ ArrayCPP(const SelfType& a) : BaseType(a) {}
+ const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
+};
+
+
+// ***** ArrayCC
+//
+// A modification of the array that uses the given default value to
+// construct the elements. The constructors and destructors are
+// properly called, the objects must be movable.
+
+template<class T, class SizePolicy=ArrayDefaultPolicy>
+class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >
+{
+public:
+ typedef T ValueType;
+ typedef ContainerAllocator<T> AllocatorType;
+ typedef SizePolicy SizePolicyType;
+ typedef ArrayCC<T, SizePolicy> SelfType;
+ typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType;
+
+ ArrayCC(const ValueType& defval) : BaseType(defval) {}
+ ArrayCC(const ValueType& defval, UPInt size) : BaseType(defval, size) {}
+ ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
+ ArrayCC(const SelfType& a) : BaseType(a) {}
+ const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
+};
+
+} // OVR
+
+#endif