array.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "platform.h"
  5. #include "alloc.h"
  6. namespace embree
  7. {
  8. /*! static array with static size */
  9. template<typename T, size_t N>
  10. class array_t
  11. {
  12. public:
  13. /********************** Iterators ****************************/
  14. __forceinline T* begin() const { return items; };
  15. __forceinline T* end () const { return items+N; };
  16. /********************** Capacity ****************************/
  17. __forceinline bool empty () const { return N == 0; }
  18. __forceinline size_t size () const { return N; }
  19. __forceinline size_t max_size () const { return N; }
  20. /******************** Element access **************************/
  21. __forceinline T& operator[](size_t i) { assert(i < N); return items[i]; }
  22. __forceinline const T& operator[](size_t i) const { assert(i < N); return items[i]; }
  23. __forceinline T& at(size_t i) { assert(i < N); return items[i]; }
  24. __forceinline const T& at(size_t i) const { assert(i < N); return items[i]; }
  25. __forceinline T& front() const { assert(N > 0); return items[0]; };
  26. __forceinline T& back () const { assert(N > 0); return items[N-1]; };
  27. __forceinline T* data() { return items; };
  28. __forceinline const T* data() const { return items; };
  29. private:
  30. T items[N];
  31. };
  32. /*! static array with dynamic size */
  33. template<typename T, size_t N>
  34. class darray_t
  35. {
  36. public:
  37. __forceinline darray_t () : M(0) {}
  38. __forceinline darray_t (const T& v) : M(0) {
  39. for (size_t i=0; i<N; i++) items[i] = v;
  40. }
  41. /********************** Iterators ****************************/
  42. __forceinline T* begin() const { return (T*)items; };
  43. __forceinline T* end () const { return (T*)items+M; };
  44. /********************** Capacity ****************************/
  45. __forceinline bool empty () const { return M == 0; }
  46. __forceinline size_t size () const { return M; }
  47. __forceinline size_t capacity () const { return N; }
  48. __forceinline size_t max_size () const { return N; }
  49. void resize(size_t new_size) {
  50. assert(new_size < max_size());
  51. M = new_size;
  52. }
  53. /******************** Modifiers **************************/
  54. __forceinline void push_back(const T& v)
  55. {
  56. assert(M+1 < max_size());
  57. items[M++] = v;
  58. }
  59. __forceinline void pop_back()
  60. {
  61. assert(!empty());
  62. M--;
  63. }
  64. __forceinline void clear() {
  65. M = 0;
  66. }
  67. /******************** Element access **************************/
  68. __forceinline T& operator[](size_t i) { assert(i < M); return items[i]; }
  69. __forceinline const T& operator[](size_t i) const { assert(i < M); return items[i]; }
  70. __forceinline T& at(size_t i) { assert(i < M); return items[i]; }
  71. __forceinline const T& at(size_t i) const { assert(i < M); return items[i]; }
  72. __forceinline T& front() { assert(M > 0); return items[0]; };
  73. __forceinline T& back () { assert(M > 0); return items[M-1]; };
  74. __forceinline T* data() { return items; };
  75. __forceinline const T* data() const { return items; };
  76. private:
  77. size_t M;
  78. T items[N];
  79. };
  80. /*! dynamic sized array that is allocated on the stack */
  81. #define dynamic_large_stack_array(Ty,Name,N,max_stack_bytes) StackArray<Ty,max_stack_bytes> Name(N)
  82. template<typename Ty, size_t max_stack_bytes>
  83. struct __aligned(64) StackArray
  84. {
  85. __forceinline StackArray (const size_t N)
  86. : N(N)
  87. {
  88. if (N*sizeof(Ty) <= max_stack_bytes)
  89. data = &arr[0];
  90. else
  91. data = (Ty*) alignedMalloc(N*sizeof(Ty),64);
  92. }
  93. __forceinline ~StackArray () {
  94. if (data != &arr[0]) alignedFree(data);
  95. }
  96. __forceinline operator Ty* () { return data; }
  97. __forceinline operator const Ty* () const { return data; }
  98. __forceinline Ty& operator[](const int i) { assert(i>=0 && i<N); return data[i]; }
  99. __forceinline const Ty& operator[](const int i) const { assert(i>=0 && i<N); return data[i]; }
  100. __forceinline Ty& operator[](const unsigned i) { assert(i<N); return data[i]; }
  101. __forceinline const Ty& operator[](const unsigned i) const { assert(i<N); return data[i]; }
  102. #if defined(__64BIT__) || defined(__EMSCRIPTEN__)
  103. __forceinline Ty& operator[](const size_t i) { assert(i<N); return data[i]; }
  104. __forceinline const Ty& operator[](const size_t i) const { assert(i<N); return data[i]; }
  105. #endif
  106. private:
  107. Ty arr[max_stack_bytes/sizeof(Ty)];
  108. Ty* data;
  109. size_t N;
  110. private:
  111. StackArray (const StackArray& other) DELETED; // do not implement
  112. StackArray& operator= (const StackArray& other) DELETED; // do not implement
  113. };
  114. /*! dynamic sized array that is allocated on the stack */
  115. template<typename Ty, size_t max_stack_elements, size_t max_total_elements>
  116. struct __aligned(64) DynamicStackArray
  117. {
  118. __forceinline DynamicStackArray ()
  119. : data(&arr[0]) {}
  120. __forceinline ~DynamicStackArray ()
  121. {
  122. if (!isStackAllocated())
  123. delete[] data;
  124. }
  125. __forceinline bool isStackAllocated() const {
  126. return data == &arr[0];
  127. }
  128. __forceinline size_t size() const
  129. {
  130. if (isStackAllocated()) return max_stack_elements;
  131. else return max_total_elements;
  132. }
  133. __forceinline void resize(size_t M)
  134. {
  135. assert(M <= max_total_elements);
  136. if (likely(M <= max_stack_elements)) return;
  137. if (likely(!isStackAllocated())) return;
  138. data = new Ty[max_total_elements];
  139. for (size_t i=0; i<max_stack_elements; i++)
  140. data[i] = arr[i];
  141. }
  142. __forceinline operator Ty* () { return data; }
  143. __forceinline operator const Ty* () const { return data; }
  144. __forceinline Ty& operator[](const int i) { assert(i>=0 && i<max_total_elements); resize(i+1); return data[i]; }
  145. __forceinline Ty& operator[](const unsigned i) { assert(i<max_total_elements); resize(i+1); return data[i]; }
  146. #if defined(__64BIT__) || defined(__EMSCRIPTEN__)
  147. __forceinline Ty& operator[](const size_t i) { assert(i<max_total_elements); resize(i+1); return data[i]; }
  148. #endif
  149. __forceinline DynamicStackArray (const DynamicStackArray& other)
  150. : data(&arr[0])
  151. {
  152. for (size_t i=0; i<other.size(); i++)
  153. this->operator[] (i) = other[i];
  154. }
  155. DynamicStackArray& operator= (const DynamicStackArray& other)
  156. {
  157. for (size_t i=0; i<other.size(); i++)
  158. this->operator[] (i) = other[i];
  159. return *this;
  160. }
  161. private:
  162. Ty arr[max_stack_elements];
  163. Ty* data;
  164. };
  165. }