based

Opinionated utility library
git clone git://git.dimitrijedobrota.com/based.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit 185d19a48385c7c85f80f391939f9ab0af97b43a
parent 361e63c3976c33718919e30ecce827bb6d18d14e
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Fri, 20 Jun 2025 14:51:53 +0200

No more is_traits, refactor concepts

Diffstat:
M include/based/algorithm/clamp.hpp | ++++++++++ ---------
M include/based/algorithm/max.hpp | +++++++++++ -------
M include/based/algorithm/min.hpp | +++++++++++ -------
M include/based/character/type.hpp | ++
M include/based/concept/callable.hpp | ++ --
M include/based/concept/comparable/equal.hpp | +++ ---
M include/based/concept/comparable/greater.hpp | +++ ---
M include/based/concept/comparable/greater_equal.hpp | +++ ---
M include/based/concept/comparable/less.hpp | +++ ---
M include/based/concept/comparable/less_equal.hpp | +++ ---
M include/based/concept/comparable/not_equal.hpp | +++ ---
D include/based/concept/is/castable.hpp | -----------
D include/based/concept/is/convertable.hpp | ---------------
D include/based/concept/is/enum.hpp | ---------------------------
D include/based/concept/is/invocable.hpp | -----------
D include/based/concept/is/regular.hpp | ----------------
D include/based/concept/is/same.hpp | ---------------
D include/based/concept/is/semiregular.hpp | ----------------
A include/based/concept/is_arithmetic.hpp | +++++++++++++
A include/based/concept/is_array.hpp | +++++++++++++++++++++++++
A include/based/concept/is_base_of.hpp | ++++++++++++++++++++++++++++++++++
A include/based/concept/is_castable.hpp | +++++++++++
A include/based/concept/is_class.hpp | ++++++++++++++++++++++++
A include/based/concept/is_const.hpp | +++++++++++++++++++++
A include/based/concept/is_convertible.hpp | +++++++++++
A include/based/concept/is_enum.hpp | +++++++++++++++++++++++++++
A include/based/concept/is_floating_point.hpp | ++++++++++++++
A include/based/concept/is_function.hpp | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A include/based/concept/is_integral.hpp | ++++++++++++++++++
A include/based/concept/is_invocable.hpp | ++++++++++++++
A include/based/concept/is_lvalue_reference.hpp | +++++++++++++++++++++
A include/based/concept/is_member_pointer.hpp | ++++++++++++++++++++++
A include/based/concept/is_null_pointer.hpp | +++++++++++++
A include/based/concept/is_object.hpp | ++++++++++++++
A include/based/concept/is_pointer.hpp | ++++++++++++++++++++++++
A include/based/concept/is_reference_wrapper.hpp | +++++++++++++++++++++
A include/based/concept/is_regular.hpp | ++++++++++++++++
A include/based/concept/is_rvalue_reference.hpp | +++++++++++++++++++++
A include/based/concept/is_same.hpp | +++++++++++++++++++++++++
A include/based/concept/is_scalar.hpp | ++++++++++++++++
A include/based/concept/is_semiregular.hpp | ++++++++++++++++
A include/based/concept/is_union.hpp | +++++++++++
A include/based/concept/is_void.hpp | ++++++++++++
M include/based/concept/iterator.hpp | ++++++ ------
M include/based/concept/procedure/domain.hpp | +++++++++++ ---------
M include/based/concept/procedure/procedure.hpp | ++++++ ------
M include/based/concept/procedure/procedure_iter.hpp | ++ --
M include/based/container/list.hpp | + -
M include/based/enum/enum.hpp | +++++++ -------
M include/based/functional/function.hpp | ++ --
M include/based/functional/invoke.hpp | ++++++++ --------
M include/based/functional/reference_wrapper.hpp | ++++ ----
M include/based/instrumentation/instrumented.hpp | ++ --
M include/based/integral/strong.hpp | +++++++++++ --------------
M include/based/memory/addressof.hpp | ++ --
M include/based/trait/decay.hpp | ++++ ----
M include/based/trait/invoke_result.hpp | ++++++++++ ---------
D include/based/trait/is/arithmetic.hpp | ------------------
D include/based/trait/is/array.hpp | -----------------------------
D include/based/trait/is/base_of.hpp | --------------------------------------------
D include/based/trait/is/class.hpp | ----------------------------
D include/based/trait/is/const.hpp | ---------------------
D include/based/trait/is/convertable.hpp | --------------
D include/based/trait/is/enum.hpp | --------------
D include/based/trait/is/floating_point.hpp | ------------------------
D include/based/trait/is/function.hpp | ---------------------------------------------------------------------------------
D include/based/trait/is/integral.hpp | -------------------------------
D include/based/trait/is/invocable.hpp | --------------------
D include/based/trait/is/lvalue_reference.hpp | ---------------------
D include/based/trait/is/member_pointer.hpp | --------------------------------
D include/based/trait/is/null_pointer.hpp | ------------------
D include/based/trait/is/object.hpp | --------------------------
D include/based/trait/is/pointer.hpp | ------------------------------------
D include/based/trait/is/reference_wrapper.hpp | ---------------------
D include/based/trait/is/rvalue_reference.hpp | ---------------------
D include/based/trait/is/same.hpp | ---------------------
D include/based/trait/is/scalar.hpp | ---------------------------
D include/based/trait/is/union.hpp | --------------
D include/based/trait/is/void.hpp | -----------------
M include/based/utility/forward.hpp | ++ --
M test/source/algorithm/max_test.cpp | +++++++++++++++++++++++++++++++++ ---------------------------------
M test/source/algorithm/min_test.cpp | ++++++++++++++++++++++++++++++++ --------------------------------
M test/source/concept/callable_test.cpp | ++++++++ ---------
M test/source/enum/bitmask_test.cpp | +++++++++++++++++ ------------------
M test/source/enum/standard_test.cpp | +++ ---
M test/source/integral/literals_test.cpp | ++++++++++++++++++++++++++++++ ------------------------
M test/source/integral/type_test.cpp | +++++++++++++++++++++++++++++++++++++++++ -----------------------------------------
M test/source/trait/invoke_result_test.cpp | ++ --
M test/source/trait/is_array_test.cpp | ++++++++++ ----------
M test/source/trait/is_base_of_test.cpp | +++++++++ ---------
M test/source/trait/is_class_test.cpp | +++++++++++ -----------
M test/source/trait/is_const_test.cpp | +++++++++++++++++++++++ -----------------------
M test/source/trait/is_enum_test.cpp | +++++++ -------
M test/source/trait/is_lvalue_reference_test.cpp | +++++++++++++++++++++++ -----------------------
M test/source/trait/is_null_pointer_test.cpp | ++++++++++++ ------------
M test/source/trait/is_rvalue_reference_test.cpp | +++++++++++++++++++++++++ -------------------------
M test/source/trait/is_void_test.cpp | ++++++++++ -----------
M test/source/trait/remove_const_test.cpp | +++++++++++++++++++++++++++ --------------------------
M test/source/trait/remove_cv_test.cpp | +++++++++++++++++++++++++++ --------------------------
M test/source/trait/remove_cvref_test.cpp | +++++++++++++++++++++++++++ --------------------------
M test/source/trait/remove_pointer_test.cpp | ++++++++++++ -----------
M test/source/trait/remove_reference_test.cpp | +++++++++++++++++++++++++++ --------------------------
M test/source/trait/remove_volatile_test.cpp | +++++++++++++++++++++++++++ --------------------------
M test/source/trait/signature_test.cpp | +++++++++++++++++++++++++++++++++++++++++ -----------------------------------------

104 files changed, 1759 insertions(+), 1897 deletions(-)


diff --git a/ include/based/algorithm/clamp.hpp b/ include/based/algorithm/clamp.hpp

@@ -2,8 +2,8 @@


#include "based/algorithm/max.hpp"
#include "based/algorithm/min.hpp"
#include "based/concept/is/regular.hpp"
#include "based/concept/is/same.hpp"
#include "based/concept/is_regular.hpp"
#include "based/concept/is_same.hpp"
#include "based/concept/procedure/procedure.hpp"
#include "based/trait/remove_reference.hpp"
#include "based/utility/forward.hpp"

@@ -13,11 +13,11 @@ namespace based


