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");
98 for (
uint8_t ByteIdx = 0; ByteIdx <
sizeof(T); ++ByteIdx)
99 BytePtrs[ByteIdx] = &ByteArrays[ByteIdx][Idx];
106 for (
uint8_t ByteIdx = 0; ByteIdx <
sizeof(T); ++ByteIdx)
107 BytePtrs[ByteIdx] = &ByteArrays[ByteIdx][Idx];
114 [[clang::always_inline]] T
get()
const {
return static_cast<T
>(*this); }
116 [[clang::always_inline]] constexpr
operator T()
const {
119 for (
uint8_t Idx = 0; Idx <
sizeof(T); ++Idx)
121 return __bit_cast<T>(Bytes);
124 template <
typename... ArgsT>
125 [[clang::always_inline]]
auto operator()(ArgsT &&...Args)
const ->
auto {
126 return static_cast<const T
>(
get())(std::forward<ArgsT>(Args)...);
129 template <
typename Q = T>
130 [[clang::always_inline]] std::enable_if_t<!std::is_const_v<Q>,
const Ptr<T> &>
132 auto *Bytes =
reinterpret_cast<const uint8_t *
>(&Val);
134 for (
uint8_t Idx = 0; Idx <
sizeof(T); ++Idx)
136 return *
static_cast<Ptr<T> *
>(
this);
139 template <
typename Q = T>
140 [[clang::always_inline]] std::enable_if_t<std::is_pointer_v<Q>,
const T>
144 template <
typename Q = T>
145 [[clang::always_inline]] std::enable_if_t<std::is_pointer_v<Q>, T>
155 [[clang::always_inline]] ConstWrapper(
const Ptr<T> &P) : V(P) {}
156 [[clang::always_inline]]
const T *
operator->()
const {
return &V; }
160 template <
typename Q = T>
161 [[clang::always_inline]] std::enable_if_t<!std::is_pointer_v<Q>, ConstWrapper>
163 return *
static_cast<const Ptr<T> *
>(
this);
166 template <
typename U>
168 *
this = *
this + Right;
169 return *
static_cast<Ptr<T> *
>(
this);
172 template <
typename U>
174 *
this = *
this - Right;
175 return *
static_cast<Ptr<T> *
>(
this);
178 template <
typename U>
180 *
this = *
this * Right;
181 return *
static_cast<Ptr<T> *
>(
this);
184 template <
typename U>
186 *
this = *
this / Right;
187 return *
static_cast<Ptr<T> *
>(
this);
190 template <
typename U>
192 *
this = *
this % Right;
193 return *
static_cast<Ptr<T> *
>(
this);
196 template <
typename U>
198 *
this = *
this ^ Right;
199 return *
static_cast<Ptr<T> *
>(
this);
202 template <
typename U>
204 *
this = *
this & Right;
205 return *
static_cast<Ptr<T> *
>(
this);
208 template <
typename U>
210 *
this = *
this | Right;
211 return *
static_cast<Ptr<T> *
>(
this);
214 template <
typename U>
216 *
this = *
this << Right;
217 return *
static_cast<Ptr<T> *
>(
this);
220 template <
typename U>
222 *
this = *
this >> Right;
223 return *
static_cast<Ptr<T> *
>(
this);
228 return *
static_cast<Ptr<T> *
>(
this);
232 return *
static_cast<Ptr<T> *
>(
this);
238 return *
static_cast<Ptr<T> *
>(
this);
244 return *
static_cast<Ptr<T> *
>(
this);
248 template <
typename T>
class Ptr :
public BasePtr<T> {
251 using BasePtr<T>::operator=;
254 template <
typename T, u
int8_t N>
class Ptr<T[N]> {
255 static_assert(!std::is_volatile_v<T>,
"volatile types are not supported");
256 static_assert(std::is_trivial_v<T>,
"non-trivial types are unsupported");
257 static_assert(std::is_standard_layout_v<T>,
258 "non-standard layout types are unsupported");
259 static_assert(std::alignment_of_v<T> == 1,
"aligned types are not supported");
262 [[clang::always_inline]]
Ptr<T> *ptrs() {
263 return reinterpret_cast<Ptr<T> *
>(PtrStorage);
268 [[clang::always_inline]] constexpr
Ptr(
const uint8_t ByteArrays[][M],
271 for (
uint8_t ArrayIdx = 0; ArrayIdx < N; ++ArrayIdx)
272 new (&ptrs()[ArrayIdx])
Ptr<T>(ByteArrays + ArrayIdx *
sizeof(T), Idx);
278 for (
uint8_t ArrayIdx = 0; ArrayIdx < N; ++ArrayIdx)
279 new (&ptrs()[ArrayIdx])
Ptr<T>(ByteArrays + ArrayIdx *
sizeof(T), Idx);
305 return &
A == &Other.
A &&
Idx == Other.
Idx;
308 return !(*
this == Other);
312 template <
typename T, u
int8_t N>
333 template <
typename T, u
int8_t N>
class Array {
334 static_assert(!std::is_volatile_v<T>,
"volatile types are not supported");
335 static_assert(std::is_trivial_v<T>,
"non-trivial types are unsupported");
336 static_assert(std::is_standard_layout_v<T>,
337 "only standard layout types are supported");
338 static_assert(std::alignment_of_v<T> == 1,
"aligned types are not supported");
340 uint8_t ByteArrays[
sizeof(T)][N];
347 for (
const T &Entry : Entries) {
351 for (
uint8_t ByteIdx = 0; ByteIdx <
sizeof(T); ++ByteIdx)
352 ByteArrays[ByteIdx][Idx] = Bytes[ByteIdx];
359 [[clang::always_inline]] constexpr
Array() =
default;
363 memcpy(ByteArrays, Other.ByteArrays,
sizeof(Other.ByteArrays));
367 return {ByteArrays, Idx};
371 return {ByteArrays, Idx};
378 return {*
this,
size()};
385 return {*
this,
size()};
388 [[clang::always_inline]] constexpr
uint8_t size()
const {
return N; }