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));
92template<
typename ...Ts>
98template<
typename To,
typename From>
100 To ret =
static_cast<To
>(x);
101 assert(
static_cast<From
>(ret) == x);
106template<
typename T,
typename U>
107constexpr decltype(
auto)
cast(U &&x) {
108 if constexpr(
requires {
const_cast<T
>(
FWD(x)); })
109 return const_cast<T
>(
FWD(x));
110 else if constexpr(
requires {
static_cast<T
>(
FWD(x)); })
111 return static_cast<T
>(
FWD(x));
113 return reinterpret_cast<T
>(
FWD(x));
117template<
typename To,
typename From>
118requires byte_pointer<To> || byte_pointer<From>
120 constexpr bool is_const = std::is_const_v<std::remove_pointer_t<From>>;
121 using V = std::conditional_t<is_const, const void*, void*>;
122 return chain_cast<To, V>(p);
126template<
typename To,
typename From>
128 byte_type<To> || char_type<To>
129 || byte_type<From> || char_type<From>
131 assert(!(
s.size() %
sizeof(To)));
132 return {byte_cast<To*>(
s.data()),
s.size() /
sizeof(To)};
137 return static_cast<std::underlying_type_t<T>
>(t);
141inline constexpr auto ptr_diff(
const auto *lhs,
const auto *rhs) {
142 return byte_cast<const char*>(lhs) - byte_cast<const char*>(rhs);
146inline constexpr bool ptr_cmp(
const auto *p0,
const auto *p1)
147 {
return static_cast<const void*
>(p0) ==
static_cast<const void*
>(p1); }
150template<standard_layout T>
153 return static_cast<std::size_t
>(
ptr_diff(&(t.*p), &t));
156inline auto as_bytes(
const void *p) {
return static_cast<const std::byte*
>(p); }
157inline auto as_bytes(
void *p) {
return static_cast<std::byte*
>(p); }
160 {
return {
as_bytes(x),
sizeof(*x)}; }
162 {
return {
as_bytes(x),
sizeof(*x)}; }
164inline constexpr bool str_less(
const char *lhs,
const char *rhs) {
165 if(!std::is_constant_evaluated())
166 return std::strcmp(lhs, rhs) < 0;
167 while(*lhs && *rhs && *lhs == *rhs)
169 return *rhs && (!*lhs || *lhs < *rhs);
172template<
typename To,
typename From>
174 sizeof(To) ==
sizeof(From)
175 && std::is_trivially_copyable_v<To>
176 && std::is_trivially_copyable_v<From>)
178 static_assert(std::is_trivially_constructible_v<To>);
180 std::memcpy(&ret, &from,
sizeof(To));
185constexpr auto set_bit(T t, T mask,
bool value) {
186 assert(std::popcount(mask) == 1);
187 return t ^ ((t ^ -T{value}) & mask);
197template<
typename T,
typename O>
200template<
typename T,
typename R,
typename ...Args>
207template<member_po
inter auto p>
210 requires requires (T t) { {t.*p}; }
211 constexpr decltype(
auto)
operator()(
const T &t)
215template<member_po
inter auto p>
218 requires requires (T t) { {t.*p}; }
220 {
return lhs.*p < rhs.*p; }
227constexpr decltype(
auto)
rptr(
auto &&r) {
return &r; }
229bool read_file(std::string_view filename, std::string *ret);
230bool read_file(std::string_view filename, std::vector<std::byte> *ret);
assert
Definition: debug.lua:3
constexpr auto bit_cast(const From &from)
Definition: utils.h:177
constexpr To byte_cast(From p)
reinterpret_cast restricted to conversions from/to char/uchar.
Definition: utils.h:119
bool read_file(std::string_view filename, std::string *ret)
Definition: utils.cpp:30
constexpr auto to_underlying(T t)
Definition: utils.h:136
constexpr chain_cast(auto &&x)
Performs successive static_casts, right to left.
Definition: utils.h:93
constexpr rptr(auto &&r)
Allows passing an rvalue pointer to a function.
Definition: utils.h:227
constexpr auto set_bit(T t, T mask, bool value)
Definition: utils.h:185
constexpr bool str_less(const char *lhs, const char *rhs)
Definition: utils.h:164
constexpr cast(U &&x)
Cast value to T with the strictest cast operator.
Definition: utils.h:107
typename member_obj_type< T >::type member_obj_type_t
Definition: utils.h:205
constexpr bool ptr_cmp(const auto *p0, const auto *p1)
Compares the address of two pointers.
Definition: utils.h:146
To narrow(const From &x)
Casts x to a narrower type, asserting that the value is preserved.
Definition: utils.h:99
std::size_t offsetof_ptr(auto T::*p)
Similar to the stdlib's offsetof, but using member data pointers.
Definition: utils.h:151
std::span< const std::byte > as_byte_span(const auto *x)
Definition: utils.h:159
empty
Definition: utils.h:89
constexpr auto ptr_diff(const auto *lhs, const auto *rhs)
Signed distance in bytes between pointers.
Definition: utils.h:141
auto as_bytes(const void *p)
Definition: utils.h:156
constexpr bool operator()(const T &lhs, const T &rhs)
Definition: utils.h:219
Type associated with a member object/function pointer.
Definition: utils.h:195
std::chrono::seconds s
Definition: timing.cpp:6
#define FWD(...)
Definition: utils.h:18