// clamp a value between low and high
template<
BareRegular T,
BareRegular U,
BareRegular V,
trait::BareRegular T,
trait::BareRegular U,
trait::BareRegular V,
RegularProcedure<bool, T, T> Rel>
requires(BareSameAs<T, U> && BareSameAs<T, V>)
requires(trait::IsSameBare<T, U> && trait::IsSameBare<T, V>)
constexpr decltype(auto) clamp(T&& value, U&& low, V&& high, Rel rel)
{
return based::max(

@@ -28,15 +28,16 @@ constexpr decltype(auto) clamp(T&& value, U&& low, V&& high, Rel rel)

}

// clamp a value between low and high
template<BareRegular T, BareRegular U, BareRegular V>
requires(BareSameAs<T, U> && BareSameAs<T, V>)
template<trait::BareRegular T, trait::BareRegular U, trait::BareRegular V>
requires(trait::IsSameBare<T, U> && trait::IsSameBare<T, V>)
constexpr decltype(auto) clamp(T&& value, U&& low, V&& high)
{
return based::clamp(
based::forward<T>(value),
based::forward<U>(low),
based::forward<V>(high),
[](const trait::RemoveReference<T>& llhs, const trait::RemoveReference<U>& lrhs)
[](const trait::RemoveReference<T>& llhs,
const trait::RemoveReference<U>& lrhs)
{
return llhs < lrhs;
}

diff --git a/ include/based/algorithm/max.hpp b/ include/based/algorithm/max.hpp

@@ -1,7 +1,7 @@

#pragma once

#include "based/concept/is/regular.hpp"
#include "based/concept/is/same.hpp"
#include "based/concept/is_regular.hpp"
#include "based/concept/is_same.hpp"
#include "based/concept/procedure/procedure.hpp"
#include "based/trait/remove_reference.hpp"
#include "based/utility/forward.hpp"

@@ -10,22 +10,26 @@ namespace based

{

// returns max element, second if equal
template<BareRegular T, BareRegular U, RegularProcedure<bool, T, T> Rel>
requires BareSameAs<T, U>
template<
trait::BareRegular T,
trait::BareRegular U,
RegularProcedure<bool, T, T> Rel>
requires trait::IsSameBare<T, U>
constexpr decltype(auto) max(T&& lhs, U&& rhs, Rel rel)
{
return rel(rhs, lhs) ? based::forward<T>(lhs) : based::forward<U>(rhs);
}

// returns max element, second if equal
template<BareRegular T, BareRegular U>
requires BareSameAs<T, U>
template<trait::BareRegular T, trait::BareRegular U>
requires trait::IsSameBare<T, U>
constexpr decltype(auto) max(T&& lhs, U&& rhs)
{
return based::max(
based::forward<T>(lhs),
based::forward<U>(rhs),
[](const trait::RemoveReference<T>& llhs, const trait::RemoveReference<U>& lrhs)
[](const trait::RemoveReference<T>& llhs,
const trait::RemoveReference<U>& lrhs)
{
return llhs < lrhs;
}

diff --git a/ include/based/algorithm/min.hpp b/ include/based/algorithm/min.hpp

@@ -1,7 +1,7 @@

#pragma once

#include "based/concept/is/regular.hpp"
#include "based/concept/is/same.hpp"
#include "based/concept/is_regular.hpp"
#include "based/concept/is_same.hpp"
#include "based/concept/procedure/procedure.hpp"
#include "based/trait/remove_reference.hpp"
#include "based/utility/forward.hpp"

@@ -9,22 +9,26 @@

namespace based
{

template<BareRegular T, BareRegular U, RegularProcedure<bool, T, T> Rel>
requires BareSameAs<T, U>
template<
trait::BareRegular T,
trait::BareRegular U,
RegularProcedure<bool, T, T> Rel>
requires trait::IsSameBare<T, U>
constexpr decltype(auto) min(T&& lhs, U&& rhs, Rel rel)
{
return rel(rhs, lhs) ? based::forward<U>(rhs) : based::forward<T>(lhs);
}

// returns min element, first if equal
template<BareRegular T, BareRegular U>
requires BareSameAs<T, U>
template<trait::BareRegular T, trait::BareRegular U>
requires trait::IsSameBare<T, U>
constexpr decltype(auto) min(T&& lhs, U&& rhs)
{
return based::min(
based::forward<T>(lhs),
based::forward<U>(rhs),
[](const trait::RemoveReference<T>& llhs, const trait::RemoveReference<U>& lrhs)
[](const trait::RemoveReference<T>& llhs,
const trait::RemoveReference<U>& lrhs)
{
return llhs < lrhs;
}

diff --git a/ include/based/character/type.hpp b/ include/based/character/type.hpp

@@ -1,5 +1,7 @@

#pragma once

#include <compare>

#include "based/integral/types.hpp"

namespace based

diff --git a/ include/based/concept/callable.hpp b/ include/based/concept/callable.hpp

@@ -1,7 +1,7 @@

#pragma once

#include "based/concept/is_function.hpp"
#include "based/trait/decay.hpp"
#include "based/trait/is/function.hpp"
#include "based/trait/remove_pointer.hpp"
#include "based/trait/signature.hpp"

@@ -12,7 +12,7 @@ template<typename T>

struct callable;

template<typename T>
requires(is_function_v<T>)
requires(trait::IsFunction<T>)
struct callable<T> : public Signature<trait::Decay<T>>
{
};

diff --git a/ include/based/concept/comparable/equal.hpp b/ include/based/concept/comparable/equal.hpp

@@ -1,6 +1,6 @@

#pragma once

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/trait/remove_reference.hpp"

namespace based

@@ -12,8 +12,8 @@ template<typename T>

concept EqualComparable = requires(
const trait::RemoveReference<T>& lhs, const trait::RemoveReference<T>& rhs
) {
{ lhs == rhs } -> SameAs<bool>;
{ rhs == lhs } -> SameAs<bool>;
{ lhs == rhs } -> trait::IsSame<bool>;
{ rhs == lhs } -> trait::IsSame<bool>;
};

// clang-format on

diff --git a/ include/based/concept/comparable/greater.hpp b/ include/based/concept/comparable/greater.hpp

@@ -1,6 +1,6 @@

#pragma once

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/trait/remove_reference.hpp"

namespace based

@@ -12,8 +12,8 @@ template<typename T>

concept GreaterComparable = requires
(const trait::RemoveReference<T>& lhs, const trait::RemoveReference<T>& rhs)
{
{lhs > rhs} -> SameAs<bool>;
{rhs > lhs} -> SameAs<bool>;
{lhs > rhs} -> trait::IsSame<bool>;
{rhs > lhs} -> trait::IsSame<bool>;
};

// clang-format on

diff --git a/ include/based/concept/comparable/greater_equal.hpp b/ include/based/concept/comparable/greater_equal.hpp

@@ -1,6 +1,6 @@

#pragma once

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/trait/remove_reference.hpp"

namespace based

@@ -12,8 +12,8 @@ template<typename T>

concept LessEqualComparable = requires
(const trait::RemoveReference<T>& lhs, const trait::RemoveReference<T>& rhs)
{
{lhs <= rhs} -> SameAs<bool>;
{rhs <= lhs} -> SameAs<bool>;
{lhs <= rhs} -> trait::IsSame<bool>;
{rhs <= lhs} -> trait::IsSame<bool>;
};

// clang-format on

diff --git a/ include/based/concept/comparable/less.hpp b/ include/based/concept/comparable/less.hpp

@@ -1,6 +1,6 @@

#pragma once

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/trait/remove_reference.hpp"

namespace based

@@ -12,8 +12,8 @@ template<typename T>

concept LessComparable = requires
(const trait::RemoveReference<T>& lhs, const trait::RemoveReference<T>& rhs)
{
{lhs < rhs} -> SameAs<bool>;
{rhs < lhs} -> SameAs<bool>;
{lhs < rhs} -> trait::IsSame<bool>;
{rhs < lhs} -> trait::IsSame<bool>;
};

// clang-format on

diff --git a/ include/based/concept/comparable/less_equal.hpp b/ include/based/concept/comparable/less_equal.hpp

@@ -1,6 +1,6 @@

#pragma once

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/trait/remove_reference.hpp"

namespace based

@@ -12,8 +12,8 @@ template<typename T>

concept GreaterEqualComparable = requires
(const trait::RemoveReference<T>& lhs, const trait::RemoveReference<T>& rhs)
{
{lhs >= rhs} -> SameAs<bool>;
{rhs >= lhs} -> SameAs<bool>;
{lhs >= rhs} -> trait::IsSame<bool>;
{rhs >= lhs} -> trait::IsSame<bool>;
};

// clang-format on

diff --git a/ include/based/concept/comparable/not_equal.hpp b/ include/based/concept/comparable/not_equal.hpp

@@ -1,6 +1,6 @@

#pragma once

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/trait/remove_reference.hpp"

namespace based

@@ -12,8 +12,8 @@ template<typename T>

concept NotEqualComparable = requires
(const trait::RemoveReference<T>& lhs, const trait::RemoveReference<T>& rhs)
{
{lhs != rhs} -> SameAs<bool>;
{rhs != lhs} -> SameAs<bool>;
{lhs != rhs} -> trait::IsSame<bool>;
{rhs != lhs} -> trait::IsSame<bool>;
};

// clang-format on

diff --git a/ include/based/concept/is/castable.hpp b/ include/based/concept/is/castable.hpp

@@ -1,11 +0,0 @@

#pragma once

#include "based/utility/declvar.hpp"

namespace based
{

template<class From, class To>
concept CastableTo = requires { static_cast<To>(declval<From>()); };

} // namespace based

diff --git a/ include/based/concept/is/convertable.hpp b/ include/based/concept/is/convertable.hpp

@@ -1,15 +0,0 @@

#pragma once

#include "based/trait/is/convertable.hpp"
#include "based/utility/declvar.hpp"

namespace based
{

template<class From, class To>
concept ConvertibleTo = requires {
requires(is_convertible_v<From, To>);
static_cast<To>(declval<From>());
};

} // namespace based

diff --git a/ include/based/concept/is/enum.hpp b/ include/based/concept/is/enum.hpp

@@ -1,27 +0,0 @@

#pragma once

#include "based/trait/is/enum.hpp"

namespace based
{

namespace detail
{

void test_conversion(...); // selected when E is complete and scoped
void test_conversion(int) = delete; // selected when E is complete and unscoped

} // namespace detail

template<class T>
concept IsEnum = is_enum_v<T>;

template<class T>
concept IsScopedEnum = requires {
requires(IsEnum<T>);
{
detail::test_conversion(T {})
};
};

} // namespace based

diff --git a/ include/based/concept/is/invocable.hpp b/ include/based/concept/is/invocable.hpp

@@ -1,11 +0,0 @@

#pragma once

#include "based/trait/is/invocable.hpp"

namespace based
{

template<typename P, typename... Args>
concept Invocable = is_invocable_v<P, Args...>;

} // namespace based

diff --git a/ include/based/concept/is/regular.hpp b/ include/based/concept/is/regular.hpp

@@ -1,16 +0,0 @@

#pragma once

#include <concepts>

#include "based/trait/remove_cvref.hpp"

namespace based
{

template<typename T>
concept Regular = std::regular<T>;

template<typename T>
concept BareRegular = Regular<trait::RemoveCvref<T>>;

} // namespace based

diff --git a/ include/based/concept/is/same.hpp b/ include/based/concept/is/same.hpp

@@ -1,15 +0,0 @@

#pragma once

#include "based/trait/is/same.hpp"
#include "based/trait/remove_cvref.hpp"

namespace based
{

template<class T, class U>
concept SameAs = is_same_v<T, U> && is_same_v<U, T>;

template<class T, class U>
concept BareSameAs = SameAs<trait::RemoveCvref<T>, trait::RemoveCvref<U>>;

} // namespace based

diff --git a/ include/based/concept/is/semiregular.hpp b/ include/based/concept/is/semiregular.hpp

@@ -1,16 +0,0 @@

#pragma once

#include <concepts>

#include "based/trait/remove_cvref.hpp"

namespace based
{

template<typename T>
concept Semiregular = std::semiregular<T>;

template<typename T>
concept BareSemiregular = Semiregular<trait::RemoveCvref<T>>;

} // namespace based

diff --git a/ include/based/concept/is_arithmetic.hpp b/ include/based/concept/is_arithmetic.hpp

@@ -0,0 +1,13 @@

#pragma once

#include "based/concept/is_floating_point.hpp"
#include "based/concept/is_integral.hpp"
#include "based/trait/integral_constant.hpp"

namespace based::trait
{

template<class T>
concept IsArithmetic = IsIntegral<T> || IsFloatingPoint<T>;

} // namespace based::trait

diff --git a/ include/based/concept/is_array.hpp b/ include/based/concept/is_array.hpp

@@ -0,0 +1,25 @@

#pragma once

#include "based/integral/types.hpp"
#include "based/trait/integral_constant.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off
// NOLINTBEGIN(*array*)
template<class T> struct IsArray : FalseType {};
template<class T> struct IsArray<T[]> : TrueType {};
template<class T, SizeT n> struct IsArray<T[n]> : TrueType {};
// NOLINTEND(*array*)
// clang-format on

} // namespace detail

template<class T>
concept IsArray = detail::IsArray<T>::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_base_of.hpp b/ include/based/concept/is_base_of.hpp

@@ -0,0 +1,34 @@

#pragma once

#include "based/concept/is_class.hpp"
#include "based/trait/integral_constant.hpp"

namespace based::trait
{

namespace detail
{

template<class B>
auto test_ptr_conv(const volatile B*) -> TrueType;

template<class>
auto test_ptr_conv(const volatile void*) -> FalseType;

template<class B, class D>
auto test_is_base_of(int)
-> decltype(test_ptr_conv<B>(static_cast<D*>(nullptr)));

template<class, class>
auto test_is_base_of(...) -> TrueType; // private or ambiguous base

} // namespace detail

template<class Base, class Derived>
concept IsBaseOf = requires {
requires(IsClass<Base>);
requires(IsClass<Derived>);
requires(decltype(detail::test_is_base_of<Base, Derived>(0))::value);
};

} // namespace based::trait

diff --git a/ include/based/concept/is_castable.hpp b/ include/based/concept/is_castable.hpp

@@ -0,0 +1,11 @@

#pragma once

#include "based/utility/declvar.hpp"

namespace based::trait
{

template<class From, class To>
concept IsCastableTo = requires { static_cast<To>(declval<From>()); };

} // namespace based::trait

diff --git a/ include/based/concept/is_class.hpp b/ include/based/concept/is_class.hpp

@@ -0,0 +1,24 @@

#pragma once

#include "based/concept/is_union.hpp"
#include "based/trait/integral_constant.hpp"

namespace based::trait
{

namespace detail
{

template<class T>
requires(!IsUnion<T>)
auto test(int T::*) -> TrueType;

template<class T>
auto test(...) -> FalseType;

} // namespace detail

template<class T>
concept IsClass = decltype(detail::test<T>(nullptr))::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_const.hpp b/ include/based/concept/is_const.hpp

@@ -0,0 +1,21 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off
template<class T> struct IsConst : FalseType {};
template<class T> struct IsConst<const T> : TrueType {};
// clang-format on

} // namespace detail

template<class T>
concept IsConst = detail::IsConst<T>::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_convertible.hpp b/ include/based/concept/is_convertible.hpp

@@ -0,0 +1,11 @@

#pragma once

#include <type_traits>

namespace based::trait
{

template<class From, class To>
concept IsConvertible = std::is_convertible_v<From, To>;

} // namespace based::trait

diff --git a/ include/based/concept/is_enum.hpp b/ include/based/concept/is_enum.hpp

@@ -0,0 +1,27 @@

#pragma once

#include <type_traits>

namespace based::trait
{

namespace detail
{

void test_conversion(...); // selected when E is complete and scoped
void test_conversion(int) = delete; // selected when E is complete and unscoped

} // namespace detail

template<class T>
concept IsEnum = std::is_enum_v<T>;

template<class T>
concept IsScopedEnum = requires {
requires(IsEnum<T>);
{
detail::test_conversion(T {})
};
};

} // namespace based::trait

diff --git a/ include/based/concept/is_floating_point.hpp b/ include/based/concept/is_floating_point.hpp

@@ -0,0 +1,14 @@

#pragma once

#include "based/concept/is_same.hpp"
#include "based/trait/remove_cv.hpp"

namespace based::trait
{

template<class T>
concept IsFloatingPoint =
IsSame<float, trait::RemoveCv<T>> || IsSame<double, trait::RemoveCv<T>>
|| IsSame<long double, trait::RemoveCv<T>>;

} // namespace based::trait

diff --git a/ include/based/concept/is_function.hpp b/ include/based/concept/is_function.hpp

@@ -0,0 +1,99 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off

template<typename>
struct IsFunction : FalseType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) volatile noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) volatile & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) volatile && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const volatile noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const volatile & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const volatile && noexcept(ne)> : TrueType {};

// NOLINTBEGIN(*ambiguous-ellipsis*)

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) volatile noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) volatile & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) volatile && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const volatile noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const volatile & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const volatile && noexcept(ne)> : TrueType {};

// NOLINTEND(*ambiguous-ellipsis*)

// clang-format on

} // namespace detail

template<class T>
concept IsFunction = detail::IsFunction<T>::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_integral.hpp b/ include/based/concept/is_integral.hpp

@@ -0,0 +1,18 @@

#pragma once

#include "based/concept/is_convertible.hpp"
#include "based/integral/types.hpp"

namespace based::trait
{

template<class T>
concept IsSignedIntegral = IsConvertible<I, T>;

template<class T>
concept IsUnsignedIntegral = IsConvertible<U, T>;

template<class T>
concept IsIntegral = IsSignedIntegral<T> || IsUnsignedIntegral<T>;

} // namespace based::trait

diff --git a/ include/based/concept/is_invocable.hpp b/ include/based/concept/is_invocable.hpp

@@ -0,0 +1,14 @@

#pragma once

#include <type_traits>

namespace based::trait
{

template<typename P, typename... Args>
concept IsInvocable = std::is_invocable_v<P, Args...>;

template<typename P, typename... Args>
concept IsNothrowInvocable = std::is_nothrow_invocable_v<P, Args...>;

} // namespace based::trait

diff --git a/ include/based/concept/is_lvalue_reference.hpp b/ include/based/concept/is_lvalue_reference.hpp

@@ -0,0 +1,21 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off
template<class T> struct IsLvalueReference : FalseType {};
template<class T> struct IsLvalueReference<T&> : TrueType {};
// clang-format on

} // namespace detail

template<class T>
concept IsLvalueReference = detail::IsLvalueReference<T>::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_member_pointer.hpp b/ include/based/concept/is_member_pointer.hpp

@@ -0,0 +1,22 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/remove_cv.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off
template<class T> struct IsMemberPointer : FalseType {};
template<class T, class U> struct IsMemberPointer<T U::*> : TrueType {};
// clang-format on

} // namespace detail

template<class T>
concept IsMemberPointer = detail::IsMemberPointer<RemoveCv<T>>::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_null_pointer.hpp b/ include/based/concept/is_null_pointer.hpp

@@ -0,0 +1,13 @@

#pragma once

#include "based/concept/is_same.hpp"
#include "based/memory/nullptr.hpp"
#include "based/trait/remove_cv.hpp"

namespace based::trait
{

template<class T>
concept IsNullPointer = IsSame<NullptrT, RemoveCv<T>>;

} // namespace based::trait

diff --git a/ include/based/concept/is_object.hpp b/ include/based/concept/is_object.hpp

@@ -0,0 +1,14 @@

#pragma once

#include "based/concept/is_array.hpp"
#include "based/concept/is_class.hpp"
#include "based/concept/is_scalar.hpp"
#include "based/concept/is_union.hpp"

namespace based::trait
{

template<class T>
concept IsObject = IsScalar<T> || IsArray<T> || IsUnion<T> || IsClass<T>;

} // namespace based::trait

diff --git a/ include/based/concept/is_pointer.hpp b/ include/based/concept/is_pointer.hpp

@@ -0,0 +1,24 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off
template<class T> struct IsPointer : FalseType {};
template<class T> struct IsPointer<T*> : TrueType {};
template<class T> struct IsPointer<T* const> : TrueType {};
template<class T> struct IsPointer<T* volatile> : TrueType {};
template<class T> struct IsPointer<T* const volatile> : TrueType {};
// clang-format on

} // namespace detail

template<class T>
concept IsPointer = detail::IsPointer<T>::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_reference_wrapper.hpp b/ include/based/concept/is_reference_wrapper.hpp

@@ -0,0 +1,21 @@

#pragma once

#include "based/functional/reference_wrapper.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off
template<class T> struct IsReferenceWrapper : FalseType {};
template<class U> struct IsReferenceWrapper<ReferenceWrapper<U>> : TrueType {};
// clang-format on

} // namespace detail

template<class T>
concept IsReferenceWrapper = detail::IsReferenceWrapper<T>::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_regular.hpp b/ include/based/concept/is_regular.hpp

@@ -0,0 +1,16 @@

#pragma once

#include <concepts>

#include "based/trait/remove_cvref.hpp"

namespace based::trait
{

template<typename T>
concept Regular = std::regular<T>;

template<typename T>
concept BareRegular = Regular<RemoveCvref<T>>;

} // namespace based::trait

diff --git a/ include/based/concept/is_rvalue_reference.hpp b/ include/based/concept/is_rvalue_reference.hpp

@@ -0,0 +1,21 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off
template<class T> struct IsRvalueReference : FalseType {};
template<class T> struct IsRvalueReference<T&&> : TrueType {};
// clang-format on

} // namespace detail

template<class T>
concept IsRvalueReference = detail::IsRvalueReference<T>::value;

} // namespace based::trait

diff --git a/ include/based/concept/is_same.hpp b/ include/based/concept/is_same.hpp

@@ -0,0 +1,25 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/remove_cvref.hpp"

namespace based::trait
{

namespace detail
{

// clang-format off
template<class T, class U> struct IsSame : FalseType {};
template<class T> struct IsSame<T, T> : TrueType {};
// clang-format on

} // namespace detail

template<class T, class U>
concept IsSame = detail::IsSame<T, U>::value && detail::IsSame<U, T>::value;

template<class T, class U>
concept IsSameBare = IsSame<RemoveCvref<T>, RemoveCvref<U>>;

} // namespace based::trait

diff --git a/ include/based/concept/is_scalar.hpp b/ include/based/concept/is_scalar.hpp

@@ -0,0 +1,16 @@

#pragma once

#include "based/concept/is_arithmetic.hpp"
#include "based/concept/is_enum.hpp"
#include "based/concept/is_member_pointer.hpp"
#include "based/concept/is_null_pointer.hpp"
#include "based/concept/is_pointer.hpp"

