1#ifndef NNGN_UTILS_UTILS_H
2#define NNGN_UTILS_UTILS_H
18#define FWD(...) std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
20#define NNGN_DEFAULT_CONSTRUCT(x) \
22 x(const x&) = default; \
23 x &operator=(const x&) = default; \
24 x(x&&) noexcept = default; \
25 x &operator=(x&&) noexcept = default; \
27#define NNGN_VIRTUAL(x) \
28 NNGN_DEFAULT_CONSTRUCT(x) \
29 virtual ~x() = default;
31#define NNGN_PURE_VIRTUAL(x) \
32 NNGN_DEFAULT_CONSTRUCT(x) \
35#define NNGN_NO_COPY(x) \
36 x(const x&) = delete; \
37 x &operator=(const x&) = delete;
39#define NNGN_MOVE_ONLY(x) \
41 x(x&&) noexcept = default; \
42 x &operator=(x&&) noexcept = default;
44#define NNGN_NO_MOVE(x) \
45 x(const x&) = delete; \
46 x &operator=(const x&) = delete; \
47 x(x&&) noexcept = delete; \
48 x &operator=(x&&) noexcept = delete;
50#define NNGN_ANON_IMPL1(l) nngn_anon_ ## l
51#define NNGN_ANON_IMPL0(l) NNGN_ANON_IMPL1(l)
52#define NNGN_ANON() NNGN_ANON_IMPL0(__LINE__)
53#define NNGN_ANON_DECL(...) \
54 [[maybe_unused]] const auto NNGN_ANON() = __VA_ARGS__;
56#define NNGN_CONTAINER_OF(t, n, p) \
57 (nngn::byte_cast<t*>(nngn::byte_cast<char*>(p) - offsetof(t, n)))
59#define NNGN_BIND_MEM_FN(x, f) \
60 std::bind_front([] { \
61 constexpr auto nngn_ret = \
62 &std::remove_pointer_t<std::decay_t<decltype(x)>>::f; \
63 static_assert(std::is_member_function_pointer_v<decltype(nngn_ret)>); \
67#define NNGN_EXPOSE_ITERATOR(n, m) \
68 NNGN_EXPOSE_ITERATOR0(n, m, cbegin) \
69 NNGN_EXPOSE_ITERATOR0(n, m, cend) \
70 NNGN_EXPOSE_ITERATOR0(n, m, begin) \
71 NNGN_EXPOSE_ITERATOR0(n, m, end)
72#define NNGN_EXPOSE_ITERATOR0(n, m, i) \
73 auto n##i(void) const { using std::i; return i(this->m); } \
74 auto n##i(void) { using std::i; return i(this->m); }
82 constexpr decltype(
auto)
operator<<(
auto &&x) {
83 return static_cast<T>(
FWD(x));
94template<
typename ...Ts>
100template<
typename To,
typename From>
102 To ret =
static_cast<To
>(x);
103 assert(
static_cast<From
>(ret) == x);
108template<
typename T,
typename U>
109constexpr decltype(
auto)
cast(U &&x) {
110 if constexpr(
requires {
const_cast<T>(
FWD(x)); })
111 return const_cast<T>(
FWD(x));
112 else if constexpr(
requires {
static_cast<T>(
FWD(x)); })
113 return static_cast<T>(
FWD(x));
115 return reinterpret_cast<T>(
FWD(x));
119template<
typename To,
typename From>
120requires byte_pointer<To> || byte_pointer<From>
122 constexpr bool is_const = std::is_const_v<std::remove_pointer_t<From>>;
123 using V = std::conditional_t<is_const, const void*, void*>;
128template<
typename To,
typename From>
130 byte_type<To> || char_type<To>
131 || byte_type<From> || char_type<From>
133 assert(!(
s.size() %
sizeof(To)));
139 return static_cast<std::underlying_type_t<T>
>(t);
143inline constexpr auto ptr_diff(
const auto *lhs,
const auto *rhs) {
148inline constexpr bool ptr_cmp(
const auto *p0,
const auto *p1)
149 {
return static_cast<const void*
>(p0) ==
static_cast<const void*
>(p1); }
152template<standard_layout T>
155 return static_cast<std::size_t
>(
ptr_diff(&(t.*p), &t));
158inline auto as_bytes(
const void *p) {
return static_cast<const std::byte*
>(p); }
159inline auto as_bytes(
void *p) {
return static_cast<std::byte*
>(p); }
162 {
return {
as_bytes(x),
sizeof(*x)}; }
164 {
return {
as_bytes(x),
sizeof(*x)}; }
166inline constexpr bool str_less(
const char *lhs,
const char *rhs) {
167 if(!std::is_constant_evaluated())
168 return std::strcmp(lhs, rhs) < 0;
169 while(*lhs && *rhs && *lhs == *rhs)
171 return *rhs && (!*lhs || *lhs < *rhs);
174template<
typename To,
typename From>
176 sizeof(To) ==
sizeof(From)
177 && std::is_trivially_copyable_v<To>
178 && std::is_trivially_copyable_v<From>)
180 static_assert(std::is_trivially_constructible_v<To>);
182 std::memcpy(&ret, &from,
sizeof(To));
188 assert(std::popcount(mask) == 1);
189 return t ^ ((t ^ -
T{value}) & mask);
199template<
typename T,
typename O>
202template<
typename T,
typename R,
typename ...Args>
209template<member_po
inter auto p>
212 requires requires (
T t) { {t.*p}; }
213 constexpr decltype(
auto)
operator()(
const T &t)
217template<member_po
inter auto p>
220 requires requires (
T t) { {t.*p}; }
222 {
return lhs.*p < rhs.*p; }
229constexpr decltype(
auto)
rptr(
auto &&
r) {
return &
r; }
231bool read_file(std::string_view filename, std::string *ret);
232bool read_file(std::string_view filename, std::vector<std::byte> *ret);
assert
Definition debug.lua:3
local r
Definition gamma.lua:7
constexpr auto bit_cast(const From &from)
Definition utils.h:179
constexpr To byte_cast(From p)
reinterpret_cast restricted to conversions from/to char/uchar.
Definition utils.h:121
bool read_file(std::string_view filename, std::string *ret)
Definition utils.cpp:30
constexpr auto to_underlying(T t)
Definition utils.h:138
constexpr chain_cast(auto &&x)
Performs successive static_casts, right to left.
Definition utils.h:95
constexpr rptr(auto &&r)
Allows passing an rvalue pointer to a function.
Definition utils.h:229
constexpr auto set_bit(T t, T mask, bool value)
Definition utils.h:187
constexpr bool str_less(const char *lhs, const char *rhs)
Definition utils.h:166
constexpr cast(U &&x)
Cast value to T with the strictest cast operator.
Definition utils.h:109
constexpr bool ptr_cmp(const auto *p0, const auto *p1)
Compares the address of two pointers.
Definition utils.h:148
To narrow(const From &x)
Casts x to a narrower type, asserting that the value is preserved.
Definition utils.h:101
std::size_t offsetof_ptr(auto T::*p)
Similar to the stdlib's offsetof, but using member data pointers.
Definition utils.h:153
std::span< const std::byte > as_byte_span(const auto *x)
Definition utils.h:161
empty
Definition utils.h:89
constexpr auto ptr_diff(const auto *lhs, const auto *rhs)
Signed distance in bytes between pointers.
Definition utils.h:143
auto as_bytes(const void *p)
Definition utils.h:158
typename member_obj_type< T >::type member_obj_type_t
Definition utils.h:207
#define FWD(...)
Definition utils.h:18
constexpr bool operator()(const T &lhs, const T &rhs)
Definition utils.h:221
Type associated with a member object/function pointer.
Definition utils.h:197
std::chrono::seconds s
Definition timing.cpp:6