12using i8 = std::int8_t;
13using i16 = std::int16_t;
14using i32 = std::int32_t;
15using i64 = std::int64_t;
17using u8 = std::uint8_t;
18using u16 = std::uint16_t;
19using u32 = std::uint32_t;
20using u64 = std::uint64_t;
22using idx = std::ptrdiff_t;
23using usize = std::size_t;
24using isize = std::ptrdiff_t;
25using byte = std::byte;
27using const_voidp =
const void*;
29template<
typename T,
typename D = std::default_delete<T>>
30using up = std::unique_ptr<T, D>;
36[[nodiscard]]
constexpr bool fuzzy_equal(T a, T b) {
37 const T scale = std::same_as<T, double> ? T(1000000000000.) : T(100000.f);
38 return std::fabs(a - b) * scale <= std::min(std::fabs(a), std::fabs(b));
42using param_t = std::conditional_t<std::is_trivially_copyable_v<T> &&
sizeof(T) <= 32, T,
const T&>;
45auto cmp_set(T& lhs, param_t<T> rhs)
noexcept ->
bool {
46 if constexpr (std::is_floating_point_v<T>) {
47 if (! fuzzy_equal(lhs, rhs)) {
65 template<
class... Args>
66 decltype(
auto)
operator()(Args&&... args)
const {
68 return f(*
this, std::forward<Args>(args)...);
73y_combinator(F) -> y_combinator<F>;