namespace based::trait
{

template<class T>
concept IsScalar = IsArithmetic<T> || IsEnum<T> || IsPointer<T>
|| IsMemberPointer<T> || IsNullPointer<T>;

} // namespace based::trait

diff --git a/ include/based/concept/is_semiregular.hpp b/ include/based/concept/is_semiregular.hpp

@@ -0,0 +1,16 @@

#pragma once

#include <concepts>

#include "based/trait/remove_cvref.hpp"

namespace based::trait
{

template<typename T>
concept Semiregular = std::semiregular<T>;

template<typename T>
concept BareSemiregular = Semiregular<RemoveCvref<T>>;

} // namespace based::trait

diff --git a/ include/based/concept/is_union.hpp b/ include/based/concept/is_union.hpp

@@ -0,0 +1,11 @@

#pragma once

#include <type_traits>

namespace based::trait
{

template<class T>
concept IsUnion = std::is_union_v<T>;

} // namespace based::trait

diff --git a/ include/based/concept/is_void.hpp b/ include/based/concept/is_void.hpp

@@ -0,0 +1,12 @@

#pragma once

#include "based/concept/is_same.hpp"
#include "based/trait/remove_cv.hpp"

namespace based::trait
{

template<class T>
concept IsVoid = IsSame<void, trait::RemoveCv<T>>;

} // namespace based::trait

diff --git a/ include/based/concept/iterator.hpp b/ include/based/concept/iterator.hpp

@@ -1,7 +1,7 @@

#pragma once

#include "based/concept/is/regular.hpp"
#include "based/concept/is/same.hpp"
#include "based/concept/is_regular.hpp"
#include "based/concept/is_same.hpp"
#include "based/trait/iterator.hpp"

namespace based

@@ -11,20 +11,20 @@ namespace based


template<typename T>
concept Readable = requires(T val) {
requires(Regular<T>);
requires(trait::Regular<T>);
typename iter_value_t<T>;
{
*val
} -> BareSameAs<iter_value_t<T>>;
} -> trait::IsSameBare<iter_value_t<T>>;
};

template<typename T>
concept Iterator = requires(T val) {
requires(Regular<T>);
requires(trait::Regular<T>);
typename iter_dist_t<T>;
{
++val
} -> BareSameAs<T>;
} -> trait::IsSameBare<T>;
// successor is not necessarily regular
};

diff --git a/ include/based/concept/procedure/domain.hpp b/ include/based/concept/procedure/domain.hpp

@@ -2,12 +2,12 @@


#include <tuple>

#include "based/concept/is/regular.hpp"
#include "based/concept/is/same.hpp"
#include "based/concept/is/semiregular.hpp"
#include "based/concept/is_const.hpp"
#include "based/concept/is_regular.hpp"
#include "based/concept/is_same.hpp"
#include "based/concept/is_semiregular.hpp"
#include "based/integral/types.hpp"
#include "based/trait/invoke_result.hpp"
#include "based/trait/is/const.hpp"
#include "based/trait/remove_cvref.hpp"
#include "based/trait/remove_pointer.hpp"
#include "based/trait/remove_reference.hpp"

@@ -16,24 +16,26 @@ namespace based

{

template<typename T>
concept Input = SameAs<T, trait::RemoveCvref<trait::RemovePointer<T>>>
|| is_const_v<trait::RemoveReference<T>> || is_const_v<trait::RemovePointer<T>>;
concept Input = trait::IsSame<T, trait::RemoveCvref<trait::RemovePointer<T>>>
|| trait::IsConst<trait::RemoveReference<T>>
|| trait::IsConst<trait::RemovePointer<T>>;

template<SizeT idx, typename... Args>
requires(idx < sizeof...(Args))
using ElemT = std::tuple_element_t<idx, std::tuple<Args...>>;

template<typename... Args>
concept SemiregularDomain = (Semiregular<trait::RemoveCvref<Args>> && ...);
concept SemiregularDomain =
(trait::Semiregular<trait::RemoveCvref<Args>> && ...);

template<typename... Args>
concept RegularDomain = (Regular<trait::RemoveCvref<Args>> && ...);
concept RegularDomain = (trait::Regular<trait::RemoveCvref<Args>> && ...);

template<typename... Args>
concept InputDomain = (Input<Args> && ...);

template<typename... Args>
concept HomogeneousDomain = (SameAs<ElemT<0, Args...>, Args> && ...);
concept HomogeneousDomain = (trait::IsSame<ElemT<0, Args...>, Args> && ...);

template<typename P, typename... Args>
using RetT = InvokeResultT<P, Args...>;

diff --git a/ include/based/concept/procedure/procedure.hpp b/ include/based/concept/procedure/procedure.hpp

@@ -1,8 +1,8 @@

#pragma once

#include "based/concept/is/convertable.hpp"
#include "based/concept/is/invocable.hpp"
#include "based/concept/is/regular.hpp"
#include "based/concept/is_convertible.hpp"
#include "based/concept/is_invocable.hpp"
#include "based/concept/is_regular.hpp"
#include "based/concept/procedure/domain.hpp"
#include "based/trait/integral_constant.hpp"
#include "based/trait/invoke_result.hpp"

@@ -18,11 +18,11 @@ namespace detail

template<typename P, typename Sig> struct Procedure : public FalseType {};

template<typename P, typename Ret, typename... Args>
requires (Invocable<P, Args...> && ConvertibleTo<InvokeResultT<P, Args...>, Ret>)
requires (trait::IsInvocable<P, Args...> && trait::IsConvertible<InvokeResultT<P, Args...>, Ret>)
struct Procedure<P, Ret(Args...)> : public TrueType {};

template<typename P, typename... Args>
requires (Invocable<P, Args...>)
requires (trait::IsInvocable<P, Args...>)
struct Procedure<P, void(Args...)> : public TrueType {};

template<typename P, typename Ret, typename... Args>

@@ -42,7 +42,7 @@ template<typename P, typename Ret, typename... Args>

concept RegularProcedure = requires {
requires(Procedure<P, Ret, Args...>);
requires(RegularDomain<Args...>);
requires(Regular<RetT<P, Args...>>);
requires(trait::Regular<RetT<P, Args...>>);
};

} // namespace based

diff --git a/ include/based/concept/procedure/procedure_iter.hpp b/ include/based/concept/procedure/procedure_iter.hpp

@@ -19,9 +19,9 @@ concept IterUnaryProcedure = requires {

};

template<typename P, typename Ret, typename I>
concept IterRegularProcedure = requires {
concept Itertrait::RegularProcedure = requires {
requires(Iterator<I>);
requires(RegularProcedure<P, Ret, iter_value_t<I>>);
requires(trait::RegularProcedure<P, Ret, iter_value_t<I>>);
};

} // namespace based

diff --git a/ include/based/container/list.hpp b/ include/based/container/list.hpp

@@ -3,7 +3,7 @@

#include <cassert>
#include <vector>

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/integral/types.hpp"

namespace based

diff --git a/ include/based/enum/enum.hpp b/ include/based/enum/enum.hpp

@@ -1,8 +1,8 @@

#pragma once

#include "based/algorithm/clamp.hpp"
#include "based/concept/is/enum.hpp"
#include "based/concept/is/same.hpp"
#include "based/concept/is_enum.hpp"
#include "based/concept/is_same.hpp"

