Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
StaticArray.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
8
10template <class T, uint N>
11class [[nodiscard]] StaticArray
12{
13public:
14 using value_type = T;
15
16 using size_type = uint;
17
18 static constexpr uint Capacity = N;
19
21 StaticArray() = default;
22
24 explicit StaticArray(std::initializer_list<T> inList)
25 {
26 JPH_ASSERT(inList.size() <= N);
27 for (typename std::initializer_list<T>::iterator i = inList.begin(); i != inList.end(); ++i)
28 ::new (reinterpret_cast<T *>(&mElements[mSize++])) T(*i);
29 }
30
33 {
34 while (mSize < inRHS.mSize)
35 {
36 ::new (&mElements[mSize]) T(inRHS[mSize]);
37 ++mSize;
38 }
39 }
40
43 {
44 if constexpr (!is_trivially_destructible<T>())
45 for (T *e = reinterpret_cast<T *>(mElements), *end = e + mSize; e < end; ++e)
46 e->~T();
47 }
48
50 void clear()
51 {
52 if constexpr (!is_trivially_destructible<T>())
53 for (T *e = reinterpret_cast<T *>(mElements), *end = e + mSize; e < end; ++e)
54 e->~T();
55 mSize = 0;
56 }
57
59 void push_back(const T &inElement)
60 {
61 JPH_ASSERT(mSize < N);
62 ::new (&mElements[mSize++]) T(inElement);
63 }
64
66 template <class... A>
67 void emplace_back(A &&... inElement)
68 {
69 JPH_ASSERT(mSize < N);
70 ::new (&mElements[mSize++]) T(std::forward<A>(inElement)...);
71 }
72
74 void pop_back()
75 {
76 JPH_ASSERT(mSize > 0);
77 reinterpret_cast<T &>(mElements[--mSize]).~T();
78 }
79
81 bool empty() const
82 {
83 return mSize == 0;
84 }
85
88 {
89 return mSize;
90 }
91
94 {
95 return N;
96 }
97
99 void resize(size_type inNewSize)
100 {
101 JPH_ASSERT(inNewSize <= N);
102 if constexpr (!is_trivially_constructible<T>())
103 for (T *element = reinterpret_cast<T *>(mElements) + mSize, *element_end = reinterpret_cast<T *>(mElements) + inNewSize; element < element_end; ++element)
104 ::new (element) T;
105 if constexpr (!is_trivially_destructible<T>())
106 for (T *element = reinterpret_cast<T *>(mElements) + inNewSize, *element_end = reinterpret_cast<T *>(mElements) + mSize; element < element_end; ++element)
107 element->~T();
108 mSize = inNewSize;
109 }
110
111 using const_iterator = const T *;
112
115 {
116 return reinterpret_cast<const T *>(mElements);
117 }
118
120 {
121 return reinterpret_cast<const T *>(mElements + mSize);
122 }
123
124 using iterator = T *;
125
127 {
128 return reinterpret_cast<T *>(mElements);
129 }
130
132 {
133 return reinterpret_cast<T *>(mElements + mSize);
134 }
135
136 const T * data() const
137 {
138 return reinterpret_cast<const T *>(mElements);
139 }
140
141 T * data()
142 {
143 return reinterpret_cast<T *>(mElements);
144 }
145
147 T & operator [] (size_type inIdx)
148 {
149 JPH_ASSERT(inIdx < mSize);
150 return reinterpret_cast<T &>(mElements[inIdx]);
151 }
152
153 const T & operator [] (size_type inIdx) const
154 {
155 JPH_ASSERT(inIdx < mSize);
156 return reinterpret_cast<const T &>(mElements[inIdx]);
157 }
158
160 const T & front() const
161 {
162 JPH_ASSERT(mSize > 0);
163 return reinterpret_cast<const T &>(mElements[0]);
164 }
165
166 T & front()
167 {
168 JPH_ASSERT(mSize > 0);
169 return reinterpret_cast<T &>(mElements[0]);
170 }
171
173 const T & back() const
174 {
175 JPH_ASSERT(mSize > 0);
176 return reinterpret_cast<const T &>(mElements[mSize - 1]);
177 }
178
179 T & back()
180 {
181 JPH_ASSERT(mSize > 0);
182 return reinterpret_cast<T &>(mElements[mSize - 1]);
183 }
184
187 {
188 size_type p = size_type(inIter - begin());
189 JPH_ASSERT(p < mSize);
190 reinterpret_cast<T &>(mElements[p]).~T();
191 if (p + 1 < mSize)
192 memmove(mElements + p, mElements + p + 1, (mSize - p - 1) * sizeof(T));
193 --mSize;
194 }
195
198 {
199 size_type p = size_type(inBegin - begin());
200 size_type n = size_type(inEnd - inBegin);
201 JPH_ASSERT(inEnd <= end());
202 for (size_type i = 0; i < n; ++i)
203 reinterpret_cast<T &>(mElements[p + i]).~T();
204 if (p + n < mSize)
205 memmove(mElements + p, mElements + p + n, (mSize - p - n) * sizeof(T));
206 mSize -= n;
207 }
208
210 StaticArray<T, N> & operator = (const StaticArray<T, N> &inRHS)
211 {
212 size_type rhs_size = inRHS.size();
213
214 if ((void *)this != (void *)&inRHS)
215 {
216 clear();
217
218 while (mSize < rhs_size)
219 {
220 ::new (&mElements[mSize]) T(inRHS[mSize]);
221 ++mSize;
222 }
223 }
224
225 return *this;
226 }
227
229 template <uint M>
230 StaticArray<T, N> & operator = (const StaticArray<T, M> &inRHS)
231 {
232 size_type rhs_size = inRHS.size();
233 JPH_ASSERT(rhs_size <= N);
234
235 if ((void *)this != (void *)&inRHS)
236 {
237 clear();
238
239 while (mSize < rhs_size)
240 {
241 ::new (&mElements[mSize]) T(inRHS[mSize]);
242 ++mSize;
243 }
244 }
245
246 return *this;
247 }
248
250 bool operator == (const StaticArray<T, N> &inRHS) const
251 {
252 if (mSize != inRHS.mSize)
253 return false;
254 for (size_type i = 0; i < mSize; ++i)
255 if (!(reinterpret_cast<const T &>(mElements[i]) == reinterpret_cast<const T &>(inRHS.mElements[i])))
256 return false;
257 return true;
258 }
259
260 bool operator != (const StaticArray<T, N> &inRHS) const
261 {
262 if (mSize != inRHS.mSize)
263 return true;
264 for (size_type i = 0; i < mSize; ++i)
265 if (reinterpret_cast<const T &>(mElements[i]) != reinterpret_cast<const T &>(inRHS.mElements[i]))
266 return true;
267 return false;
268 }
269
270protected:
271 struct alignas(T) Storage
272 {
273 uint8 mData[sizeof(T)];
274 };
275
276 static_assert(sizeof(T) == sizeof(Storage), "Mismatch in size");
277 static_assert(alignof(T) == alignof(Storage), "Mismatch in alignment");
278
279 size_type mSize = 0;
280 Storage mElements[N];
281};
282
284
285JPH_SUPPRESS_WARNING_PUSH
286JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat")
287
288namespace std
289{
291 template <class T, JPH::uint N>
292 struct hash<JPH::StaticArray<T, N>>
293 {
294 size_t operator () (const JPH::StaticArray<T, N> &inRHS) const
295 {
296 std::size_t ret = 0;
297
298 // Hash length first
299 JPH::HashCombine(ret, inRHS.size());
300
301 // Then hash elements
302 for (const T &t : inRHS)
303 JPH::HashCombine(ret, t);
304
305 return ret;
306 }
307 };
308}
309
310JPH_SUPPRESS_WARNING_POP
unsigned int uint
Definition: Core.h:309
#define JPH_NAMESPACE_END
Definition: Core.h:240
#define JPH_CLANG_SUPPRESS_WARNING(w)
Definition: Core.h:133
uint8_t uint8
Definition: Core.h:310
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:234
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
Simple variable length array backed by a fixed size buffer.
Definition: StaticArray.h:12
StaticArray()=default
Default constructor.
void push_back(const T &inElement)
Add element to the back of the array.
Definition: StaticArray.h:59
size_type capacity() const
Returns maximum amount of elements the array can hold.
Definition: StaticArray.h:93
iterator end()
Definition: StaticArray.h:131
T * data()
Definition: StaticArray.h:141
void clear()
Destruct all elements and set length to zero.
Definition: StaticArray.h:50
T value_type
Definition: StaticArray.h:14
iterator begin()
Definition: StaticArray.h:126
StaticArray(std::initializer_list< T > inList)
Constructor from initializer list.
Definition: StaticArray.h:24
const T * const_iterator
Definition: StaticArray.h:111
T * iterator
Definition: StaticArray.h:124
T & front()
Definition: StaticArray.h:166
void erase(const_iterator inIter)
Remove one element from the array.
Definition: StaticArray.h:186
const_iterator begin() const
Iterators.
Definition: StaticArray.h:114
uint size_type
Definition: StaticArray.h:16
const T & back() const
Last element in the array.
Definition: StaticArray.h:173
const T * data() const
Definition: StaticArray.h:136
void emplace_back(A &&... inElement)
Construct element at the back of the array.
Definition: StaticArray.h:67
void erase(const_iterator inBegin, const_iterator inEnd)
Remove multiple element from the array.
Definition: StaticArray.h:197
Storage mElements[N]
Definition: StaticArray.h:280
bool empty() const
Returns true if there are no elements in the array.
Definition: StaticArray.h:81
StaticArray(const StaticArray< T, N > &inRHS)
Copy constructor.
Definition: StaticArray.h:32
const T & front() const
First element in the array.
Definition: StaticArray.h:160
T & back()
Definition: StaticArray.h:179
const_iterator end() const
Definition: StaticArray.h:119
size_type mSize
Definition: StaticArray.h:279
size_type size() const
Returns amount of elements in the array.
Definition: StaticArray.h:87
void pop_back()
Remove element from the back of the array.
Definition: StaticArray.h:74
void resize(size_type inNewSize)
Resize array to new length.
Definition: StaticArray.h:99
~StaticArray()
Destruct all elements.
Definition: StaticArray.h:42
Definition: Reference.h:207
Definition: StaticArray.h:272