tAlignedArray.h
Engine/source/core/util/tAlignedArray.h
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