namespace based::enumeration
{

@@ -107,14 +107,14 @@ namespace enum_traits

* Enumeration traits class template
*
* Requires:
* - IsScopedEnum<T>
* - trait::IsScopedEnum<T>
*
* Contains:
* - category_type: The Enumeration category used for this type
* - value_type: The underlying type for this type
*/
template<class T>
requires IsScopedEnum<T>
requires trait::IsScopedEnum<T>
// TODO: check for proper int type
struct Traits
{

@@ -172,7 +172,7 @@ static constexpr Enum max = Enum::max;

template<class Enum, class Category>
concept IsCategory = requires {
requires(HasCategory<Enum>);
requires(SameAs<Category, CategoryType<Enum>>);
requires(trait::IsSame<Category, CategoryType<Enum>>);
};

template<class Enum>

@@ -384,7 +384,7 @@ struct Traits<category::Discrete<Enum, vals...>>

using Category = category::Discrete<Enum, vals...>;

template<enum_traits::IsCategory<Category> EnumI>
requires SameAs<Enum, EnumI>
requires trait::IsSame<Enum, EnumI>
static constexpr bool valid() noexcept
{
if constexpr (enum_traits::HasNone<Enum>) {

@@ -395,7 +395,7 @@ struct Traits<category::Discrete<Enum, vals...>>

}

template<enum_traits::IsCategory<Category> EnumI>
requires SameAs<Enum, EnumI>
requires trait::IsSame<Enum, EnumI>
static constexpr Enum enum_cast(enum_traits::value_type<Enum> value) noexcept
{
if ((... || (detail::value_cast_impl(vals) == value))) {

diff --git a/ include/based/functional/function.hpp b/ include/based/functional/function.hpp

@@ -2,7 +2,7 @@


#include <functional>

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/integral/types.hpp"
#include "based/trait/decay.hpp"
#include "based/trait/signature.hpp"

@@ -49,7 +49,7 @@ public:


template<typename CallableArg, typename Callable = trait::Decay<CallableArg>>
requires(requires {
!SameAs<Function, Callable>;
!trait::IsSame<Function, Callable>;
sizeof(Callable) <= size;
alignof(Callable) <= alignment;
std::is_trivially_destructible_v<Callable>;

diff --git a/ include/based/functional/invoke.hpp b/ include/based/functional/invoke.hpp

@@ -1,10 +1,10 @@

#pragma once

#include "based/trait/is/base_of.hpp"
#include "based/trait/is/function.hpp"
#include "based/trait/is/invocable.hpp"
#include "based/trait/is/object.hpp"
#include "based/trait/is/reference_wrapper.hpp"
#include "based/concept/is_base_of.hpp"
#include "based/concept/is_function.hpp"
#include "based/concept/is_invocable.hpp"
#include "based/concept/is_object.hpp"
#include "based/concept/is_reference_wrapper.hpp"
#include "based/utility/forward.hpp"

namespace based

@@ -18,10 +18,10 @@ constexpr decltype(auto) invoke_memptr(

)
{
using ObjectT = trait::RemoveCvref<Object>;
constexpr bool is_member_function = is_function_v<Pointed>;
constexpr bool is_wrapped = false = is_reference_wrapper_v<ObjectT>;
constexpr bool is_member_function = trait::IsFunction<Pointed>;
constexpr bool is_wrapped = false = trait::IsReferenceWrapper<ObjectT>;
constexpr bool is_derived_object = false =
is_same_v<C, ObjectT> || is_base_of_v<C, ObjectT>;
is_same_v<C, ObjectT> || trait::IsBaseOf<C, ObjectT>;

if constexpr (is_member_function) {
if constexpr (is_derived_object) {

diff --git a/ include/based/functional/reference_wrapper.hpp b/ include/based/functional/reference_wrapper.hpp

@@ -1,8 +1,8 @@

#pragma once

#include "based/concept/is_invocable.hpp"
#include "based/concept/is_same.hpp"
#include "based/memory/addressof.hpp"
#include "based/trait/is/invocable.hpp"
#include "based/trait/is/same.hpp"
#include "based/trait/remove_cvref.hpp"
#include "based/utility/declvar.hpp"
#include "based/utility/forward.hpp"

@@ -32,7 +32,7 @@ public:

template<class U>
requires(requires {
detail::fun<T>(declval<U>());
requires(!is_same_v<ReferenceWrapper, trait::RemoveCvref<U>>);
requires(!trait::IsSame<ReferenceWrapper, trait::RemoveCvref<U>>);
})

// NOLINTNEXTLINE(*explicit*)

@@ -57,7 +57,7 @@ public:


template<class... Args>
constexpr decltype(auto) operator()(Args&&... args) const
noexcept(is_nothrow_invocable_v<T&, Args...>)
noexcept(trait::IsNothrowInvocable<T&, Args...>)
{
return get(based::forward<Args>(args)...);
}

diff --git a/ include/based/instrumentation/instrumented.hpp b/ include/based/instrumentation/instrumented.hpp

@@ -81,7 +81,7 @@ struct instrumented : instrumented_base

;
}

// Semiregular:
// trait::Semiregular:
instrumented()
{
++counts[op::ctor_default];

@@ -127,7 +127,7 @@ struct instrumented : instrumented_base

;
}

// Regular
// trait::Regular

friend bool operator==(const instrumented& lhs, const instrumented& rhs)
{

diff --git a/ include/based/integral/strong.hpp b/ include/based/integral/strong.hpp

@@ -1,9 +1,6 @@

#pragma once

#include <compare>

#include "based/concept/is/same.hpp"
#include "based/trait/is/class.hpp"
#include "based/concept/is_same.hpp"

namespace based
{

@@ -91,7 +88,7 @@ constexpr auto operator+(LHS lhs, RHS rhs)

template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires Addable<LHS, RHS>;
requires SameAs<LHS, decltype(add(lhs, rhs))>;
requires trait::IsSame<LHS, decltype(add(lhs, rhs))>;
})
constexpr auto& operator+=(LHS& lhs, RHS rhs)
{

@@ -111,7 +108,7 @@ 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))>;
requires trait::IsSame<LHS, decltype(sub(lhs, rhs))>;
})
constexpr auto& operator-=(LHS& lhs, RHS rhs)
{

@@ -131,7 +128,7 @@ 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))>;
requires trait::IsSame<LHS, decltype(mul(lhs, rhs))>;
})
constexpr auto& operator*=(LHS& lhs, RHS rhs)
{

@@ -151,7 +148,7 @@ 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))>;
requires trait::IsSame<LHS, decltype(div(lhs, rhs))>;
})
constexpr auto& operator/=(LHS& lhs, RHS rhs)
{

@@ -171,7 +168,7 @@ 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))>;
requires trait::IsSame<LHS, decltype(mod(lhs, rhs))>;
})
constexpr auto& operator%=(LHS& lhs, RHS rhs)
{

@@ -191,7 +188,7 @@ constexpr auto operator<<(LHS lhs, RHS rhs)

template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires Lshiftable<LHS, RHS>;
requires SameAs<LHS, decltype(lshift(lhs, rhs))>;
requires trait::IsSame<LHS, decltype(lshift(lhs, rhs))>;
})
constexpr auto& operator<<=(LHS& lhs, RHS rhs)
{

@@ -211,7 +208,7 @@ constexpr auto operator>>(LHS lhs, RHS rhs)

template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires Rshiftable<LHS, RHS>;
requires SameAs<LHS, decltype(rshift(lhs, rhs))>;
requires trait::IsSame<LHS, decltype(rshift(lhs, rhs))>;
})
constexpr auto& operator>>=(LHS& lhs, RHS rhs)
{

@@ -231,7 +228,7 @@ 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))>;
requires trait::IsSame<LHS, decltype(land(lhs, rhs))>;
})
constexpr auto& operator&=(LHS& lhs, RHS rhs)
{

@@ -251,7 +248,7 @@ 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))>;
requires trait::IsSame<LHS, decltype(lor(lhs, rhs))>;
})
constexpr auto& operator|=(LHS& lhs, RHS rhs)
{

@@ -271,7 +268,7 @@ constexpr auto operator^(LHS lhs, RHS rhs)

template<class LHS, class RHS>
requires(requires(LHS lhs, RHS rhs) {
requires Xorable<LHS, RHS>;
requires SameAs<LHS, decltype(lxor(lhs, rhs))>;
requires trait::IsSame<LHS, decltype(lxor(lhs, rhs))>;
})
constexpr auto& operator^=(LHS& lhs, RHS rhs)
{

diff --git a/ include/based/memory/addressof.hpp b/ include/based/memory/addressof.hpp

@@ -1,6 +1,6 @@

#pragma once

#include "based/trait/is/object.hpp"
#include "based/concept/is_object.hpp"

namespace based
{

@@ -12,7 +12,7 @@ T* addressof(T& arg) noexcept

}

template<class T>
requires is_object_v<T>
requires trait::IsObject<T>
T* addressof(T& arg) noexcept
{
// NOLINTBEGIN(*reinterpret*,*const*)

diff --git a/ include/based/trait/decay.hpp b/ include/based/trait/decay.hpp

@@ -1,8 +1,8 @@

#pragma once

#include "based/concept/is_array.hpp"
#include "based/concept/is_function.hpp"
#include "based/trait/add_pointer.hpp"
#include "based/trait/is/array.hpp"
#include "based/trait/is/function.hpp"
#include "based/trait/remove_cv.hpp"
#include "based/trait/remove_extent.hpp"
#include "based/trait/remove_reference.hpp"

@@ -20,14 +20,14 @@ struct Decay

};

template<class U>
requires is_array_v<U>
requires trait::IsArray<U>
struct Decay<U>
{
using Type = trait::AddPointer<trait::RemoveExtent<U>>;
};

template<class U>
requires is_function_v<U>
requires trait::IsFunction<U>
struct Decay<U>
{
using Type = trait::AddPointer<U>;

diff --git a/ include/based/trait/invoke_result.hpp b/ include/based/trait/invoke_result.hpp

@@ -1,8 +1,8 @@

#pragma once

#include "based/concept/is_base_of.hpp"
#include "based/concept/is_reference_wrapper.hpp"
#include "based/trait/decay.hpp"
#include "based/trait/is/base_of.hpp"
#include "based/trait/is/reference_wrapper.hpp"
#include "based/utility/forward.hpp"

namespace based

@@ -23,19 +23,19 @@ template<class B, class MT>

struct InvokeImpl<MT B::*>
{
template<class T>
requires(is_base_of_v<B, trait::Decay<T>>)
requires(trait::IsBaseOf<B, trait::Decay<T>>)
static auto get(T&& obj) -> T&&;

template<class T>
requires(is_reference_wrapper_v<trait::Decay<T>>)
requires(trait::IsReferenceWrapper<trait::Decay<T>>)
static auto get(T&& obj) -> decltype(obj.get());

template<class T>
requires(!is_base_of_v<B, trait::Decay<T>> && !is_reference_wrapper_v<trait::Decay<T>>)
requires(!trait::IsBaseOf<B, trait::Decay<T>> && !trait::IsReferenceWrapper<trait::Decay<T>>)
static auto get(T&& obj) -> decltype(*based::forward<T>(obj));

template<class T, class... Args, class MT1>
requires(is_function_v<MT1>)
requires(trait::IsFunction<MT1>)
static auto call(MT1 B::* pmf, T&& obj, Args&&... args)
-> decltype((InvokeImpl::get(based::forward<T>(obj)).*pmf)(
based::forward<Args>(args)...

@@ -47,9 +47,10 @@ struct InvokeImpl<MT B::*>

};

template<class F, class... Args>
auto invoke_f(F&& func, Args&&... args) -> decltype(InvokeImpl<trait::Decay<F>>::call(
based::forward<F>(func), based::forward<Args>(args)...
));
auto invoke_f(F&& func, Args&&... args)
-> decltype(InvokeImpl<trait::Decay<F>>::call(
based::forward<F>(func), based::forward<Args>(args)...
));

} // namespace detail

diff --git a/ include/based/trait/is/arithmetic.hpp b/ include/based/trait/is/arithmetic.hpp

@@ -1,18 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/is/floating_point.hpp"
#include "based/trait/is/integral.hpp"

namespace based
{

template<class T>
struct IsArithmetic : BoolConstant<is_integral_v<T> || is_floating_point_v<T>>
{
};

template<class T>
constexpr bool is_arithmetic_v = IsArithmetic<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/array.hpp b/ include/based/trait/is/array.hpp

@@ -1,29 +0,0 @@

#pragma once

#include "based/integral/types.hpp"
#include "based/trait/integral_constant.hpp"

namespace based
{

// NOLINTBEGIN(*array*)
template<class T>
struct IsArray : FalseType
{
};

template<class T>
struct IsArray<T[]> : TrueType
{
};

template<class T, SizeT n>
struct IsArray<T[n]> : TrueType
{
};
// NOLINTEND(*array*)

template<class T>
constexpr bool is_array_v = IsArray<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/base_of.hpp b/ include/based/trait/is/base_of.hpp

@@ -1,44 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/is/class.hpp"

namespace based
{

namespace details
{

template<class B>
TrueType test_ptr_conv(const volatile B*);

template<class>
FalseType test_ptr_conv(const volatile void*);

template<class B, class D>
auto test_is_base_of(int)
-> decltype(test_ptr_conv<B>(static_cast<D*>(nullptr)));

template<class, class>
auto test_is_base_of(...) -> TrueType; // private or ambiguous base

} // namespace details

template<class Base, class Derived>
struct IsBaseOf : FalseType
{
};

template<class Base, class Derived>
requires(
is_class_v<Base> && is_class_v<Derived>
&& decltype(details::test_is_base_of<Base, Derived>(0))::value
)
struct IsBaseOf<Base, Derived> : TrueType
{
};

template<class Base, class Derived>
constexpr bool is_base_of_v = IsBaseOf<Base, Derived>::value;

} // namespace based

diff --git a/ include/based/trait/is/class.hpp b/ include/based/trait/is/class.hpp

@@ -1,28 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/is/union.hpp"

namespace based
{

namespace detail
{

template<class T>
BoolConstant<!is_union_v<T>> test(int T::*);

template<class T>
FalseType test(...);

} // namespace detail

template<class T>
struct IsClass : decltype(detail::test<T>(nullptr))
{
};

template<class T>
constexpr bool is_class_v = IsClass<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/const.hpp b/ include/based/trait/is/const.hpp

@@ -1,21 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based
{

template<class T>
struct IsConst : FalseType
{
};

template<class T>
struct IsConst<const T> : TrueType
{
};

template<class T>
constexpr bool is_const_v = IsConst<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/convertable.hpp b/ include/based/trait/is/convertable.hpp

@@ -1,14 +0,0 @@

#pragma once

#include <type_traits>

namespace based
{

template<class From, class To>
using IsConvertible = std::is_convertible<From, To>;

template<class From, class To>
constexpr bool is_convertible_v = std::is_convertible_v<From, To>;

} // namespace based

diff --git a/ include/based/trait/is/enum.hpp b/ include/based/trait/is/enum.hpp

@@ -1,14 +0,0 @@

#pragma once

#include <type_traits>

namespace based
{

template<class T>
using is_enum = std::is_enum<T>; // NOLINT(*identifier*)

template<class T>
constexpr bool is_enum_v = std::is_enum_v<T>;

} // namespace based

diff --git a/ include/based/trait/is/floating_point.hpp b/ include/based/trait/is/floating_point.hpp

@@ -1,24 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/is/same.hpp"
#include "based/trait/remove_cv.hpp"

namespace based
{

template<class T>
struct IsFloatingPoint : FalseType
{
};

template<class T>
requires(is_same_v<float, trait::RemoveCv<T>> || is_same_v<double, trait::RemoveCv<T>> || is_same_v<long double, trait::RemoveCv<T>>)
struct IsFloatingPoint<T> : TrueType
{
};

template<class T>
constexpr bool is_floating_point_v = IsFloatingPoint<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/function.hpp b/ include/based/trait/is/function.hpp

@@ -1,93 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based
{

// clang-format off

template<typename>
struct IsFunction : FalseType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) volatile noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) volatile & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) volatile && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const volatile noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const volatile & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args...) const volatile && noexcept(ne)> : TrueType {};

// NOLINTBEGIN(*ambiguous-ellipsis*)

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) volatile noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) volatile & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) volatile && noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const volatile noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const volatile & noexcept(ne)> : TrueType {};

template<typename Ret, bool ne, typename... Args>
struct IsFunction<Ret(Args......) const volatile && noexcept(ne)> : TrueType {};

// NOLINTEND(*ambiguous-ellipsis*)

template<class T> constexpr bool is_function_v = IsFunction<T>::value;

// clang-format on

} // namespace based

diff --git a/ include/based/trait/is/integral.hpp b/ include/based/trait/is/integral.hpp

@@ -1,31 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based
{

template<class T>
struct IsIntegral : FalseType
{
};

template<class T>
requires(
requires(
T obj, T* ptr, void (*func)(T)
) // T* parameter excludes reference types
{
reinterpret_cast<T>(obj); // NOLINT(*reinterpret*, *redundant*)
func(0); // Exclude enumeration types
ptr + obj; // Exclude everything not yet excluded but integral types
}
)
struct IsIntegral<T> : TrueType
{
};

template<class T>
constexpr bool is_integral_v = IsIntegral<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/invocable.hpp b/ include/based/trait/is/invocable.hpp

@@ -1,20 +0,0 @@

#pragma once

#include <type_traits>

namespace based
{

template<class F, class... Args>
using IsInvocable = std::is_invocable<F, Args...>;

template<class F, class... Args>
constexpr bool is_invocable_v = std::is_invocable_v<F, Args...>;

template<class F, class... Args>
using IsNothrowInvocable = std::is_nothrow_invocable<F, Args...>;

template<class F, class... Args>
constexpr bool is_nothrow_invocable_v = std::is_nothrow_invocable_v<F, Args...>;

} // namespace based

diff --git a/ include/based/trait/is/lvalue_reference.hpp b/ include/based/trait/is/lvalue_reference.hpp

@@ -1,21 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based
{

template<class T>
struct IsLvalueReference : FalseType
{
};

template<class T>
struct IsLvalueReference<T&> : TrueType
{
};

template<class T>
constexpr bool is_lvalue_reference_v = IsLvalueReference<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/member_pointer.hpp b/ include/based/trait/is/member_pointer.hpp

@@ -1,32 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/remove_cv.hpp"

namespace based
{

namespace detail
{

template<class T>
struct IsMemberPointerHelper : FalseType
{
};

template<class T, class U>
struct IsMemberPointerHelper<T U::*> : TrueType
{
};

} // namespace detail

template<class T>
struct IsMemberPointer : detail::IsMemberPointerHelper<trait::RemoveCv<T>>
{
};

template<class T>
constexpr bool is_member_pointer_v = IsMemberPointer<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/null_pointer.hpp b/ include/based/trait/is/null_pointer.hpp

@@ -1,18 +0,0 @@

#pragma once

#include "based/memory/nullptr.hpp"
#include "based/trait/is/same.hpp"
#include "based/trait/remove_cv.hpp"

namespace based
{

template<class T>
struct IsNullPointer : IsSame<NullptrT, trait::RemoveCv<T>>
{
};

template<class T>
constexpr bool is_null_pointer_v = IsNullPointer<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/object.hpp b/ include/based/trait/is/object.hpp

@@ -1,26 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/is/array.hpp"
#include "based/trait/is/class.hpp"
#include "based/trait/is/scalar.hpp"
#include "based/trait/is/union.hpp"

namespace based
{

template<class T>
struct IsObject : FalseType
{
};

template<class T>
requires(is_scalar_v<T> || is_array_v<T> || is_union_v<T> || is_class_v<T>)
struct IsObject<T> : TrueType
{
};

template<class T>
constexpr bool is_object_v = IsObject<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/pointer.hpp b/ include/based/trait/is/pointer.hpp

@@ -1,36 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based
{

template<class T>
struct IsPointer : FalseType
{
};

template<class T>
struct IsPointer<T*> : TrueType
{
};

template<class T>
struct IsPointer<T* const> : TrueType
{
};

template<class T>
struct IsPointer<T* volatile> : TrueType
{
};

template<class T>
struct IsPointer<T* const volatile> : TrueType
{
};

template<class T>
constexpr bool is_pointer_v = IsPointer<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/reference_wrapper.hpp b/ include/based/trait/is/reference_wrapper.hpp

@@ -1,21 +0,0 @@

#pragma once

#include "based/functional/reference_wrapper.hpp"

namespace based
{

template<class T>
struct IsReferenceWrapper : FalseType
{
};

template<class U>
struct IsReferenceWrapper<ReferenceWrapper<U>> : TrueType
{
};

template<class T>
constexpr bool is_reference_wrapper_v = IsReferenceWrapper<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/rvalue_reference.hpp b/ include/based/trait/is/rvalue_reference.hpp

@@ -1,21 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based
{

template<class T>
struct IsRvalueReference : FalseType
{
};

template<class T>
struct IsRvalueReference<T&&> : TrueType
{
};

template<class T>
constexpr bool is_rvalue_reference_v = IsRvalueReference<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/same.hpp b/ include/based/trait/is/same.hpp

@@ -1,21 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"

namespace based
{

template<class T, class U>
struct IsSame : FalseType
{
};

template<class T>
struct IsSame<T, T> : TrueType
{
};

template<class T, class U>
constexpr bool is_same_v = IsSame<T, U>::value;

} // namespace based

diff --git a/ include/based/trait/is/scalar.hpp b/ include/based/trait/is/scalar.hpp

@@ -1,27 +0,0 @@

#pragma once

#include "based/trait/integral_constant.hpp"
#include "based/trait/is/arithmetic.hpp"
#include "based/trait/is/enum.hpp"
#include "based/trait/is/member_pointer.hpp"
#include "based/trait/is/null_pointer.hpp"
#include "based/trait/is/pointer.hpp"

namespace based
{

template<class T>
struct IsScalar : FalseType
{
};

template<class T>
requires(is_arithmetic_v<T> || is_enum_v<T> || is_pointer_v<T> || is_member_pointer_v<T> || is_null_pointer_v<T>)
struct IsScalar<T>
{
};

template<class T>
constexpr bool is_scalar_v = IsScalar<T>::value;

} // namespace based

diff --git a/ include/based/trait/is/union.hpp b/ include/based/trait/is/union.hpp

@@ -1,14 +0,0 @@

#pragma once

#include <type_traits>

namespace based
{

template<class T>
using IsUnion = std::is_union<T>;

template<class T>
constexpr bool is_union_v = std::is_union_v<T>;

} // namespace based

diff --git a/ include/based/trait/is/void.hpp b/ include/based/trait/is/void.hpp

@@ -1,17 +0,0 @@

#pragma once

#include "based/trait/is/same.hpp"
#include "based/trait/remove_cv.hpp"

namespace based
{

template<class T>
struct IsVoid : IsSame<void, trait::RemoveCv<T>>
{
};

template<class T>
constexpr bool is_void_v = IsVoid<T>::value;

} // namespace based

diff --git a/ include/based/utility/forward.hpp b/ include/based/utility/forward.hpp

@@ -1,6 +1,6 @@

#pragma once

#include "based/trait/is/lvalue_reference.hpp"
#include "based/concept/is_lvalue_reference.hpp"
#include "based/trait/remove_reference.hpp"

namespace based

@@ -16,7 +16,7 @@ template<class T>

// NOLINTNEXTLINE(*move*)
constexpr decltype(auto) forward(trait::RemoveReference<T>&& tmp) noexcept
{
static_assert(!is_lvalue_reference_v<T>);
static_assert(!trait::IsLvalueReference<T>);
return static_cast<T&&>(tmp);
}

diff --git a/ test/source/algorithm/max_test.cpp b/ test/source/algorithm/max_test.cpp

@@ -4,7 +4,7 @@


#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/utility/move.hpp"

// NOLINTBEGIN(*const-arg*,*const-correctness*,*after-move, *access-moved)

@@ -13,7 +13,7 @@ TEST_CASE("max(literal, literal) = right", "[algorithm/max]")

{
using ResT = decltype(based::max(3, 4));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::max(3, 4) == 4);
}

@@ -21,7 +21,7 @@ TEST_CASE("max(literal, literal) = left", "[algorithm/max]")

{
using ResT = decltype(based::max(4, 3));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::max(4, 3) == 4);
}

@@ -31,7 +31,7 @@ TEST_CASE("max(value, literal) = right", "[algorithm/max]")


using ResT = decltype(based::max(a, 4));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(a, 4) == 4);
}

@@ -41,7 +41,7 @@ TEST_CASE("max(value, literal) = left", "[algorithm/max]")


using ResT = decltype(based::max(a, 3));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(a, 3) == 4);
}

@@ -51,7 +51,7 @@ TEST_CASE("max(literal, value) = right", "[algorithm/max]")


using ResT = decltype(based::max(3, b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(3, b) == 4);
}

@@ -61,7 +61,7 @@ TEST_CASE("max(literal, value) = left", "[algorithm/max]")


using ResT = decltype(based::max(4, b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(4, b) == 4);
}

@@ -72,7 +72,7 @@ TEST_CASE("max(value, value) = right", "[algorithm/max]")


using ResT = decltype(based::max(a, b));

STATIC_REQUIRE(based::SameAs<int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&, ResT>);
REQUIRE(based::max(a, b) == 4);
}

@@ -83,7 +83,7 @@ TEST_CASE("max(value, value) = left", "[algorithm/max]")


using ResT = decltype(based::max(a, b));

STATIC_REQUIRE(based::SameAs<int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&, ResT>);
REQUIRE(based::max(a, b) == 4);
}

@@ -93,7 +93,7 @@ TEST_CASE("max(const value, literal) = right", "[algorithm/max]")


using ResT = decltype(based::max(a, 4));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(a, 4) == 4);
}

