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