basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | e0ae95c6466e73a9afcaffc16d1ab757e39525f7 |
parent | e34ac5ad6024931bb29429f4bb5e88c2f89b3fba |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Mon, 19 May 2025 12:55:02 +0200 |
Rest of the operators
A | include/based/types/builder.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | include/based/types/strong.hpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- |
M | include/based/types/types.hpp | | | ++++++++++++++++ ----------- |
M | test/source/types/type_test.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ------------- |
4 files changed, 621 insertions(+), 46 deletions(-)
diff --git a/ include/based/types/builder.hpp b/ include/based/types/builder.hpp
@@ -0,0 +1,300 @@
#pragma once
// NOLINTBEGIN(*macro-usage*,*macro-parentheses*,*naming*)
namespace based
{
template<typename V>
class builder_type
{
protected:
V m_val; // NOLINT (*protected*)
public:
template<class FV1>
using rebind = builder_type<V>;
using value_type = builder_type;
using basic_type = V;
constexpr ~builder_type() = default;
constexpr explicit builder_type()
: m_val(V())
{
}
constexpr explicit builder_type(V value)
: m_val(value)
{
}
constexpr builder_type(const builder_type&) = default;
constexpr builder_type& operator=(const builder_type&) = default;
constexpr builder_type(builder_type&&) = default;
constexpr builder_type& operator=(builder_type&&) = default;
[[nodiscard]] auto value() const { return m_val; }
};
#define BASED_B_DETAIL_COMMON(Name) \
template<class FV1> \
using rebind = Name<V, FV1>; \
\
using base_type::base_type; \
using base_type::operator=; \
\
using value_type = typename base_type::value_type; \
using basic_type = typename value_type::basic_type; \
\
/* NOLINTNEXTLINE(*crtp*) */ \
constexpr explicit Name(value_type value) \
: base_type(value) \
{ \
}
#define BASED_B_DETAIL_TEMPLATE(Name) \
template<class V, class FV = void> \
class Name : public V::template rebind<FV> \
{ \
using base_type = typename V::template rebind<FV>; \
\
public: \
BASED_B_DETAIL_COMMON(Name) X(FV, Name) \
};
#define BASED_B_DETAIL_SPECIALIZATION(Name) \
template<class V> \
class Name<V, void> : public V::template rebind<Name<V>> \
{ \
using base_type = typename V::template rebind<Name<V>>; \
\
public: \
BASED_B_DETAIL_COMMON(Name) X(Name, Name) \
};
#define BASED_BUILDER_DECORATOR(Name) \
BASED_B_DETAIL_TEMPLATE(Name) BASED_B_DETAIL_SPECIALIZATION(Name)
#define X(FV, Name) \
/* NOLINTNEXTLINE(*explicit*) */ \
Name(basic_type rhs) \
: base_type(rhs) \
{ \
} \
\
Name& operator=(V rhs) \
{ \
this->m_val = rhs; \
return *this; \
}
BASED_BUILDER_DECORATOR(ImplicitFrom)
#undef X
#define X(FV, Name) \
operator basic_type() \
{ \
return this->m_val; \
} \
\
operator const basic_type() const \
{ \
return this->m_val; \
}
BASED_BUILDER_DECORATOR(ImplicitTo)
#undef X
#define X(FV, Name) \
friend constexpr bool operator==(FV lhs, FV rhs) \
{ \
return lhs.m_val == rhs.m_val; \
}
BASED_BUILDER_DECORATOR(Comparable)
#undef X
#define X(FV, Name) \
friend constexpr auto operator<=>(FV lhs, FV rhs) \
{ \
return lhs.m_val <=> rhs.m_val; \
}
BASED_BUILDER_DECORATOR(Ordered)
#undef X
#define X(FV, Name) \
constexpr auto& operator+=(FV rhs) \
{ \
this->m_val += rhs.m_val; \
return *this; \
} \
friend constexpr auto operator+(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val + rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Addable)
#undef X
#define X(FV, Name) \
constexpr auto& operator-=(FV rhs) \
{ \
this->m_val -= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator-(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val - rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Subtractable)
#undef X
#define X(FV, Name) \
constexpr auto& operator*=(FV rhs) \
{ \
this->m_val *= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator*(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val * rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Multipliable)
#undef X
#define X(FV, Name) \
constexpr auto& operator/=(FV rhs) \
{ \
this->m_val /= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator/(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val / rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Divisible)
#undef X
#define X(FV, Name) \
constexpr auto& operator%=(FV rhs) \
{ \
this->m_val %= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator%(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val % rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Modable)
#undef X
#define X(FV, Name) \
friend constexpr auto& operator++(FV& lhs) \
{ \
++lhs.value; \
return lhs; \
}
BASED_BUILDER_DECORATOR(PreIncrementable)
#undef X
#define X(FV, Name) \
friend constexpr auto operator++(FV lhs, int) \
{ \
return FV(lhs.m_val++); \
}
BASED_BUILDER_DECORATOR(PostIncrementable)
#undef X
#define X(FV, Name) \
friend constexpr auto& operator--(FV& lhs) \
{ \
--lhs.value; \
return lhs; \
}
BASED_BUILDER_DECORATOR(PreDecrementable)
#undef X
#define X(FV, Name) \
friend constexpr auto operator--(FV lhs, int) \
{ \
return FV(lhs.m_val--); \
}
BASED_BUILDER_DECORATOR(PostDecrementable)
#undef X
#define X(FV, Name) \
friend constexpr auto operator~(FV rhs) \
{ \
return FV(~rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Notable)
#undef X
#define X(FV, Name) \
constexpr auto& operator&=(FV rhs) \
{ \
this->m_val &= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator&(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val & rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Andable)
#undef X
#define X(FV, Name) \
constexpr auto& operator|=(FV rhs) \
{ \
this->m_val |= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator|(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val | rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Orable)
#undef X
#define X(FV, Name) \
constexpr auto& operator^=(FV rhs) \
{ \
this->m_val ^= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator^(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val ^ rhs.m_val); \
}
BASED_BUILDER_DECORATOR(Xorable)
#undef X
#define X(FV, Name) \
constexpr auto& operator<<=(FV rhs) \
{ \
this->m_val <<= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator<<(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val << rhs.m_val); \
}
BASED_BUILDER_DECORATOR(LShiftable)
#undef X
#define X(FV, Name) \
constexpr auto& operator>>=(FV rhs) \
{ \
this->m_val >>= rhs.m_val; \
return *this; \
} \
friend constexpr auto operator>>(FV lhs, FV rhs) \
{ \
return FV(lhs.m_val >> rhs.m_val); \
}
BASED_BUILDER_DECORATOR(RShiftable)
#undef X
} // namespace based
// NOLINTEND(*macro-usage*,*macro-parentheses*,*naming*)
diff --git a/ include/based/types/strong.hpp b/ include/based/types/strong.hpp
@@ -79,8 +79,7 @@
template<class LHS, class RHS>
})
constexpr auto& operator+=(LHS& lhs, RHS& rhs)
{
lhs.value += rhs.value;
return lhs;
return lhs = lhs + rhs;
}
template<class LHS, class RHS>
@@ -94,6 +93,16 @@
constexpr auto operator-(LHS lhs, RHS rhs)
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires subtractable<LHS, RHS>;
requires SameAs<LHS, decltype(sub(lhs, rhs))>;
})
constexpr auto& operator-=(LHS& lhs, RHS& rhs)
{
return lhs = lhs - rhs;
}
template<class LHS, class RHS>
concept multiplyable = requires(LHS lhs, RHS rhs) { mul(lhs, rhs); };
template<class LHS, class RHS>
@@ -104,6 +113,16 @@
constexpr auto operator*(LHS lhs, RHS rhs)
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires multiplyable<LHS, RHS>;
requires SameAs<LHS, decltype(mul(lhs, rhs))>;
})
constexpr auto& operator*=(LHS& lhs, RHS& rhs)
{
return lhs = lhs * rhs;
}
template<class LHS, class RHS>
concept divisible = requires(LHS lhs, RHS rhs) { div(lhs, rhs); };
template<class LHS, class RHS>
@@ -114,6 +133,16 @@
constexpr auto operator/(LHS lhs, RHS rhs)
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires divisible<LHS, RHS>;
requires SameAs<LHS, decltype(div(lhs, rhs))>;
})
constexpr auto& operator/=(LHS& lhs, RHS& rhs)
{
return lhs = lhs / rhs;
}
template<class LHS, class RHS>
concept modable = requires(LHS lhs, RHS rhs) { mod(lhs, rhs); };
template<class LHS, class RHS>
@@ -124,6 +153,56 @@
constexpr auto operator%(LHS lhs, RHS rhs)
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires modable<LHS, RHS>;
requires SameAs<LHS, decltype(mod(lhs, rhs))>;
})
constexpr auto& operator%=(LHS& lhs, RHS& rhs)
{
return lhs = lhs % rhs;
}
template<class LHS, class RHS>
concept lshiftable = requires(LHS lhs, RHS rhs) { lshift(lhs, rhs); };
template<class LHS, class RHS>
requires lshiftable<LHS, RHS>
constexpr auto operator<<(LHS lhs, RHS rhs)
{
return BASED_DETAIL_MACRO(lshift(lhs, rhs), lhs.value << rhs.value);
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires lshiftable<LHS, RHS>;
requires SameAs<LHS, decltype(lshift(lhs, rhs))>;
})
constexpr auto& operator<<=(LHS& lhs, RHS& rhs)
{
return lhs = lhs << rhs;
}
template<class LHS, class RHS>
concept rshiftable = requires(LHS lhs, RHS rhs) { rshift(lhs, rhs); };
template<class LHS, class RHS>
requires rshiftable<LHS, RHS>
constexpr auto operator>>(LHS lhs, RHS rhs)
{
return BASED_DETAIL_MACRO(rshift(lhs, rhs), lhs.value >> rhs.value);
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires rshiftable<LHS, RHS>;
requires SameAs<LHS, decltype(rshift(lhs, rhs))>;
})
constexpr auto& operator>>=(LHS& lhs, RHS& rhs)
{
return lhs = lhs >> rhs;
}
template<class LHS, class RHS>
concept andable = requires(LHS lhs, RHS rhs) { land(lhs, rhs); };
template<class LHS, class RHS>
@@ -134,6 +213,16 @@
constexpr auto operator&(LHS lhs, RHS rhs)
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires andable<LHS, RHS>;
requires SameAs<LHS, decltype(land(lhs, rhs))>;
})
constexpr auto& operator&=(LHS& lhs, RHS& rhs)
{
return lhs = lhs & rhs;
}
template<class LHS, class RHS>
concept orable = requires(LHS lhs, RHS rhs) { lor(lhs, rhs); };
template<class LHS, class RHS>
@@ -144,6 +233,16 @@
constexpr auto operator|(LHS lhs, RHS rhs)
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires orable<LHS, RHS>;
requires SameAs<LHS, decltype(lor(lhs, rhs))>;
})
constexpr auto& operator|=(LHS& lhs, RHS& rhs)
{
return lhs = lhs | rhs;
}
template<class LHS, class RHS>
concept xorable = requires(LHS lhs, RHS rhs) { lxor(lhs, rhs); };
template<class LHS, class RHS>
@@ -153,6 +252,27 @@
constexpr auto operator^(LHS lhs, RHS rhs)
return BASED_DETAIL_MACRO(lxor(lhs, rhs), lhs.value ^ rhs.value);
}
template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires xorable<LHS, RHS>;
requires SameAs<LHS, decltype(lxor(lhs, rhs))>;
})
constexpr auto& operator^=(LHS& lhs, RHS& rhs)
{
return lhs = lhs ^ rhs;
}
template<class LHS>
concept lnotable = requires(LHS lhs) { lnot(lhs); };
template<class LHS>
requires lnotable<LHS>
constexpr auto operator~(LHS lhs)
{
lhs.value = ~lhs.value;
return lhs;
}
template<class LHS>
concept preincable = requires(LHS lhs) { preinc(lhs); };
diff --git a/ include/based/types/types.hpp b/ include/based/types/types.hpp
@@ -1,5 +1,4 @@
#pragma once
#include "based/macro/foreach_1.hpp"
#include "based/types/strong.hpp"
@@ -20,7 +19,7 @@
using bu64 = unsigned long int;
using size_t = bu64;
#define TYPE(Name) \
#define BASED_DETAIL_TYPE(Name) \
/* NOLINTNEXTLINE(*macro*) */ \
struct Name : strong_type<b##Name, Name> \
{ \
@@ -37,10 +36,15 @@
using size_t = bu64;
} \
} // namespace literals
TYPE(i8)
TYPE(i16)
TYPE(i32)
TYPE(i64)
BASED_DETAIL_TYPE(i8)
BASED_DETAIL_TYPE(i16)
BASED_DETAIL_TYPE(i32)
BASED_DETAIL_TYPE(i64)
BASED_DETAIL_TYPE(u8)
BASED_DETAIL_TYPE(u16)
BASED_DETAIL_TYPE(u32)
BASED_DETAIL_TYPE(u64)
#define BASED_DETAIL_OP_UNARY(Prefix, Name, Index) \
auto Name(Prefix##8)->Prefix##8; \
@@ -74,11 +78,6 @@
BASED_FOREACH_1(
i, BASED_DETAIL_OP_BINARY, compare, order, add, sub, mul, div, mod
)
TYPE(u8)
TYPE(u16)
TYPE(u32)
TYPE(u64)
BASED_FOREACH_1(u, BASED_DETAIL_OP_UNARY, preinc, postinc, predec, postdec)
BASED_FOREACH_1(
u,
@@ -90,11 +89,17 @@
BASED_FOREACH_1(
mul,
div,
mod,
lshift,
rshift,
land,
lor,
lxor
)
#undef BASED_DETAIL_TYPE
#undef BASED_DETAIL_OP_UNARY
#undef BASED_DETAIL_OP_BINARY
// NOLINTEND(google-runtime-int)
} // namespace based
diff --git a/ test/source/types/type_test.cpp b/ test/source/types/type_test.cpp
@@ -1,4 +1,4 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
// #define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <catch2/catch_test_macros.hpp>
@@ -16,7 +16,6 @@
TEST_CASE("u8", "[types/u8]")
// clang-format off
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs - rhs } -> SameAs<u8>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs + rhs } -> SameAs<u8>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs - rhs } -> SameAs<u8>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs * rhs } -> SameAs<u8>; });
@@ -25,14 +24,27 @@
TEST_CASE("u8", "[types/u8]")
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs & rhs } -> SameAs<u8>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs | rhs } -> SameAs<u8>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs ^ rhs } -> SameAs<u8>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs << rhs } -> SameAs<u8>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs >> rhs } -> SameAs<u8>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs += rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs -= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs *= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs /= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs %= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs &= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs |= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs ^= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs <<= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u8 rhs) { { lhs >>= rhs } -> SameAs<u8&>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs - rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs + rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs - rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs * rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs / rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs << rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs >> rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs % rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs & rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u8 lhs, u16 rhs) { { lhs | rhs } -> SameAs<u16>; });
@@ -40,24 +52,26 @@
TEST_CASE("u8", "[types/u8]")
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs + rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs * rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs / rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs % rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs << rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs >> rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs & rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs | rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs ^ rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u8 lhs, u32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs + rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs * rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs / rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs % rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs << rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs >> rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs & rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs | rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u8 lhs, u64 rhs) { { lhs ^ rhs } -> SameAs<u64>; });
@@ -69,48 +83,72 @@
TEST_CASE("u16", "[types/u16]")
// clang-format off
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs - rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs + rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs - rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs * rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs / rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs % rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs << rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs >> rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs & rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs | rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs ^ rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs += rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs -= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs *= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs /= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs %= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs &= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs |= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs ^= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs <<= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u8 rhs) { { lhs >>= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs - rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs + rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs - rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs * rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs / rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs % rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs << rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs >> rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs & rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs | rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs ^ rhs } -> SameAs<u16>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs += rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs -= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs *= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs /= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs %= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs &= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs |= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs ^= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs <<= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u16 rhs) { { lhs >>= rhs } -> SameAs<u16&>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs + rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs * rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs / rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs % rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs << rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs >> rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs & rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs | rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs ^ rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u16 lhs, u32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs + rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs * rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs / rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs % rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs << rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs >> rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs & rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs | rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u16 lhs, u64 rhs) { { lhs ^ rhs } -> SameAs<u64>; });
@@ -122,48 +160,82 @@
TEST_CASE("u32", "[types/u32]")
// clang-format off
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs + rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs * rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs / rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs % rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs << rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs >> rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs & rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs | rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs ^ rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs += rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs -= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs *= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs /= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs %= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs &= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs |= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs ^= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs <<= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u8 rhs) { { lhs >>= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs + rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs * rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs / rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs % rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs << rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs >> rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs & rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs | rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs ^ rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs += rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs -= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs *= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs /= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs %= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs &= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs |= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs ^= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs <<= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u16 rhs) { { lhs >>= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs + rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs - rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs * rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs / rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs % rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs << rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs >> rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs & rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs | rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs ^ rhs } -> SameAs<u32>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs += rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs -= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs *= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs /= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs %= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs &= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs |= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs ^= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs <<= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs >>= rhs } -> SameAs<u32&>; });
STATIC_REQUIRE(requires(u32 lhs, u32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs + rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs * rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs / rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs % rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs << rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs >> rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs & rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs | rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u32 lhs, u64 rhs) { { lhs ^ rhs } -> SameAs<u64>; });
@@ -175,51 +247,95 @@
TEST_CASE("u64", "[types/u64]")
// clang-format off
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs + rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs * rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs / rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs % rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs << rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs >> rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs & rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs | rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs ^ rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs += rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs -= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs *= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs /= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs %= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs &= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs |= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs ^= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs <<= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u8 rhs) { { lhs >>= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs + rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs * rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs / rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs % rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs << rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs >> rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs & rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs | rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs ^ rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs += rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs -= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs *= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs /= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs %= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs &= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs |= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs ^= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs <<= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u16 rhs) { { lhs >>= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs + rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs * rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs / rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs % rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs << rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs >> rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs & rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs | rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs ^ rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs += rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs -= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs *= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs /= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs %= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs &= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs |= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs ^= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs <<= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs >>= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs + rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs - rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs * rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs / rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs % rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs << rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs >> rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs & rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs | rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs ^ rhs } -> SameAs<u64>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs += rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs -= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs *= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs /= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs %= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs &= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs |= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs ^= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs <<= rhs } -> SameAs<u64&>; });
STATIC_REQUIRE(requires(u64 lhs, u64 rhs) { { lhs >>= rhs } -> SameAs<u64&>; });
// clang-format on
}
@@ -233,16 +349,19 @@
TEST_CASE("i8", "[types/i8]")
// clang-format off
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs - rhs } -> SameAs<i8>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs + rhs } -> SameAs<i8>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs - rhs } -> SameAs<i8>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs * rhs } -> SameAs<i8>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs / rhs } -> SameAs<i8>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs % rhs } -> SameAs<i8>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs += rhs } -> SameAs<i8&>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs -= rhs } -> SameAs<i8&>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs *= rhs } -> SameAs<i8&>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs /= rhs } -> SameAs<i8&>; });
STATIC_REQUIRE(requires(i8 lhs, i8 rhs) { { lhs %= rhs } -> SameAs<i8&>; });
STATIC_REQUIRE(requires(i8 lhs, i16 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i8 lhs, i16 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i8 lhs, i16 rhs) { { lhs - rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i8 lhs, i16 rhs) { { lhs + rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i8 lhs, i16 rhs) { { lhs - rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i8 lhs, i16 rhs) { { lhs * rhs } -> SameAs<i16>; });
@@ -251,7 +370,6 @@
TEST_CASE("i8", "[types/i8]")
STATIC_REQUIRE(requires(i8 lhs, i32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i8 lhs, i32 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i8 lhs, i32 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i8 lhs, i32 rhs) { { lhs + rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i8 lhs, i32 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i8 lhs, i32 rhs) { { lhs * rhs } -> SameAs<i32>; });
@@ -260,7 +378,6 @@
TEST_CASE("i8", "[types/i8]")
STATIC_REQUIRE(requires(i8 lhs, i32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i8 lhs, i64 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i8 lhs, i64 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i8 lhs, i64 rhs) { { lhs + rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i8 lhs, i64 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i8 lhs, i64 rhs) { { lhs * rhs } -> SameAs<i64>; });
@@ -274,25 +391,32 @@
TEST_CASE("i16", "[types/i16]")
// clang-format off
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs - rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs + rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs - rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs * rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs / rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs % rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs += rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs -= rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs *= rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs /= rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i8 rhs) { { lhs %= rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs - rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs + rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs - rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs * rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs / rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs % rhs } -> SameAs<i16>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs += rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs -= rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs *= rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs /= rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i16 rhs) { { lhs %= rhs } -> SameAs<i16&>; });
STATIC_REQUIRE(requires(i16 lhs, i32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i16 lhs, i32 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i16 lhs, i32 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i16 lhs, i32 rhs) { { lhs + rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i16 lhs, i32 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i16 lhs, i32 rhs) { { lhs * rhs } -> SameAs<i32>; });
@@ -301,7 +425,6 @@
TEST_CASE("i16", "[types/i16]")
STATIC_REQUIRE(requires(i16 lhs, i32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i16 lhs, i64 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i16 lhs, i64 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i16 lhs, i64 rhs) { { lhs + rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i16 lhs, i64 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i16 lhs, i64 rhs) { { lhs * rhs } -> SameAs<i64>; });
@@ -315,34 +438,45 @@
TEST_CASE("i32", "[types/i32]")
// clang-format off
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs + rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs * rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs / rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs % rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs += rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs -= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs *= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs /= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i8 rhs) { { lhs %= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs + rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs * rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs / rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs % rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs += rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs -= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs *= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs /= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i16 rhs) { { lhs %= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs + rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs - rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs * rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs / rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs % rhs } -> SameAs<i32>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs += rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs -= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs *= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs /= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs %= rhs } -> SameAs<i32&>; });
STATIC_REQUIRE(requires(i32 lhs, i32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i32 lhs, i64 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i32 lhs, i64 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i32 lhs, i64 rhs) { { lhs + rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i32 lhs, i64 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i32 lhs, i64 rhs) { { lhs * rhs } -> SameAs<i64>; });
@@ -356,38 +490,54 @@
TEST_CASE("i64", "[types/i64]")
// clang-format off
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs + rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs * rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs / rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs % rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs += rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs -= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs *= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs /= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i8 rhs) { { lhs %= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs + rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs * rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs / rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs % rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs += rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs -= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs *= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs /= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i16 rhs) { { lhs %= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs + rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs * rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs / rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs % rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs += rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs -= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs *= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs /= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs %= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i32 rhs) { { lhs == rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs <= rhs } -> SameAs<bool>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs + rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs - rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs * rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs / rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs % rhs } -> SameAs<i64>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs += rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs -= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs *= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs /= rhs } -> SameAs<i64&>; });
STATIC_REQUIRE(requires(i64 lhs, i64 rhs) { { lhs %= rhs } -> SameAs<i64&>; });
// clang-format on
}