46 template <
typename T, u
int8_t N>
class Array;
72 template <
typename T>
struct Ptr;
74 template <
class _ToType,
class _FromType>
75 constexpr _ToType __bit_cast(
const _FromType &__from) {
76 return __builtin_bit_cast(_ToType, __from);
81 static_assert(!std::is_volatile_v<T>,
"volatile types are not supported");
82 static_assert(std::is_trivial_v<T>,
"non-trivial types are unsupported");
83 static_assert(std::is_standard_layout_v<T>,
84 "non-standard layout types are unsupported");
85 static_assert(std::alignment_of_v<T> == 1,
"aligned types are not supported");
97 template <u
int8_t N, u
int8_t ByteIdx = 0>
98 [[clang::always_inline]] constexpr
void initBytePtrs(
100 if constexpr (ByteIdx <
sizeof(T)) {
101 BytePtrs[ByteIdx] = &ByteArrays[ByteIdx][Idx];
102 initBytePtrs<N, ByteIdx + 1>(ByteArrays, Idx);
110 initBytePtrs<N>(ByteArrays, Idx);
116 initBytePtrs<N>(ByteArrays, Idx);
123 [[clang::always_inline]] T
get()
const {
return static_cast<T
>(*this); }
128 template <u
int8_t Idx = 0>
129 [[clang::always_inline]] constexpr
void readBytes(
130 uint8_t (&Bytes)[
sizeof(T)])
const {
131 if constexpr (Idx <
sizeof(T)) {
133 readBytes<Idx + 1>(Bytes);
138 [[clang::always_inline]] constexpr
operator T()
const {
141 return __bit_cast<T>(Bytes);
144 template <
typename... ArgsT>
145 [[clang::always_inline]]
auto operator()(ArgsT &&...Args)
const ->
auto {
146 return static_cast<const T
>(
get())(std::forward<ArgsT>(Args)...);
152 template <u
int8_t Idx = 0>
153 [[clang::always_inline]]
void writeBytes(
const uint8_t *Bytes) {
154 if constexpr (Idx <
sizeof(T)) {
156 writeBytes<Idx + 1>(Bytes);
161 template <
typename Q = T>
162 [[clang::always_inline]] std::enable_if_t<!std::is_const_v<Q>,
const Ptr<T> &>
164 writeBytes(
reinterpret_cast<const uint8_t *
>(&Val));
165 return *
static_cast<Ptr<T> *
>(
this);
168 template <
typename Q = T>
169 [[clang::always_inline]] std::enable_if_t<std::is_pointer_v<Q>,
const T>
173 template <
typename Q = T>
174 [[clang::always_inline]] std::enable_if_t<std::is_pointer_v<Q>, T>
184 [[clang::always_inline]] ConstWrapper(
const Ptr<T> &P) : V(P) {}
185 [[clang::always_inline]]
const T *
operator->()
const {
return &V; }
189 template <
typename Q = T>
190 [[clang::always_inline]] std::enable_if_t<!std::is_pointer_v<Q>, ConstWrapper>
192 return *
static_cast<const Ptr<T> *
>(
this);
195 template <
typename U>
197 *
this = *
this + Right;
198 return *
static_cast<Ptr<T> *
>(
this);
201 template <
typename U>
203 *
this = *
this - Right;
204 return *
static_cast<Ptr<T> *
>(
this);
207 template <
typename U>
209 *
this = *
this * Right;
210 return *
static_cast<Ptr<T> *
>(
this);
213 template <
typename U>
215 *
this = *
this / Right;
216 return *
static_cast<Ptr<T> *
>(
this);
219 template <
typename U>
221 *
this = *
this % Right;
222 return *
static_cast<Ptr<T> *
>(
this);
225 template <
typename U>
227 *
this = *
this ^ Right;
228 return *
static_cast<Ptr<T> *
>(
this);
231 template <
typename U>
233 *
this = *
this & Right;
234 return *
static_cast<Ptr<T> *
>(
this);
237 template <
typename U>
239 *
this = *
this | Right;
240 return *
static_cast<Ptr<T> *
>(
this);
243 template <
typename U>
245 *
this = *
this << Right;
246 return *
static_cast<Ptr<T> *
>(
this);
249 template <
typename U>
251 *
this = *
this >> Right;
252 return *
static_cast<Ptr<T> *
>(
this);
257 return *
static_cast<Ptr<T> *
>(
this);
261 return *
static_cast<Ptr<T> *
>(
this);
267 return *
static_cast<Ptr<T> *
>(
this);
273 return *
static_cast<Ptr<T> *
>(
this);
283 template <
typename T, u
int8_t N>
class Ptr<T[N]> {
284 static_assert(!std::is_volatile_v<T>,
"volatile types are not supported");
285 static_assert(std::is_trivial_v<T>,
"non-trivial types are unsupported");
286 static_assert(std::is_standard_layout_v<T>,
287 "non-standard layout types are unsupported");
288 static_assert(std::alignment_of_v<T> == 1,
"aligned types are not supported");
291 [[clang::always_inline]]
Ptr<T> *ptrs() {
292 return reinterpret_cast<Ptr<T> *
>(PtrStorage);
297 template <u
int8_t M, u
int8_t ArrayIdx = 0>
298 [[clang::always_inline]] constexpr
void initPtrs(
const uint8_t ByteArrays[][M],
300 if constexpr (ArrayIdx < N) {
301 new (&ptrs()[ArrayIdx])
Ptr<T>(ByteArrays + ArrayIdx *
sizeof(T), Idx);
302 initPtrs<M, ArrayIdx + 1>(ByteArrays, Idx);
308 [[clang::always_inline]] constexpr
Ptr(
const uint8_t ByteArrays[][M],
310 initPtrs<M>(ByteArrays, Idx);
315 initPtrs<M>(ByteArrays, Idx);
323 friend class Array<T, N>;
341 return &
A == &Other.
A &&
Idx == Other.
Idx;
344 return !(*
this == Other);
348 template <
typename T, u
int8_t N>
350 friend class Array<T, N>;
369 template <
typename T, u
int8_t N>
class Array {
370 static_assert(!std::is_volatile_v<T>,
"volatile types are not supported");
371 static_assert(std::is_trivial_v<T>,
"non-trivial types are unsupported");
372 static_assert(std::is_standard_layout_v<T>,
373 "only standard layout types are supported");
374 static_assert(std::alignment_of_v<T> == 1,
"aligned types are not supported");
376 uint8_t ByteArrays[
sizeof(T)][N];
379 template <u
int8_t ByteIdx = 0>
380 [[clang::always_inline]] constexpr
void storeEntryBytes(
382 if constexpr (ByteIdx <
sizeof(T)) {
383 ByteArrays[ByteIdx][Idx] = Bytes[ByteIdx];
384 storeEntryBytes<ByteIdx + 1>(Idx, Bytes);
393 for (
const T &Entry : Entries) {
402 [[clang::always_inline]] constexpr
Array() =
default;
406 memcpy(ByteArrays, Other.ByteArrays,
sizeof(Other.ByteArrays));
410 return {ByteArrays, Idx};
414 return {ByteArrays, Idx};
421 return {*
this,
size()};
428 return {*
this,
size()};
431 [[clang::always_inline]] constexpr
uint8_t size()
const {
return N; }
uint8_t Idx
Definition: soa.h:327
const Array< T, N > & A
Definition: soa.h:326
bool operator==(const ArrayConstIterator &Other) const
Definition: soa.h:340
bool operator!=(const ArrayConstIterator &Other) const
Definition: soa.h:343
ArrayConstIterator(const Array< T, N > &A, uint8_t Idx)
Definition: soa.h:329
ArrayConstIterator & operator++()
Definition: soa.h:335
Ptr< const T > operator*() const
Definition: soa.h:333
ArrayIterator & operator++()
Definition: soa.h:363
Ptr< T > operator*() const
Definition: soa.h:359
constexpr Array()=default
constexpr ArrayConstIterator< T, N > end() const
Definition: soa.h:420
constexpr ArrayIterator< T, N > end()
Definition: soa.h:427
constexpr ArrayConstIterator< T, N > begin() const
Definition: soa.h:417
constexpr Ptr< T > operator[](uint8_t Idx)
Definition: soa.h:409
constexpr ArrayIterator< T, N > begin()
Definition: soa.h:424
constexpr Ptr< const T > operator[](uint8_t Idx) const
Definition: soa.h:413
constexpr Array(const Array< T, M > &Other)
Definition: soa.h:405
constexpr Array(std::initializer_list< T > Entries)
Definition: soa.h:391
constexpr uint8_t size() const
Definition: soa.h:431
Base class for pointer to array elements.
Definition: soa.h:80
std::enable_if_t< std::is_pointer_v< Q >, T > operator->()
Definition: soa.h:175
Ptr< T > & operator^=(const U &Right)
Definition: soa.h:226
std::enable_if_t<!std::is_const_v< Q >, const Ptr< T > & > operator=(const T &Val)
Definition: soa.h:163
Ptr< T > & operator>>=(const U &Right)
Definition: soa.h:250
Ptr< T > & operator<<=(const U &Right)
Definition: soa.h:244
Ptr< T > & operator%=(const U &Right)
Definition: soa.h:220
Ptr< T > & operator+=(const U &Right)
Definition: soa.h:196
T get() const
Definition: soa.h:123
Ptr< T > & operator|=(const U &Right)
Definition: soa.h:238
Ptr< T > & operator-=(const U &Right)
Definition: soa.h:202
const uint8_t * BytePtrs[sizeof(T)]
Definition: soa.h:81
Ptr< T > & operator++()
Definition: soa.h:255
Ptr< T > & operator--()
Definition: soa.h:259
Ptr< T > & operator&=(const U &Right)
Definition: soa.h:232
auto operator()(ArgsT &&...Args) const -> auto
Definition: soa.h:145
Ptr< T > & operator*=(const U &Right)
Definition: soa.h:208
T operator--(int)
Definition: soa.h:270
constexpr BasePtr(const uint8_t ByteArrays[][N], uint8_t Idx)
Definition: soa.h:108
std::enable_if_t< std::is_pointer_v< Q >, const T > operator->() const
Definition: soa.h:170
std::enable_if_t<!std::is_pointer_v< Q >, ConstWrapper > operator->() const
Definition: soa.h:191
Ptr< T > & operator/=(const U &Right)
Definition: soa.h:214
T operator++(int)
Definition: soa.h:264
constexpr BasePtr(uint8_t ByteArrays[][N], uint8_t Idx)
Definition: soa.h:114
Ptr< const T > operator[](uint8_t Idx) const
Definition: soa.h:318
constexpr Ptr(const uint8_t ByteArrays[][M], uint8_t Idx)
Definition: soa.h:308
constexpr Ptr(uint8_t ByteArrays[][M], uint8_t Idx)
Definition: soa.h:314
Definition: initializer_list:8
::uint8_t uint8_t
Definition: cstdint:21
void * memcpy(void *__restrict__ s1, const void *__restrict__ s2, size_t n)