@@ -103,7 +103,7 @@ TEST_CASE("max(const value, literal) = left", "[algorithm/max]")


using ResT = decltype(based::max(a, 3));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(a, 3) == 4);
}

@@ -113,7 +113,7 @@ TEST_CASE("max(literal, const value) = right", "[algorithm/max]")


using ResT = decltype(based::max(3, b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(3, b) == 4);
}

@@ -123,7 +123,7 @@ TEST_CASE("max(literal, const value) = left", "[algorithm/max]")


using ResT = decltype(based::max(4, b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(4, b) == 4);
}

@@ -134,7 +134,7 @@ TEST_CASE("max(const value, const value) = right", "[algorithm/max]")


using ResT = decltype(based::max(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::max(a, b) == 4);
}

@@ -145,7 +145,7 @@ TEST_CASE("max(const value, const value) = left", "[algorithm/max]")


using ResT = decltype(based::max(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::max(a, b) == 4);
}

@@ -156,7 +156,7 @@ TEST_CASE("max(value, const value) = right", "[algorithm/max]")


using ResT = decltype(based::max(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::max(a, b) == 4);
}

@@ -167,7 +167,7 @@ TEST_CASE("max(value, const value) = left", "[algorithm/max]")


using ResT = decltype(based::max(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::max(a, b) == 4);
}

@@ -178,7 +178,7 @@ TEST_CASE("max(const value, value) = right", "[algorithm/max]")


using ResT = decltype(based::max(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::max(a, b) == 4);
}

@@ -189,7 +189,7 @@ TEST_CASE("max(const value, value) = left", "[algorithm/max]")


using ResT = decltype(based::max(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::max(a, b) == 4);
}

@@ -199,7 +199,7 @@ TEST_CASE("max(move, literal) = right", "[algorithm/max]")


using ResT = decltype(based::max(based::move(a), 4));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::max(based::move(a), 4) == 4);
}

@@ -209,7 +209,7 @@ TEST_CASE("max(move, literal) = left", "[algorithm/max]")


using ResT = decltype(based::max(based::move(a), 3));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::max(based::move(a), 3) == 4);
}

@@ -220,7 +220,7 @@ TEST_CASE("max(move, value) = right", "[algorithm/max]")


using ResT = decltype(based::max(based::move(a), b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(based::move(a), b) == 4);
}

@@ -231,7 +231,7 @@ TEST_CASE("max(move, value) = left", "[algorithm/max]")


using ResT = decltype(based::max(based::move(a), b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(based::move(a), b) == 4);
}

@@ -242,7 +242,7 @@ TEST_CASE("max(move, const value) = right", "[algorithm/max]")


using ResT = decltype(based::max(based::move(a), b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(based::move(a), b) == 4);
}

@@ -253,7 +253,7 @@ TEST_CASE("max(move, const value) = left", "[algorithm/max]")


using ResT = decltype(based::max(based::move(a), b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(based::move(a), b) == 4);
}

@@ -263,7 +263,7 @@ TEST_CASE("max(literal, move) = right", "[algorithm/max]")


using ResT = decltype(based::max(3, based::move(b)));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::max(3, based::move(b)) == 4);
}

@@ -273,7 +273,7 @@ TEST_CASE("max(literal, move) = left", "[algorithm/max]")


using ResT = decltype(based::max(4, based::move(b)));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::max(4, based::move(b)) == 4);
}

@@ -284,7 +284,7 @@ TEST_CASE("max(value, move) = right", "[algorithm/max]")


using ResT = decltype(based::max(a, based::move(b)));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(a, based::move(b)) == 4);
}

@@ -295,7 +295,7 @@ TEST_CASE("max(value, move) = left", "[algorithm/max]")


using ResT = decltype(based::max(a, based::move(b)));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(a, based::move(b)) == 4);
}

@@ -306,7 +306,7 @@ TEST_CASE("max(const value, move) = right", "[algorithm/max]")


using ResT = decltype(based::max(a, based::move(b)));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(a, based::move(b)) == 4);
}

@@ -317,7 +317,7 @@ TEST_CASE("max(const value, move) = left", "[algorithm/max]")


using ResT = decltype(based::max(a, based::move(b)));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::max(a, based::move(b)) == 4);
}

@@ -328,7 +328,7 @@ TEST_CASE("max(move, move) = right", "[algorithm/max]")


using ResT = decltype(based::max(based::move(a), based::move(b)));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::max(based::move(a), based::move(b)) == 4);
}

@@ -339,7 +339,7 @@ TEST_CASE("max(move, move) = left", "[algorithm/max]")


using ResT = decltype(based::max(based::move(a), based::move(b)));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::max(based::move(a), based::move(b)) == 4);
}

diff --git a/ test/source/algorithm/min_test.cpp b/ test/source/algorithm/min_test.cpp

@@ -12,7 +12,7 @@ TEST_CASE("min(literal, literal) = left", "[algorithm/min]")

{
using ResT = decltype(based::min(3, 4));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::min(3, 4) == 3);
}

@@ -20,7 +20,7 @@ TEST_CASE("min(literal, literal) = right", "[algorithm/min]")

{
using ResT = decltype(based::min(4, 3));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::min(4, 3) == 3);
}

@@ -30,7 +30,7 @@ TEST_CASE("min(value, literal) = left", "[algorithm/min]")


using ResT = decltype(based::min(a, 4));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(a, 4) == 3);
}

@@ -40,7 +40,7 @@ TEST_CASE("min(value, literal) = right", "[algorithm/min]")


using ResT = decltype(based::min(a, 3));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(a, 3) == 3);
}

@@ -50,7 +50,7 @@ TEST_CASE("min(literal, value) = left", "[algorithm/min]")


using ResT = decltype(based::min(3, b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(3, b) == 3);
}

@@ -60,7 +60,7 @@ TEST_CASE("min(literal, value) = right", "[algorithm/min]")


using ResT = decltype(based::min(4, b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(4, b) == 3);
}

@@ -71,7 +71,7 @@ TEST_CASE("min(value, value) = left", "[algorithm/min]")


using ResT = decltype(based::min(a, b));

STATIC_REQUIRE(based::SameAs<int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&, ResT>);
REQUIRE(based::min(a, b) == 3);
}

@@ -82,7 +82,7 @@ TEST_CASE("min(value, value) = right", "[algorithm/min]")


using ResT = decltype(based::min(a, b));

STATIC_REQUIRE(based::SameAs<int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&, ResT>);
REQUIRE(based::min(a, b) == 3);
}

@@ -92,7 +92,7 @@ TEST_CASE("min(const value, literal) = left", "[algorithm/min]")


using ResT = decltype(based::min(a, 4));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(a, 4) == 3);
}

@@ -102,7 +102,7 @@ TEST_CASE("min(const value, literal) = right", "[algorithm/min]")


using ResT = decltype(based::min(a, 3));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(a, 3) == 3);
}

@@ -112,7 +112,7 @@ TEST_CASE("min(literal, const value) = left", "[algorithm/min]")


using ResT = decltype(based::min(3, b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(3, b) == 3);
}

@@ -122,7 +122,7 @@ TEST_CASE("min(literal, const value) = right", "[algorithm/min]")


using ResT = decltype(based::min(4, b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(4, b) == 3);
}

@@ -133,7 +133,7 @@ TEST_CASE("min(const value, const value) = left", "[algorithm/min]")


using ResT = decltype(based::min(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::min(a, b) == 3);
}

@@ -144,7 +144,7 @@ TEST_CASE("min(const value, const value) = right", "[algorithm/min]")


using ResT = decltype(based::min(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::min(a, b) == 3);
}

@@ -155,7 +155,7 @@ TEST_CASE("min(value, const value) = left", "[algorithm/min]")


using ResT = decltype(based::min(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::min(a, b) == 3);
}

@@ -166,7 +166,7 @@ TEST_CASE("min(value, const value) = right", "[algorithm/min]")


using ResT = decltype(based::min(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::min(a, b) == 3);
}

@@ -177,7 +177,7 @@ TEST_CASE("min(const value, value) = left", "[algorithm/min]")


using ResT = decltype(based::min(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::min(a, b) == 3);
}

@@ -188,7 +188,7 @@ TEST_CASE("min(const value, value) = right", "[algorithm/min]")


using ResT = decltype(based::min(a, b));

STATIC_REQUIRE(based::SameAs<const int&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<const int&, ResT>);
REQUIRE(based::min(a, b) == 3);
}

@@ -198,7 +198,7 @@ TEST_CASE("min(move, literal) = left", "[algorithm/min]")


using ResT = decltype(based::min(based::move(a), 4));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::min(based::move(a), 4) == 3);
}

@@ -208,7 +208,7 @@ TEST_CASE("min(move, literal) = right", "[algorithm/min]")


using ResT = decltype(based::min(based::move(a), 3));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::min(based::move(a), 3) == 3);
}

@@ -219,7 +219,7 @@ TEST_CASE("min(move, value) = left", "[algorithm/min]")


using ResT = decltype(based::min(based::move(a), b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(based::move(a), b) == 3);
}

@@ -230,7 +230,7 @@ TEST_CASE("min(move, value) = right", "[algorithm/min]")


using ResT = decltype(based::min(based::move(a), b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(based::move(a), b) == 3);
}

@@ -241,7 +241,7 @@ TEST_CASE("min(move, const value) = left", "[algorithm/min]")


using ResT = decltype(based::min(based::move(a), b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(based::move(a), b) == 3);
}

@@ -252,7 +252,7 @@ TEST_CASE("min(move, const value) = right", "[algorithm/min]")


using ResT = decltype(based::min(based::move(a), b));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(based::move(a), b) == 3);
}

@@ -262,7 +262,7 @@ TEST_CASE("min(literal, move) = left", "[algorithm/min]")


using ResT = decltype(based::min(3, based::move(b)));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::min(3, based::move(b)) == 3);
}

@@ -272,7 +272,7 @@ TEST_CASE("min(literal, move) = right", "[algorithm/min]")


using ResT = decltype(based::min(4, based::move(b)));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::min(4, based::move(b)) == 3);
}

@@ -283,7 +283,7 @@ TEST_CASE("min(value, move) = left", "[algorithm/min]")


using ResT = decltype(based::min(a, based::move(b)));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(a, based::move(b)) == 3);
}

@@ -294,7 +294,7 @@ TEST_CASE("min(value, move) = right", "[algorithm/min]")


using ResT = decltype(based::min(a, based::move(b)));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(a, based::move(b)) == 3);
}

@@ -305,7 +305,7 @@ TEST_CASE("min(const value, move) = left", "[algorithm/min]")


using ResT = decltype(based::min(a, based::move(b)));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(a, based::move(b)) == 3);
}

@@ -316,7 +316,7 @@ TEST_CASE("min(const value, move) = right", "[algorithm/min]")


using ResT = decltype(based::min(a, based::move(b)));

STATIC_REQUIRE(based::SameAs<int, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int, ResT>);
REQUIRE(based::min(a, based::move(b)) == 3);
}

@@ -327,7 +327,7 @@ TEST_CASE("min(move, move) = left", "[algorithm/min]")


using ResT = decltype(based::min(based::move(a), based::move(b)));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::min(based::move(a), based::move(b)) == 3);
}

@@ -338,7 +338,7 @@ TEST_CASE("min(move, move) = right", "[algorithm/min]")


using ResT = decltype(based::min(based::move(a), based::move(b)));

STATIC_REQUIRE(based::SameAs<int&&, ResT>);
STATIC_REQUIRE(based::trait::IsSame<int&&, ResT>);
REQUIRE(based::min(based::move(a), based::move(b)) == 3);
}

diff --git a/ test/source/concept/callable_test.cpp b/ test/source/concept/callable_test.cpp

@@ -4,8 +4,7 @@


#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/trait/remove_extent.hpp"
#include "based/concept/is_same.hpp"

namespace
{

@@ -18,15 +17,15 @@ int free_func(int a, double b)


} // namespace

using based::SameAs;
using based::trait::IsSame;

TEST_CASE("free function", "[concept/callable]")
{
using TypeT = decltype(free_func);

STATIC_REQUIRE(based::Callable<TypeT>);
STATIC_REQUIRE(SameAs<based::CallableSigT<TypeT>, int(int, double)>);
STATIC_REQUIRE(SameAs<based::CallableRetT<TypeT>, int>);
STATIC_REQUIRE(IsSame<based::CallableSigT<TypeT>, int(int, double)>);
STATIC_REQUIRE(IsSame<based::CallableRetT<TypeT>, int>);
}

TEST_CASE("lambda", "[concept/callable]")

@@ -38,8 +37,8 @@ TEST_CASE("lambda", "[concept/callable]")

using TypeT = decltype(func);

STATIC_REQUIRE(based::Callable<TypeT>);
STATIC_REQUIRE(SameAs<based::CallableSigT<TypeT>, int(int, double)>);
STATIC_REQUIRE(SameAs<based::CallableRetT<TypeT>, int>);
STATIC_REQUIRE(IsSame<based::CallableSigT<TypeT>, int(int, double)>);
STATIC_REQUIRE(IsSame<based::CallableRetT<TypeT>, int>);
}

struct Func

@@ -55,7 +54,7 @@ TEST_CASE("member function", "[concept/callable]")


