#pragma once namespace BAN { template struct remove_refenrece { using type = T; }; template struct remove_refenrece { using type = T; }; template struct remove_refenrece { using type = T; }; template using remove_reference_t = typename remove_refenrece::type; template struct remove_const { using type = T; }; template struct remove_const { using type = T; }; template using remove_const_t = typename remove_const::type; template struct remove_volatile { using type = T; }; template struct remove_volatile { using type = T; }; template using remove_volatile_t = typename remove_volatile::type; template struct remove_cv { using type = remove_volatile_t>; }; template using remove_cv_t = typename remove_cv::type; template struct remove_const_and_reference { using type = remove_const_t>; }; template using remove_const_and_reference_t = typename remove_const_and_reference::type; template struct enable_if {}; template struct enable_if { using type = T; }; template using enable_if_t = typename enable_if::type; template struct maybe_const { using type = T; }; template struct maybe_const { using type = const T; }; template using maybe_const_t = typename maybe_const::type; template struct either_or { using type = T2; }; template struct either_or { using type = T1; }; template using either_or_t = typename either_or::type; template struct integral_constant { static constexpr T value = V; }; template inline constexpr T integral_constant_v = integral_constant::value; using true_type = integral_constant; using false_type = integral_constant; template struct is_same : false_type {}; template struct is_same : true_type {}; template inline constexpr bool is_same_v = is_same::value; template concept same_as = BAN::is_same_v; template struct is_lvalue_reference : false_type {}; template struct is_lvalue_reference : true_type {}; template inline constexpr bool is_lvalue_reference_v = is_lvalue_reference::value; template concept lvalue_reference = is_lvalue_reference_v; template struct is_constructible { static constexpr bool value = __is_constructible(T, Args...); }; template inline constexpr bool is_constructible_v = is_constructible::value; template struct is_default_constructible { static constexpr bool value = is_constructible_v; }; template inline constexpr bool is_default_constructible_v = is_default_constructible::value; template struct is_copy_constructible { static constexpr bool value = is_constructible_v; }; template inline constexpr bool is_copy_constructible_v = is_copy_constructible::value; template struct is_move_constructible { static constexpr bool value = is_constructible_v; }; template inline constexpr bool is_move_constructible_v = is_move_constructible::value; template struct is_integral { static constexpr bool value = requires (T t, T* p, void (*f)(T)) { reinterpret_cast(t); f(0); p + t; }; }; template inline constexpr bool is_integral_v = is_integral::value; template concept integral = is_integral_v; template struct is_floating_point : false_type {}; template<> struct is_floating_point : true_type {}; template<> struct is_floating_point : true_type {}; template<> struct is_floating_point : true_type {}; template inline constexpr bool is_floating_point_v = is_floating_point::value; template concept floating_point = is_floating_point_v; template struct is_pointer : false_type {}; template struct is_pointer : true_type {}; template struct is_pointer : true_type {}; template struct is_pointer : true_type {}; template struct is_pointer : true_type {}; template inline constexpr bool is_pointer_v = is_pointer::value; template concept pointer = is_pointer_v; template struct is_const : false_type {}; template struct is_const : true_type {}; template inline constexpr bool is_const_v = is_const::value; template struct is_arithmetic { static constexpr bool value = is_integral_v || is_floating_point_v; }; template inline constexpr bool is_arithmetic_v = is_arithmetic::value; template struct is_base_of { static constexpr bool value = __is_base_of(Base, Derived); }; template inline constexpr bool is_base_of_v = is_base_of::value; namespace detail { template> struct is_signed { static constexpr bool value = T(-1) < T(0); }; template struct is_signed : false_type {}; template> struct is_unsigned { static constexpr bool value = T(0) < T(-1); }; template struct is_unsigned : false_type {}; } template struct is_signed : detail::is_signed {}; template inline constexpr bool is_signed_v = is_signed::value; template concept signed_integral = is_signed_v && is_integral_v; template struct is_unsigned : detail::is_unsigned {}; template inline constexpr bool is_unsigned_v = is_unsigned::value; template concept unsigned_integral = is_unsigned_v && is_integral_v; #define __BAN_TRAITS_MAKE_UNSIGNED_CV(__type) \ template<> struct make_unsigned<__type> { using type = unsigned __type; }; \ template<> struct make_unsigned { using type = unsigned const __type; }; \ template<> struct make_unsigned { using type = unsigned volatile __type; }; \ template<> struct make_unsigned { using type = unsigned const volatile __type; }; template requires is_arithmetic_v struct make_unsigned { using type = T; }; __BAN_TRAITS_MAKE_UNSIGNED_CV(char) __BAN_TRAITS_MAKE_UNSIGNED_CV(short) __BAN_TRAITS_MAKE_UNSIGNED_CV(int) __BAN_TRAITS_MAKE_UNSIGNED_CV(long) __BAN_TRAITS_MAKE_UNSIGNED_CV(long long) template using make_unsigned_t = typename make_unsigned::type; #undef __BAN_TRAITS_MAKE_UNSIGNED_CV #define __BAN_TRAITS_MAKE_SIGNED_CV(__type) \ template<> struct make_signed { using type = __type; }; \ template<> struct make_signed { using type = const __type; }; \ template<> struct make_signed { using type = volatile __type; }; \ template<> struct make_signed { using type = const volatile __type; }; template requires is_arithmetic_v struct make_signed { using type = T; }; __BAN_TRAITS_MAKE_SIGNED_CV(char) __BAN_TRAITS_MAKE_SIGNED_CV(short) __BAN_TRAITS_MAKE_SIGNED_CV(int) __BAN_TRAITS_MAKE_SIGNED_CV(long) __BAN_TRAITS_MAKE_SIGNED_CV(long long) template using make_signed_t = typename make_signed::type; #undef __BAN_TRAITS_MAKE_SIGNED_CV template struct less { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } }; template struct equal { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; } }; template struct greater { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs > rhs; } }; }