tAlignedArray.h 6.5 KB

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