// based::error_template<decltype(&func::template operator()<int, double>)>();
STATIC_REQUIRE(based::Callable<Func>);
STATIC_REQUIRE(SameAs<based::CallableSigT<Func>, int(int, double)>);
STATIC_REQUIRE(SameAs<based::CallableRetT<Func>, int>);
STATIC_REQUIRE(IsSame<based::CallableSigT<Func>, int(int, double)>);
STATIC_REQUIRE(IsSame<based::CallableRetT<Func>, int>);
}
*/

diff --git a/ test/source/enum/bitmask_test.cpp b/ test/source/enum/bitmask_test.cpp

@@ -2,7 +2,7 @@


#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/enum/enum.hpp"
#include "based/integral/types.hpp"

@@ -26,8 +26,7 @@ TEST_CASE("types", "[enum/enum_flag]")


TEST_CASE("operations", "[enum/enum_flag]")
{
using based::SameAs;

using based::trait::IsSame;
SECTION("operators")
{
using namespace based::enumeration; // NOLINT(*namespace*)

@@ -37,13 +36,13 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
a == b
} -> SameAs<bool>;
} -> IsSame<bool>;
});

STATIC_REQUIRE(requires(var a, var b) {
{
a != b
} -> SameAs<bool>;
} -> IsSame<bool>;
});
}

@@ -52,13 +51,13 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
a | b
} -> SameAs<var>;
} -> IsSame<var>;
});

STATIC_REQUIRE(requires(var a, var b) {
{
a |= b
} -> SameAs<var&>;
} -> IsSame<var&>;
});
}

@@ -67,13 +66,13 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
a& b
} -> SameAs<var>;
} -> IsSame<var>;
});

STATIC_REQUIRE(requires(var a, var b) {
{
a &= b
} -> SameAs<var&>;
} -> IsSame<var&>;
});
}

@@ -82,13 +81,13 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
a ^ b
} -> SameAs<var>;
} -> IsSame<var>;
});

STATIC_REQUIRE(requires(var a, var b) {
{
a ^= b
} -> SameAs<var&>;
} -> IsSame<var&>;
});
}

@@ -97,7 +96,7 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a) {
{
~a
} -> SameAs<var>;
} -> IsSame<var>;
});
}

@@ -106,7 +105,7 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
set(a, b)
} -> SameAs<var&>;
} -> IsSame<var&>;
});
}

@@ -115,7 +114,7 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
mask(a, b)
} -> SameAs<var&>;
} -> IsSame<var&>;
});
}

@@ -124,7 +123,7 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
tgl(a, b)
} -> SameAs<var&>;
} -> IsSame<var&>;
});
}

@@ -133,7 +132,7 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a) {
{
neg(a)
} -> SameAs<var&>;
} -> IsSame<var&>;
});
}

@@ -142,7 +141,7 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
clear(a, b)
} -> SameAs<var&>;
} -> IsSame<var&>;
});
}

@@ -151,7 +150,7 @@ TEST_CASE("operations", "[enum/enum_flag]")

STATIC_REQUIRE(requires(var a, var b) {
{
test(a, b)
} -> SameAs<bool>;
} -> IsSame<bool>;
});
}
}

diff --git a/ test/source/enum/standard_test.cpp b/ test/source/enum/standard_test.cpp

@@ -2,7 +2,7 @@


#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/invocable.hpp"
#include "based/concept/is_invocable.hpp"
#include "based/enum/enum.hpp"
#include "based/integral/types.hpp"

@@ -61,6 +61,6 @@ TEST_CASE("safety", "[enum/standard]")

REQUIRE(crnt.get_var(Test::var::b) == 2);
REQUIRE(crnt.get_var(Test::var::c) == 3);

REQUIRE(!based::Invocable<decltype(&Test::get_var), based::U8>);
REQUIRE(!based::Invocable<decltype(&Test::get_var), int>);
REQUIRE(!based::trait::IsInvocable<decltype(&Test::get_var), based::U8>);
REQUIRE(!based::trait::IsInvocable<decltype(&Test::get_var), int>);
}

diff --git a/ test/source/integral/literals_test.cpp b/ test/source/integral/literals_test.cpp

@@ -4,38 +4,44 @@


#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/castable.hpp"
#include "based/concept/is_castable.hpp"

using namespace based::literals; // NOLINT(*namespace*)

using based::CastableTo;
using based::trait::IsCastableTo;

TEST_CASE("unsigned", "[integral/literals]")
{
STATIC_REQUIRE(CastableTo<decltype(0_u), based::U8>);
STATIC_REQUIRE(CastableTo<decltype(255_u), based::U8>);
STATIC_REQUIRE(CastableTo<decltype(256_u), based::U16>);
STATIC_REQUIRE(CastableTo<decltype(65535_u), based::U16>);
STATIC_REQUIRE(CastableTo<decltype(65536_u), based::U32>);
STATIC_REQUIRE(CastableTo<decltype(4294967295_u), based::U32>);
STATIC_REQUIRE(CastableTo<decltype(4294967296_u), based::U64>);
STATIC_REQUIRE(CastableTo<decltype(18446744073709551615_u), based::U64>);
// clang-format off
STATIC_REQUIRE(IsCastableTo<decltype(0_u), based::U8>);
STATIC_REQUIRE(IsCastableTo<decltype(255_u), based::U8>);
STATIC_REQUIRE(IsCastableTo<decltype(256_u), based::U16>);
STATIC_REQUIRE(IsCastableTo<decltype(65535_u), based::U16>);
STATIC_REQUIRE(IsCastableTo<decltype(65536_u), based::U32>);
STATIC_REQUIRE(IsCastableTo<decltype(4294967295_u), based::U32>);
STATIC_REQUIRE(IsCastableTo<decltype(4294967296_u), based::U64>);
STATIC_REQUIRE(IsCastableTo<decltype(18446744073709551615_u), based::U64>);
// clang-format on
}

TEST_CASE("signed", "[integral/literals]")
{
STATIC_REQUIRE(CastableTo<decltype(0_i), based::I8>);
STATIC_REQUIRE(CastableTo<decltype(127_i), based::I8>);
STATIC_REQUIRE(CastableTo<decltype(128_i), based::I16>);
STATIC_REQUIRE(CastableTo<decltype(32767_i), based::I16>);
STATIC_REQUIRE(CastableTo<decltype(2147483647_i), based::I32>);
STATIC_REQUIRE(CastableTo<decltype(2147483648_i), based::I64>);
STATIC_REQUIRE(CastableTo<decltype(9223372036854775807_i), based::I64>);

STATIC_REQUIRE(CastableTo<decltype(-127_i), based::I8>);
STATIC_REQUIRE(CastableTo<decltype(-128_i), based::I16>);
STATIC_REQUIRE(CastableTo<decltype(-32767_i), based::I16>);
STATIC_REQUIRE(CastableTo<decltype(-2147483647_i), based::I32>);
STATIC_REQUIRE(CastableTo<decltype(-2147483648_i), based::I64>);
STATIC_REQUIRE(CastableTo<decltype(-9223372036854775807_i), based::I64>);
// clang-format off
STATIC_REQUIRE(IsCastableTo<decltype(0_i), based::I8>);
STATIC_REQUIRE(IsCastableTo<decltype(127_i), based::I8>);
STATIC_REQUIRE(IsCastableTo<decltype(128_i), based::I16>);
STATIC_REQUIRE(IsCastableTo<decltype(32767_i), based::I16>);
STATIC_REQUIRE(IsCastableTo<decltype(2147483647_i), based::I32>);
STATIC_REQUIRE(IsCastableTo<decltype(2147483648_i), based::I64>);
STATIC_REQUIRE(IsCastableTo<decltype(9223372036854775807_i), based::I64>);
// clang-format

// clang-format off
STATIC_REQUIRE(IsCastableTo<decltype(-127_i), based::I8>);
STATIC_REQUIRE(IsCastableTo<decltype(-128_i), based::I16>);
STATIC_REQUIRE(IsCastableTo<decltype(-32767_i), based::I16>);
STATIC_REQUIRE(IsCastableTo<decltype(-2147483647_i), based::I32>);
STATIC_REQUIRE(IsCastableTo<decltype(-2147483648_i), based::I64>);
STATIC_REQUIRE(IsCastableTo<decltype(-9223372036854775807_i), based::I64>);
// clang-format on
}

diff --git a/ test/source/integral/type_test.cpp b/ test/source/integral/type_test.cpp

@@ -2,340 +2,340 @@


#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
#include "based/integral/types.hpp"

using based::SameAs;
using based::U16;
using based::U32;
using based::U64;
using based::U8;
using based::trait::IsSame;

TEST_CASE("U8", "[integral/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>; });
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, 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>; });

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<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, U8 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs + rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs - rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs * rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs / rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs % rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs & rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs | rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs ^ rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs << rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs >> rhs } -> IsSame<U8>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs += rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs -= rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs *= rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs /= rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs %= rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs &= rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs |= rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs ^= rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs <<= rhs } -> IsSame<U8&>; });
STATIC_REQUIRE(requires(U8 lhs, U8 rhs) { { lhs >>= rhs } -> IsSame<U8&>; });

STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs + rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs - rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs * rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs / rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs << rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs >> rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs % rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs & rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs | rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U8 lhs, U16 rhs) { { lhs ^ rhs } -> IsSame<U16>; });

STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs + rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs - rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs * rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs / rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs % rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs << rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs >> rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs & rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs | rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs ^ rhs } -> IsSame<U32>; });

STATIC_REQUIRE(requires(U8 lhs, U32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs + rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs - rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs * rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs / rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs % rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs << rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs >> rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs & rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs | rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U8 lhs, U64 rhs) { { lhs ^ rhs } -> IsSame<U64>; });
// clang-format on
}

TEST_CASE("U16", "[integral/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, 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, 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<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, U8 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs + rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs - rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs * rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs / rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs % rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs << rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs >> rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs & rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs | rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs ^ rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs += rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs -= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs *= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs /= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs %= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs &= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs |= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs ^= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs <<= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U8 rhs) { { lhs >>= rhs } -> IsSame<U16&>; });

STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs + rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs - rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs * rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs / rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs % rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs << rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs >> rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs & rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs | rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs ^ rhs } -> IsSame<U16>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs += rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs -= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs *= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs /= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs %= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs &= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs |= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs ^= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs <<= rhs } -> IsSame<U16&>; });
STATIC_REQUIRE(requires(U16 lhs, U16 rhs) { { lhs >>= rhs } -> IsSame<U16&>; });

STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs + rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs - rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs * rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs / rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs % rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs << rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs >> rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs & rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs | rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs ^ rhs } -> IsSame<U32>; });

STATIC_REQUIRE(requires(U16 lhs, U32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs + rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs - rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs * rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs / rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs % rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs << rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs >> rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs & rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs | rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U16 lhs, U64 rhs) { { lhs ^ rhs } -> IsSame<U64>; });
// clang-format on
}

TEST_CASE("U32", "[integral/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, 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, 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<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, U8 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs + rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs - rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs * rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs / rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs % rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs << rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs >> rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs & rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs | rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs ^ rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs += rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs -= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs *= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs /= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs %= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs &= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs |= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs ^= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs <<= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U8 rhs) { { lhs >>= rhs } -> IsSame<U32&>; });

STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs + rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs - rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs * rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs / rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs % rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs << rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs >> rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs & rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs | rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs ^ rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs += rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs -= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs *= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs /= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs %= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs &= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs |= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs ^= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs <<= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U16 rhs) { { lhs >>= rhs } -> IsSame<U32&>; });

STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs + rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs - rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs * rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs / rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs % rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs << rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs >> rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs & rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs | rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs ^ rhs } -> IsSame<U32>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs += rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs -= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs *= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs /= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs %= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs &= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs |= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs ^= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs <<= rhs } -> IsSame<U32&>; });
STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs >>= rhs } -> IsSame<U32&>; });

STATIC_REQUIRE(requires(U32 lhs, U32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs + rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs - rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs * rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs / rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs % rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs << rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs >> rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs & rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs | rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U32 lhs, U64 rhs) { { lhs ^ rhs } -> IsSame<U64>; });
// clang-format on
}

TEST_CASE("U64", "[integral/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, 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, 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<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, U8 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs + rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs - rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs * rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs / rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs % rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs << rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs >> rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs & rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs | rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs ^ rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs += rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs -= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs *= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs /= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs %= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs &= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs |= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs ^= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs <<= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U8 rhs) { { lhs >>= rhs } -> IsSame<U64&>; });

STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs + rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs - rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs * rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs / rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs % rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs << rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs >> rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs & rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs | rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs ^ rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs += rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs -= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs *= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs /= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs %= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs &= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs |= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs ^= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs <<= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U16 rhs) { { lhs >>= rhs } -> IsSame<U64&>; });

STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs + rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs - rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs * rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs / rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs % rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs << rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs >> rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs & rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs | rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs ^ rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs += rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs -= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs *= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs /= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs %= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs &= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs |= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs ^= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs <<= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs >>= rhs } -> IsSame<U64&>; });

STATIC_REQUIRE(requires(U64 lhs, U32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs + rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs - rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs * rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs / rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs % rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs << rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs >> rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs & rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs | rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs ^ rhs } -> IsSame<U64>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs += rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs -= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs *= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs /= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs %= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs &= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs |= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs ^= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs <<= rhs } -> IsSame<U64&>; });
STATIC_REQUIRE(requires(U64 lhs, U64 rhs) { { lhs >>= rhs } -> IsSame<U64&>; });
// clang-format on
}

@@ -347,197 +347,197 @@ using based::I8;

TEST_CASE("I8", "[integral/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, 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>; });
STATIC_REQUIRE(requires(I8 lhs, I16 rhs) { { lhs % rhs } -> SameAs<I16>; });

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>; });
STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs % rhs } -> SameAs<I32>; });

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>; });
STATIC_REQUIRE(requires(I8 lhs, I64 rhs) { { lhs % rhs } -> SameAs<I64>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs + rhs } -> IsSame<I8>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs - rhs } -> IsSame<I8>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs * rhs } -> IsSame<I8>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs / rhs } -> IsSame<I8>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs % rhs } -> IsSame<I8>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs += rhs } -> IsSame<I8&>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs -= rhs } -> IsSame<I8&>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs *= rhs } -> IsSame<I8&>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs /= rhs } -> IsSame<I8&>; });
STATIC_REQUIRE(requires(I8 lhs, I8 rhs) { { lhs %= rhs } -> IsSame<I8&>; });

STATIC_REQUIRE(requires(I8 lhs, I16 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I8 lhs, I16 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I8 lhs, I16 rhs) { { lhs + rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I8 lhs, I16 rhs) { { lhs - rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I8 lhs, I16 rhs) { { lhs * rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I8 lhs, I16 rhs) { { lhs / rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I8 lhs, I16 rhs) { { lhs % rhs } -> IsSame<I16>; });

STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs + rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs - rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs * rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs / rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs % rhs } -> IsSame<I32>; });

STATIC_REQUIRE(requires(I8 lhs, I32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I8 lhs, I64 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I8 lhs, I64 rhs) { { lhs + rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I8 lhs, I64 rhs) { { lhs - rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I8 lhs, I64 rhs) { { lhs * rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I8 lhs, I64 rhs) { { lhs / rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I8 lhs, I64 rhs) { { lhs % rhs } -> IsSame<I64>; });
// clang-format on
}

TEST_CASE("I16", "[integral/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, 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, 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>; });
STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs % rhs } -> SameAs<I32>; });

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>; });
STATIC_REQUIRE(requires(I16 lhs, I64 rhs) { { lhs % rhs } -> SameAs<I64>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs + rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs - rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs * rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs / rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs % rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs += rhs } -> IsSame<I16&>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs -= rhs } -> IsSame<I16&>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs *= rhs } -> IsSame<I16&>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs /= rhs } -> IsSame<I16&>; });
STATIC_REQUIRE(requires(I16 lhs, I8 rhs) { { lhs %= rhs } -> IsSame<I16&>; });

STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs + rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs - rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs * rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs / rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs % rhs } -> IsSame<I16>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs += rhs } -> IsSame<I16&>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs -= rhs } -> IsSame<I16&>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs *= rhs } -> IsSame<I16&>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs /= rhs } -> IsSame<I16&>; });
STATIC_REQUIRE(requires(I16 lhs, I16 rhs) { { lhs %= rhs } -> IsSame<I16&>; });

STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs + rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs - rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs * rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs / rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs % rhs } -> IsSame<I32>; });

STATIC_REQUIRE(requires(I16 lhs, I32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I16 lhs, I64 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I16 lhs, I64 rhs) { { lhs + rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I16 lhs, I64 rhs) { { lhs - rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I16 lhs, I64 rhs) { { lhs * rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I16 lhs, I64 rhs) { { lhs / rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I16 lhs, I64 rhs) { { lhs % rhs } -> IsSame<I64>; });
// clang-format on
}

TEST_CASE("I32", "[integral/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, 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, 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<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>; });
STATIC_REQUIRE(requires(I32 lhs, I64 rhs) { { lhs % rhs } -> SameAs<I64>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs + rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs - rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs * rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs / rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs % rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs += rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs -= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs *= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs /= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I8 rhs) { { lhs %= rhs } -> IsSame<I32&>; });

STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs + rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs - rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs * rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs / rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs % rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs += rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs -= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs *= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs /= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I16 rhs) { { lhs %= rhs } -> IsSame<I32&>; });

STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs + rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs - rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs * rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs / rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs % rhs } -> IsSame<I32>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs += rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs -= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs *= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs /= rhs } -> IsSame<I32&>; });
STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs %= rhs } -> IsSame<I32&>; });

STATIC_REQUIRE(requires(I32 lhs, I32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I32 lhs, I64 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I32 lhs, I64 rhs) { { lhs + rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I32 lhs, I64 rhs) { { lhs - rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I32 lhs, I64 rhs) { { lhs * rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I32 lhs, I64 rhs) { { lhs / rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I32 lhs, I64 rhs) { { lhs % rhs } -> IsSame<I64>; });
// clang-format on
}

TEST_CASE("I64", "[integral/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, 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, 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<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, I8 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs + rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs - rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs * rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs / rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs % rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs += rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs -= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs *= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs /= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I8 rhs) { { lhs %= rhs } -> IsSame<I64&>; });

STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs + rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs - rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs * rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs / rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs % rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs += rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs -= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs *= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs /= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I16 rhs) { { lhs %= rhs } -> IsSame<I64&>; });

STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs + rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs - rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs * rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs / rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs % rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs += rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs -= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs *= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs /= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs %= rhs } -> IsSame<I64&>; });

STATIC_REQUIRE(requires(I64 lhs, I32 rhs) { { lhs == rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs <= rhs } -> IsSame<bool>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs + rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs - rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs * rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs / rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs % rhs } -> IsSame<I64>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs += rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs -= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs *= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs /= rhs } -> IsSame<I64&>; });
STATIC_REQUIRE(requires(I64 lhs, I64 rhs) { { lhs %= rhs } -> IsSame<I64&>; });
// clang-format on
}

diff --git a/ test/source/trait/invoke_result_test.cpp b/ test/source/trait/invoke_result_test.cpp

@@ -4,7 +4,7 @@


#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"

namespace
{

@@ -15,7 +15,7 @@ int func(double);

} // namespace

template<class Res, class T, class... Args>
concept Test = based::SameAs<based::InvokeResultT<T, Args...>, Res>;
concept Test = based::trait::IsSame<based::InvokeResultT<T, Args...>, Res>;

