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
9namespace 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
19 __forceinline T* begin() const { return items; };
20 __forceinline T* end () const { return items+N; };
21
22
23 /********************** Capacity ****************************/
24
25 __forceinline bool empty () const { return N == 0; }
26 __forceinline size_t size () const { return N; }
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
35 __forceinline T& at(size_t i) { assert(i < N); return items[i]; }
36 __forceinline const T& at(size_t i) const { assert(i < N); return items[i]; }
37
38 __forceinline T& front() const { assert(N > 0); return items[0]; };
39 __forceinline T& back () const { assert(N > 0); return items[N-1]; };
40
41 __forceinline T* data() { return items; };
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
54 __forceinline darray_t () : M(0) {}
55
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
62 __forceinline T* begin() const { return (T*)items; };
63 __forceinline T* end () const { return (T*)items+M; };
64
65
66 /********************** Capacity ****************************/
67
68 __forceinline bool empty () const { return M == 0; }
69 __forceinline size_t size () const { return M; }
70 __forceinline size_t capacity () const { return N; }
71 __forceinline size_t max_size () const { return N; }
72
73 void resize(size_t new_size) {
74 assert(new_size < max_size());
75 M = new_size;
76 }
77
78 /******************** Modifiers **************************/
79
80 __forceinline void push_back(const T& v)
81 {
82 assert(M+1 < max_size());
83 items[M++] = v;
84 }
85
86 __forceinline void pop_back()
87 {
88 assert(!empty());
89 M--;
90 }
91
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
101 __forceinline T& at(size_t i) { assert(i < M); return items[i]; }
102 __forceinline const T& at(size_t i) const { assert(i < M); return items[i]; }
103
104 __forceinline T& front() { assert(M > 0); return items[0]; };
105 __forceinline T& back () { assert(M > 0); return items[M-1]; };
106
107 __forceinline T* data() { return items; };
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 {
120 __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
129 __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__) || defined(__EMSCRIPTEN__)
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 {
162 __forceinline DynamicStackArray ()
163 : data(&arr[0]) {}
164
165 __forceinline ~DynamicStackArray ()
166 {
167 if (!isStackAllocated())
168 delete[] data;
169 }
170
171 __forceinline bool isStackAllocated() const {
172 return data == &arr[0];
173 }
174
175 __forceinline size_t size() const
176 {
177 if (isStackAllocated()) return max_stack_elements;
178 else return max_total_elements;
179 }
180
181 __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__) || defined(__EMSCRIPTEN__)
200 __forceinline Ty& operator[](const size_t i) { assert(i<max_total_elements); resize(i+1); return data[i]; }
201#endif
202
203 __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