Torque3D Documentation / _generateds / tAlignedArray.h

tAlignedArray.h

Engine/source/core/util/tAlignedArray.h

More...

Classes:

class

This is a fixed size class that will align its elements on configurable boundaries.

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _ALIGNEDARRAY_H_
 25#define _ALIGNEDARRAY_H_
 26
 27/// This is a fixed size class that will align its elements on configurable boundaries.    
 28template<typename T>
 29class AlignedArray
 30{
 31public:
 32   AlignedArray();
 33   /// Create an AlignedArray
 34   /// @param arraySize How many items
 35   /// @param elementSize Size of each element (including padding)
 36   AlignedArray(const U32 arraySize, const U32 elementSize);
 37   /// Create an AlignedArray
 38   /// @param arraySize How many items
 39   /// @param elementSize Size of each element (including padding)
 40   /// @param buffer Preallocated buffer (with data and aligned on elementSize boundaries)
 41   /// @param takeOwn If true, this class will take ownership of the buffer and free on destruct
 42   AlignedArray(const U32 arraySize, const U32 elementSize, U8* buffer, bool takeOwn);
 43   ~AlignedArray();
 44
 45   void setCapacity(const U32 arraySize, const U32 elementSize);
 46   void setCapacity(const U32 arraySize, const U32 elementSize, U8* buffer, bool takeOwn);
 47
 48   /// Size of the array
 49   U32 size() const;      
 50
 51   /// Set a new array size (up to initial size created returned by capacity)
 52   void setSize(U32 newsize);
 53
 54   /// Capacity of the array (you can setCapacity the size this high)
 55   U32 capacity() const;
 56   
 57   /// Returns the size of an element (useful for asserting, etc)
 58   U32 getElementSize() const;
 59
 60   /// Returns a pointer to the raw buffer data.
 61   const void* getBuffer() const;
 62   void* getBuffer();
 63
 64   // Returns the buffer size in bytes.
 65   U32 getBufferSize() const { return mElementSize * mElementCount; }
 66
 67   // Operators
 68   T& operator[](const U32);
 69   const T& operator[](const U32) const;
 70protected:
 71   // How big an element is, this includes padding need to align
 72   U32 mElementSize;
 73   // How many elements do we have
 74   U32 mElementCount;
 75   // How many elements can we have
 76   U32 mCapacity;
 77   // Storage, we use placement new and reinterpret casts to deal with 
 78   // alignment
 79   U8* mBuffer;
 80   // Do we own this buffer? Or are we just wrapping it?
 81   bool mOwnBuffer;
 82};
 83
 84template<typename T>
 85inline AlignedArray<T>::AlignedArray()
 86{
 87   mElementSize = 0;
 88   mElementCount = 0;
 89   mCapacity = 0;
 90   mBuffer = NULL;
 91   mOwnBuffer = true;
 92}
 93
 94template<typename T>
 95inline AlignedArray<T>::AlignedArray(const U32 arraySize, const U32 elementSize)
 96{
 97   mElementCount = 0; // avoid debug assert
 98   setCapacity(arraySize, elementSize);
 99}
100
101template<typename T>
102inline AlignedArray<T>::AlignedArray(const U32 arraySize, const U32 elementSize, U8* buffer, bool takeOwn)
103{
104   mElementCount = 0; // avoid debug assert
105   setCapacity(arraySize, elementSize, buffer, takeOwn);
106}
107
108template<typename T>
109inline AlignedArray<T>::~AlignedArray()
110{
111   if (mOwnBuffer)
112      delete[] mBuffer;
113}
114template<typename T>
115inline void AlignedArray<T>::setCapacity(const U32 arraySize, const U32 elementSize)
116{
117   AssertFatal(mElementCount == 0, "Unable to set array properties after they are init'ed");
118   AssertFatal(elementSize >= sizeof(T), "Element size is too small!");
119   AssertFatal(arraySize > 0, "0 length AlignedArrays are not allowed!");
120
121   mElementSize = elementSize;
122   mElementCount = arraySize;
123   mCapacity = arraySize;
124   mBuffer = new U8[mElementSize * mElementCount];
125   dMemset(mBuffer, 0xFF, mElementSize * mElementCount);
126   U32 bufIndex = 0;
127   for (U32 i = 0; i < mElementCount; i++)
128   {
129      T* item = reinterpret_cast<T*>(&mBuffer[bufIndex]);
130      constructInPlace(item);
131      bufIndex += mElementSize;
132   }
133   mOwnBuffer = true;
134}
135
136template<typename T>
137inline void AlignedArray<T>::setCapacity(const U32 arraySize, const U32 elementSize, U8* buffer, bool takeOwn)
138{
139   AssertFatal(mElementCount == 0, "Unable to set array properties after they are init'ed");
140   AssertFatal(elementSize >= sizeof(T), "Element size is too small!");
141   AssertFatal(arraySize > 0, "0 length AlignedArrays are not allowed!");
142   AssertFatal(buffer, "NULL buffer!");
143
144   mElementSize = elementSize;
145   mElementCount = arraySize;
146   mCapacity = arraySize;
147   mBuffer = buffer;
148   mOwnBuffer = takeOwn;
149}
150
151/// Set a new array size (up to initial size created returned by capacity)
152template<typename T>
153inline void AlignedArray<T>::setSize(U32 newsize)
154{
155   AssertFatal(newsize <= mCapacity, "Unable to grow this type of array!");
156   mElementCount = newsize;
157}
158
159template<typename T>
160inline U32 AlignedArray<T>::size() const
161{
162   return mElementCount;
163}
164
165template<typename T>
166inline U32 AlignedArray<T>::capacity() const
167{
168   return mCapacity;
169}
170
171/// Returns the size of an element (useful for asserting, etc)
172template<typename T>
173U32 AlignedArray<T>::getElementSize() const
174{
175   return mElementSize;
176}
177
178template<typename T>
179inline T& AlignedArray<T>::operator[](const U32 index)
180{
181   AssertFatal(index < mElementCount, "AlignedArray<T>::operator[] - out of bounds array access!");
182   return reinterpret_cast<T&>(mBuffer[index*mElementSize]);
183}
184
185template<typename T>
186inline const T& AlignedArray<T>::operator[](const U32 index) const
187{
188   AssertFatal(index < mElementCount, "AlignedArray<T>::operator[] - out of bounds array access!");
189   return reinterpret_cast<const T&>(mBuffer[index*mElementSize]);
190}
191
192template<typename T>
193const void* AlignedArray<T>::getBuffer() const
194{
195   return reinterpret_cast<const void*>(mBuffer);
196}
197
198template<typename T>
199void* AlignedArray<T>::getBuffer()
200{
201   return reinterpret_cast<void*>(mBuffer);
202}
203
204#endif // _ALIGNEDARRAY_H_
205