TEST_CASE("invoke_result", "[trait/invoke_result]")
{

diff --git a/ test/source/trait/is_array_test.cpp b/ test/source/trait/is_array_test.cpp

@@ -2,22 +2,22 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/array.hpp"
#include "based/concept/is_array.hpp"

TEST_CASE("is_array", "[trait/is_array]")
TEST_CASE("IsArray", "[concept/IsArray]")
{
// clang-format off
struct Test {};

// NOLINTBEGIN(*array*)
STATIC_REQUIRE(!based::is_array_v<Test>);
STATIC_REQUIRE(based::is_array_v<Test[]>);
STATIC_REQUIRE(based::is_array_v<Test[3]>);
STATIC_REQUIRE(!based::is_array_v<float>);
STATIC_REQUIRE(!based::is_array_v<int>);
STATIC_REQUIRE(based::is_array_v<int[]>);
STATIC_REQUIRE(based::is_array_v<int[3]>);
STATIC_REQUIRE(!based::is_array_v<std::array<int, 3>>);
STATIC_REQUIRE(!based::trait::IsArray<Test>);
STATIC_REQUIRE(based::trait::IsArray<Test[]>);
STATIC_REQUIRE(based::trait::IsArray<Test[3]>);
STATIC_REQUIRE(!based::trait::IsArray<float>);
STATIC_REQUIRE(!based::trait::IsArray<int>);
STATIC_REQUIRE(based::trait::IsArray<int[]>);
STATIC_REQUIRE(based::trait::IsArray<int[3]>);
STATIC_REQUIRE(!based::trait::IsArray<std::array<int, 3>>);
// clang-format on
// NOLINTEND(*array*)
}

diff --git a/ test/source/trait/is_base_of_test.cpp b/ test/source/trait/is_base_of_test.cpp

@@ -2,9 +2,9 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/base_of.hpp"
#include "based/concept/is_base_of.hpp"

TEST_CASE("is_base_of", "[trait/is_base_of]")
TEST_CASE("IsBaseOf", "[concept/IsBaseOf]")
{
// clang-format off
class A {};

@@ -14,12 +14,12 @@ TEST_CASE("is_base_of", "[trait/is_base_of]")

union e {};
using I = int;

STATIC_REQUIRE(based::is_base_of_v<A, A>);
STATIC_REQUIRE(based::is_base_of_v<A, B>);
STATIC_REQUIRE(based::is_base_of_v<A, C>);
STATIC_REQUIRE(!based::is_base_of_v<A, D>);
STATIC_REQUIRE(!based::is_base_of_v<B, A>);
STATIC_REQUIRE(!based::is_base_of_v<e, e>);
STATIC_REQUIRE(!based::is_base_of_v<I, I>);
STATIC_REQUIRE(based::trait::IsBaseOf<A, A>);
STATIC_REQUIRE(based::trait::IsBaseOf<A, B>);
STATIC_REQUIRE(based::trait::IsBaseOf<A, C>);
STATIC_REQUIRE(!based::trait::IsBaseOf<A, D>);
STATIC_REQUIRE(!based::trait::IsBaseOf<B, A>);
STATIC_REQUIRE(!based::trait::IsBaseOf<e, e>);
STATIC_REQUIRE(!based::trait::IsBaseOf<I, I>);
// clang-format on
}

diff --git a/ test/source/trait/is_class_test.cpp b/ test/source/trait/is_class_test.cpp

@@ -2,9 +2,9 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/class.hpp"
#include "based/concept/is_class.hpp"

TEST_CASE("is_class", "[trait/is_class]")
TEST_CASE("IsClass", "[concept/IsClass]")
{
// clang-format off
struct A {};

@@ -12,14 +12,14 @@ TEST_CASE("is_class", "[trait/is_class]")

enum class e {};
union u { class Uc {}; };

STATIC_REQUIRE(based::is_class_v<A>);
STATIC_REQUIRE(based::is_class_v<B>);
STATIC_REQUIRE(!based::is_class_v<B*>);
STATIC_REQUIRE(!based::is_class_v<B&>);
STATIC_REQUIRE(based::is_class_v<const B>);
STATIC_REQUIRE(!based::is_class_v<e>);
STATIC_REQUIRE(!based::is_class_v<u>);
STATIC_REQUIRE(based::is_class_v<u::Uc>);
STATIC_REQUIRE(!based::is_class_v<int>);
STATIC_REQUIRE(based::trait::IsClass<A>);
STATIC_REQUIRE(based::trait::IsClass<B>);
STATIC_REQUIRE(!based::trait::IsClass<B*>);
STATIC_REQUIRE(!based::trait::IsClass<B&>);
STATIC_REQUIRE(based::trait::IsClass<const B>);
STATIC_REQUIRE(!based::trait::IsClass<e>);
STATIC_REQUIRE(!based::trait::IsClass<u>);
STATIC_REQUIRE(based::trait::IsClass<u::Uc>);
STATIC_REQUIRE(!based::trait::IsClass<int>);
// clang-format on
}

diff --git a/ test/source/trait/is_const_test.cpp b/ test/source/trait/is_const_test.cpp

@@ -2,35 +2,35 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/const.hpp"
#include "based/concept/is_const.hpp"

TEST_CASE("is_const", "[trait/is_const]")
TEST_CASE("IsConst", "[concept/IsConst]")
{
// clang-format off
struct Test {};

// NOLINTBEGIN(*array*)
STATIC_REQUIRE(!based::is_const_v<int>);
STATIC_REQUIRE(!based::is_const_v<int&>);
STATIC_REQUIRE(!based::is_const_v<int&&>);
STATIC_REQUIRE(!based::is_const_v<int[2]>);
STATIC_REQUIRE(!based::is_const_v<int(&)[2]>);
STATIC_REQUIRE(!based::is_const_v<int(&&)[2]>);
STATIC_REQUIRE(based::is_const_v<const int>);
STATIC_REQUIRE(!based::is_const_v<const int&>);
STATIC_REQUIRE(based::is_const_v<const int[2]>);
STATIC_REQUIRE(!based::is_const_v<const int(&)[2]>);
STATIC_REQUIRE(!based::is_const_v<int(int)>);
STATIC_REQUIRE(!based::is_const_v<volatile int>);
STATIC_REQUIRE(!based::is_const_v<volatile int&>);
STATIC_REQUIRE(!based::is_const_v<volatile int&&>);
STATIC_REQUIRE(!based::is_const_v<volatile int[2]>);
STATIC_REQUIRE(!based::is_const_v<volatile int(&)[2]>);
STATIC_REQUIRE(!based::is_const_v<volatile int(&&)[2]>);
STATIC_REQUIRE(based::is_const_v<const volatile int>);
STATIC_REQUIRE(!based::is_const_v<const volatile int&>);
STATIC_REQUIRE(based::is_const_v<const volatile int[2]>);
STATIC_REQUIRE(!based::is_const_v<const volatile int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsConst<int>);
STATIC_REQUIRE(!based::trait::IsConst<int&>);
STATIC_REQUIRE(!based::trait::IsConst<int&&>);
STATIC_REQUIRE(!based::trait::IsConst<int[2]>);
STATIC_REQUIRE(!based::trait::IsConst<int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsConst<int(&&)[2]>);
STATIC_REQUIRE(based::trait::IsConst<const int>);
STATIC_REQUIRE(!based::trait::IsConst<const int&>);
STATIC_REQUIRE(based::trait::IsConst<const int[2]>);
STATIC_REQUIRE(!based::trait::IsConst<const int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsConst<int(int)>);
STATIC_REQUIRE(!based::trait::IsConst<volatile int>);
STATIC_REQUIRE(!based::trait::IsConst<volatile int&>);
STATIC_REQUIRE(!based::trait::IsConst<volatile int&&>);
STATIC_REQUIRE(!based::trait::IsConst<volatile int[2]>);
STATIC_REQUIRE(!based::trait::IsConst<volatile int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsConst<volatile int(&&)[2]>);
STATIC_REQUIRE(based::trait::IsConst<const volatile int>);
STATIC_REQUIRE(!based::trait::IsConst<const volatile int&>);
STATIC_REQUIRE(based::trait::IsConst<const volatile int[2]>);
STATIC_REQUIRE(!based::trait::IsConst<const volatile int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}

diff --git a/ test/source/trait/is_enum_test.cpp b/ test/source/trait/is_enum_test.cpp

@@ -2,19 +2,19 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/enum.hpp"
#include "based/concept/is_enum.hpp"

TEST_CASE("is_enum", "[trait/is_enum]")
TEST_CASE("IsEnum", "[concept/IsEnum]")
{
// clang-format off
struct A { enum e {}; };
enum e {};
enum class ec : int {};

STATIC_REQUIRE(!based::is_enum_v<A>);
STATIC_REQUIRE(based::is_enum_v<A::e>);
STATIC_REQUIRE(based::is_enum_v<e>);
STATIC_REQUIRE(based::is_enum_v<ec>);
STATIC_REQUIRE(!based::is_enum_v<int>);
STATIC_REQUIRE(!based::trait::IsEnum<A>);
STATIC_REQUIRE(based::trait::IsEnum<A::e>);
STATIC_REQUIRE(based::trait::IsEnum<e>);
STATIC_REQUIRE(based::trait::IsEnum<ec>);
STATIC_REQUIRE(!based::trait::IsEnum<int>);
// clang-format !on
}

diff --git a/ test/source/trait/is_lvalue_reference_test.cpp b/ test/source/trait/is_lvalue_reference_test.cpp

@@ -2,33 +2,33 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/lvalue_reference.hpp"
#include "based/concept/is_lvalue_reference.hpp"

TEST_CASE("is_lvalue_reference", "[trait/is_lvalue_reference]")
TEST_CASE("IsLvalueReference", "[concept/IsLvalueReference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(!based::is_lvalue_reference_v<int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int&&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int(&&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<int(int)>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<volatile int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int&&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<volatile int(&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<volatile int(&&)[2]>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const volatile int>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const volatile int&>);
STATIC_REQUIRE(!based::is_lvalue_reference_v<const volatile int[2]>);
STATIC_REQUIRE(based::is_lvalue_reference_v<const volatile int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<int>);
STATIC_REQUIRE(based::trait::IsLvalueReference<int&>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<int&&>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<int[2]>);
STATIC_REQUIRE(based::trait::IsLvalueReference<int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<int(&&)[2]>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<const int>);
STATIC_REQUIRE(based::trait::IsLvalueReference<const int&>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<const int[2]>);
STATIC_REQUIRE(based::trait::IsLvalueReference<const int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<int(int)>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<volatile int>);
STATIC_REQUIRE(based::trait::IsLvalueReference<volatile int&>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<volatile int&&>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<volatile int[2]>);
STATIC_REQUIRE(based::trait::IsLvalueReference<volatile int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<volatile int(&&)[2]>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<const volatile int>);
STATIC_REQUIRE(based::trait::IsLvalueReference<const volatile int&>);
STATIC_REQUIRE(!based::trait::IsLvalueReference<const volatile int[2]>);
STATIC_REQUIRE(based::trait::IsLvalueReference<const volatile int(&)[2]>);
// clang-format on
// NOLINTEND(*array*)
}

diff --git a/ test/source/trait/is_null_pointer_test.cpp b/ test/source/trait/is_null_pointer_test.cpp

@@ -2,22 +2,22 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/null_pointer.hpp"
#include "based/concept/is_null_pointer.hpp"

TEST_CASE("is_null_pointer", "[trait/is_null_pointer]")
TEST_CASE("IsNullPointer", "[concept/IsNullPointer]")
{
double const test = 0;

// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(based::is_null_pointer_v<decltype(nullptr)>);
STATIC_REQUIRE(!based::is_null_pointer_v<void>);
STATIC_REQUIRE(!based::is_null_pointer_v<const void>);
STATIC_REQUIRE(!based::is_null_pointer_v<volatile void>);
STATIC_REQUIRE(!based::is_null_pointer_v<void*>);
STATIC_REQUIRE(!based::is_null_pointer_v<int>);
STATIC_REQUIRE(!based::is_null_pointer_v<decltype(test)>);
STATIC_REQUIRE(!based::is_null_pointer_v<std::is_null_pointer<void>>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(based::trait::IsNullPointer<decltype(nullptr)>);
STATIC_REQUIRE(!based::trait::IsNullPointer<void>);
STATIC_REQUIRE(!based::trait::IsNullPointer<const void>);
STATIC_REQUIRE(!based::trait::IsNullPointer<volatile void>);
STATIC_REQUIRE(!based::trait::IsNullPointer<void*>);
STATIC_REQUIRE(!based::trait::IsNullPointer<int>);
STATIC_REQUIRE(!based::trait::IsNullPointer<decltype(test)>);
STATIC_REQUIRE(!based::trait::IsNullPointer<void>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/is_rvalue_reference_test.cpp b/ test/source/trait/is_rvalue_reference_test.cpp

@@ -2,33 +2,33 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/rvalue_reference.hpp"
#include "based/concept/is_rvalue_reference.hpp"

TEST_CASE("is_rvalue_reference", "[trait/is_rvalue_reference]")
TEST_CASE("IsRvalueReference", "[concept/IsRvalueReference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(!based::is_rvalue_reference_v<int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int&>);
STATIC_REQUIRE(based::is_rvalue_reference_v<int&&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int(&)[2]>);
STATIC_REQUIRE(based::is_rvalue_reference_v<int(&&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const int(&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<int(int)>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int&>);
STATIC_REQUIRE(based::is_rvalue_reference_v<volatile int&&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<volatile int(&)[2]>);
STATIC_REQUIRE(based::is_rvalue_reference_v<volatile int(&&)[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int&>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int[2]>);
STATIC_REQUIRE(!based::is_rvalue_reference_v<const volatile int(&)[2]>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(!based::trait::IsRvalueReference<int>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<int&>);
STATIC_REQUIRE(based::trait::IsRvalueReference<int&&>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<int[2]>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<int(&)[2]>);
STATIC_REQUIRE(based::trait::IsRvalueReference<int(&&)[2]>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<const int>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<const int&>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<const int[2]>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<const int(&)[2]>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<int(int)>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<volatile int>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<volatile int&>);
STATIC_REQUIRE(based::trait::IsRvalueReference<volatile int&&>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<volatile int[2]>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<volatile int(&)[2]>);
STATIC_REQUIRE(based::trait::IsRvalueReference<volatile int(&&)[2]>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<const volatile int>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<const volatile int&>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<const volatile int[2]>);
STATIC_REQUIRE(!based::trait::IsRvalueReference<const volatile int(&)[2]>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/is_void_test.cpp b/ test/source/trait/is_void_test.cpp

@@ -2,21 +2,20 @@


#include <catch2/catch_test_macros.hpp>

#include "based/trait/is/void.hpp"
#include "based/concept/is_void.hpp"

TEST_CASE("is_void", "[trait/is_void]")
TEST_CASE("IsVoid", "[concept/IsVoid]")
{
double const test = 0;

// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(based::is_void_v<void>);
STATIC_REQUIRE(based::is_void_v<const void>);
STATIC_REQUIRE(based::is_void_v<volatile void>);
STATIC_REQUIRE(!based::is_void_v<void*>);
STATIC_REQUIRE(!based::is_void_v<int>);
STATIC_REQUIRE(!based::is_void_v<decltype(test)>);
STATIC_REQUIRE(!based::is_void_v<std::is_void<void>>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(based::trait::IsVoid<void>);
STATIC_REQUIRE(based::trait::IsVoid<const void>);
STATIC_REQUIRE(based::trait::IsVoid<volatile void>);
STATIC_REQUIRE(!based::trait::IsVoid<void*>);
STATIC_REQUIRE(!based::trait::IsVoid<int>);
STATIC_REQUIRE(!based::trait::IsVoid<decltype(test)>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/remove_const_test.cpp b/ test/source/trait/remove_const_test.cpp

@@ -1,37 +1,38 @@

#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE

#include "based/trait/remove_const.hpp"

#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/trait/remove_const.hpp"
#include "based/concept/is_same.hpp"

using based::SameAs;
using based::trait::IsSame;

TEST_CASE("remove_const", "[trait/remove/remove_const]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<int&>, int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<const int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<volatile int>, volatile int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<const volatile int>, volatile int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<const volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveConst<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<int&>, int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<int&&>, int&&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<const int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<const int&>, const int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<const int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<int(int)>, int(int)>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<volatile int>, volatile int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<volatile int&>, volatile int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<const volatile int>, volatile int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<const volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveConst<const volatile int(&)[2]>, volatile const int(&)[2]>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/remove_cv_test.cpp b/ test/source/trait/remove_cv_test.cpp

@@ -1,37 +1,38 @@

#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE

#include "based/trait/remove_cv.hpp"

#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/trait/remove_cv.hpp"
#include "based/concept/is_same.hpp"

using based::SameAs;
using based::trait::IsSame;

TEST_CASE("remove_cv", "[trait/remove_cv]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<int&>, int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<const int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<const volatile int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<const volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCv<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<int&>, int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<int&&>, int&&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<const int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<const int&>, const int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<const int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<int(int)>, int(int)>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<volatile int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<volatile int&>, volatile int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<volatile int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<const volatile int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<const volatile int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCv<const volatile int(&)[2]>, volatile const int(&)[2]>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/remove_cvref_test.cpp b/ test/source/trait/remove_cvref_test.cpp

@@ -1,37 +1,38 @@

#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE

#include "based/trait/remove_cvref.hpp"

#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/trait/remove_cvref.hpp"
#include "based/concept/is_same.hpp"

using based::SameAs;
using based::trait::IsSame;

TEST_CASE("remove_cvref", "[trait/remove_cvref]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<int&>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<int&&>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<const int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<const int&>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<const int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<const int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<volatile int&>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<volatile int&&>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<volatile int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<volatile int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<const volatile int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<const volatile int&>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<const volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveCvref<const volatile int(&)[2]>, int[2]>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<int&>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<int&&>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<int(&)[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<int(&&)[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<const int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<const int&>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<const int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<const int(&)[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<int(int)>, int(int)>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<volatile int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<volatile int&>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<volatile int&&>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<volatile int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<volatile int(&)[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<volatile int(&&)[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<const volatile int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<const volatile int&>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<const volatile int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveCvref<const volatile int(&)[2]>, int[2]>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/remove_pointer_test.cpp b/ test/source/trait/remove_pointer_test.cpp

@@ -1,22 +1,23 @@

#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE

#include "based/trait/remove_pointer.hpp"

#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/trait/remove_pointer.hpp"
#include "based/concept/is_same.hpp"

using based::SameAs;
using based::trait::IsSame;

TEST_CASE("remove_pointer", "[trait/remove_pointer]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::trait::RemovePointer<int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemovePointer<int*>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemovePointer<int**>, int*>);
STATIC_REQUIRE(SameAs<based::trait::RemovePointer<int* const>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemovePointer<int* volatile>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemovePointer<int* const volatile>, int>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(IsSame<based::trait::RemovePointer<int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemovePointer<int*>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemovePointer<int**>, int*>);
STATIC_REQUIRE(IsSame<based::trait::RemovePointer<int* const>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemovePointer<int* volatile>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemovePointer<int* const volatile>, int>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/remove_reference_test.cpp b/ test/source/trait/remove_reference_test.cpp

@@ -1,37 +1,38 @@

#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE

#include "based/trait/remove_reference.hpp"

#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/trait/remove_reference.hpp"
#include "based/concept/is_same.hpp"

using based::SameAs;
using based::trait::IsSame;

TEST_CASE("remove_reference", "[trait/remove_reference]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<int&>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<int&&>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<int(&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<int(&&)[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<const int>, const int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<const int&>, const int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<const int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<const int(&)[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<volatile int>,volatile int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<volatile int&>, volatile int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<volatile int&&>, volatile int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<volatile int(&)[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<volatile int(&&)[2]>, volatile int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<const volatile int>, const volatile int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<const volatile int&>, volatile const int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<const volatile int[2]>, const volatile int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveReference<const volatile int(&)[2]>, volatile const int[2]>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<int&>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<int&&>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<int(&)[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<int(&&)[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<const int>, const int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<const int&>, const int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<const int[2]>, const int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<const int(&)[2]>, const int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<int(int)>, int(int)>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<volatile int>,volatile int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<volatile int&>, volatile int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<volatile int&&>, volatile int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<volatile int[2]>, volatile int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<volatile int(&)[2]>, volatile int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<volatile int(&&)[2]>, volatile int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<const volatile int>, const volatile int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<const volatile int&>, volatile const int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<const volatile int[2]>, const volatile int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveReference<const volatile int(&)[2]>, volatile const int[2]>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/remove_volatile_test.cpp b/ test/source/trait/remove_volatile_test.cpp

@@ -1,37 +1,38 @@

#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE

#include "based/trait/remove_volatile.hpp"

#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/trait/remove_volatile.hpp"
#include "based/concept/is_same.hpp"

using based::SameAs;
using based::trait::IsSame;

TEST_CASE("remove_volatile", "[trait/remove/remove_volatile]")
{
// NOLINTBEGIN(*array*)
// clang-format off
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<int&>, int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<int&&>, int&&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<const int>, const int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<const int&>, const int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<const int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<int(int)>, int(int)>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<volatile int>, int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<volatile int&>, volatile int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<volatile int[2]>, int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<const volatile int>, const int>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<const volatile int[2]>, const int[2]>);
STATIC_REQUIRE(SameAs<based::trait::RemoveVolatile<const volatile int(&)[2]>, volatile const int(&)[2]>);
// clang-format on
// NOLINTBEGIN(*array*)
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<int&>, int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<int&&>, int&&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<int(&)[2]>, int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<int(&&)[2]>, int(&&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<const int>, const int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<const int&>, const int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<const int[2]>, const int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<const int(&)[2]>, const int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<int(int)>, int(int)>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<volatile int>, int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<volatile int&>, volatile int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<volatile int&&>, volatile int&&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<volatile int[2]>, int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<volatile int(&)[2]>, volatile int(&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<volatile int(&&)[2]>, volatile int(&&)[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<const volatile int>, const int>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<const volatile int&>, volatile const int&>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<const volatile int[2]>, const int[2]>);
STATIC_REQUIRE(IsSame<based::trait::RemoveVolatile<const volatile int(&)[2]>, volatile const int(&)[2]>);
// NOLINTEND(*array*)
// clang-format on
}

diff --git a/ test/source/trait/signature_test.cpp b/ test/source/trait/signature_test.cpp

@@ -4,7 +4,7 @@


#include <catch2/catch_test_macros.hpp>

#include "based/concept/is/same.hpp"
#include "based/concept/is_same.hpp"
// NOLINTBEGIN(*cognitive-complexity*)

namespace

@@ -24,24 +24,24 @@ int free_func_noexcept(const double& a, int&& b) noexcept(true)


} // namespace

using based::SameAs;
using based::trait::IsSame;

TEST_CASE("free function", "[trait/Signature]")
{
using Sig = based::Signature<decltype(free_func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("free function noexcept", "[trait/Signature]")
{
using Sig = based::Signature<decltype(free_func_noexcept)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("empty", "[trait/Signature]")

@@ -52,14 +52,14 @@ TEST_CASE("empty", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("const", "[trait/Signature]")

@@ -70,14 +70,14 @@ TEST_CASE("const", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("volatile", "[trait/Signature]")

@@ -88,14 +88,14 @@ TEST_CASE("volatile", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("const volatile", "[trait/Signature]")

@@ -106,14 +106,14 @@ TEST_CASE("const volatile", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("noexcept", "[trait/Signature]")

@@ -124,14 +124,14 @@ TEST_CASE("noexcept", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("const noexcept", "[trait/Signature]")

@@ -142,14 +142,14 @@ TEST_CASE("const noexcept", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("volatile noexcept", "[trait/Signature]")

@@ -160,14 +160,14 @@ TEST_CASE("volatile noexcept", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("const volatile noexcept", "[trait/Signature]")

@@ -178,14 +178,14 @@ TEST_CASE("const volatile noexcept", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("lvalref", "[trait/Signature]")

@@ -196,14 +196,14 @@ TEST_CASE("lvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("const lvalref", "[trait/Signature]")

@@ -214,14 +214,14 @@ TEST_CASE("const lvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("volatile lvalref", "[trait/Signature]")

@@ -232,14 +232,14 @@ TEST_CASE("volatile lvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("const volatile lvalref", "[trait/Signature]")

@@ -250,14 +250,14 @@ TEST_CASE("const volatile lvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("noexcept lvalref", "[trait/Signature]")

@@ -268,14 +268,14 @@ TEST_CASE("noexcept lvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("const noexcept lvalref", "[trait/Signature]")

@@ -286,14 +286,14 @@ TEST_CASE("const noexcept lvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("volatile noexcept lvalref", "[trait/Signature]")

@@ -304,14 +304,14 @@ TEST_CASE("volatile noexcept lvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("const volatile noexcept lvalref", "[trait/Signature]")

@@ -322,14 +322,14 @@ TEST_CASE("const volatile noexcept lvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("rvalref", "[trait/Signature]")

@@ -340,14 +340,14 @@ TEST_CASE("rvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("const rvalref", "[trait/Signature]")

@@ -358,14 +358,14 @@ TEST_CASE("const rvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("volatile rvalref", "[trait/Signature]")

@@ -376,14 +376,14 @@ TEST_CASE("volatile rvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("const volatile rvalref", "[trait/Signature]")

@@ -394,14 +394,14 @@ TEST_CASE("const volatile rvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::NoexceptVal>);
}

TEST_CASE("noexcept rvalref", "[trait/Signature]")

@@ -412,14 +412,14 @@ TEST_CASE("noexcept rvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("const noexcept rvalref", "[trait/Signature]")

@@ -430,14 +430,14 @@ TEST_CASE("const noexcept rvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("volatile noexcept rvalref", "[trait/Signature]")

@@ -448,14 +448,14 @@ TEST_CASE("volatile noexcept rvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

TEST_CASE("const volatile noexcept rvalref", "[trait/Signature]")

@@ -466,14 +466,14 @@ TEST_CASE("const volatile noexcept rvalref", "[trait/Signature]")

};

using Sig = based::Signature<decltype(&Test::func)>;
STATIC_REQUIRE(SameAs<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(SameAs<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(SameAs<int, Sig::RetType>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(SameAs<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(SameAs<based::TrueType, Sig::NoexceptVal>);
STATIC_REQUIRE(IsSame<int(const double&, int&&), Sig::SigType>);
STATIC_REQUIRE(IsSame<std::tuple<const double&, int&&>, Sig::ArgType>);
STATIC_REQUIRE(IsSame<int, Sig::RetType>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::ConstVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::VolatileVal>);
STATIC_REQUIRE(IsSame<based::FalseType, Sig::LvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::RvalrefVal>);
STATIC_REQUIRE(IsSame<based::TrueType, Sig::NoexceptVal>);
}

// NOLINTEND(*cognitive-complexity*)