#pragma once #include "asl/integers.hpp" namespace asl { struct empty {}; template struct id { using type = T; }; template static constexpr isize_t types_count = sizeof...(Args); template struct integral_constant { static constexpr T value = kValue; }; template using bool_constant = integral_constant; using true_type = bool_constant; using false_type = bool_constant; template struct _select_helper { using type = V; }; template struct _select_helper { using type = U; }; template using select_t = _select_helper::type; template struct _same_as_helper : false_type {}; template struct _same_as_helper : true_type {}; template concept same_as = _same_as_helper::value && _same_as_helper::value; template auto _as_lref_helper(int) -> id; template auto _as_lref_helper(...) -> id; template auto _as_rref_helper(int) -> id; template auto _as_rref_helper(...) -> id; template using as_lref_t = decltype(_as_lref_helper(0))::type; template using as_rref_t = decltype(_as_rref_helper(0))::type; template consteval as_rref_t declval() {} template struct _un_ref_t { using type = T; }; template struct _un_ref_t { using type = T; }; template struct _un_ref_t { using type = T; }; template using un_ref_t = _un_ref_t::type; template concept constructible_from = __is_constructible(T, Args...); template concept default_constructible = constructible_from; template concept copy_constructible = constructible_from>; template concept move_constructible = constructible_from>; template concept trivially_constructible_from = __is_trivially_constructible(T, Args...); template concept trivially_default_constructible = trivially_constructible_from; template concept trivially_copy_constructible = trivially_constructible_from>; template concept trivially_move_constructible = trivially_constructible_from>; template concept assignable_from = __is_assignable(T, Args...); template concept copy_assignable = assignable_from, as_lref_t>; template concept move_assignable = assignable_from, as_rref_t>; template concept trivially_assignable_from = __is_trivially_assignable(T, Args...); template concept trivially_copy_assignable = trivially_assignable_from, as_lref_t>; template concept trivially_move_assignable = trivially_assignable_from, as_rref_t>; template concept trivially_destructible = __is_trivially_destructible(T); template concept trivially_copyable = __is_trivially_copyable(T); template concept copyable = copy_constructible && copy_assignable; template concept moveable = move_constructible && move_assignable; template concept convertible_from = __is_convertible(From, To); template concept derived_from = __is_class(Derived) && __is_class(Base) && convertible_from; using nullptr_t = decltype(nullptr); template struct _un_const_helper { using type = T; }; template struct _un_const_helper { using type = T; }; template using un_const_t = _un_const_helper::type; template struct _is_const_helper : false_type {}; template struct _is_const_helper : true_type {}; template concept is_const = _is_const_helper::value; template struct _un_volatile_helper { using type = T; }; template struct _un_volatile_helper { using type = T; }; template using un_volatile_t = _un_volatile_helper::type; template using un_cv_t = un_volatile_t>; template using un_cvref_t = un_ref_t>; template concept is_void = same_as>; template struct _is_ref_helper { static constexpr bool l = false; static constexpr bool r = false; }; template struct _is_ref_helper { static constexpr bool l = true; static constexpr bool r = false; }; template struct _is_ref_helper { static constexpr bool l = false; static constexpr bool r = true; }; template concept is_ref = _is_ref_helper::l || _is_ref_helper::r; template struct _is_ptr_helper : false_type {}; template struct _is_ptr_helper : true_type {}; template concept is_ptr = _is_ptr_helper>::value; template struct _tame_helper { using type = T; }; #define TAME_HELPER_IMPL(TRAILING) \ template \ struct _tame_helper { using type = R(Args...); } TAME_HELPER_IMPL(); TAME_HELPER_IMPL(&); TAME_HELPER_IMPL(&&); TAME_HELPER_IMPL(const); TAME_HELPER_IMPL(const &); TAME_HELPER_IMPL(const &&); TAME_HELPER_IMPL(volatile); TAME_HELPER_IMPL(volatile &); TAME_HELPER_IMPL(volatile &&); TAME_HELPER_IMPL(const volatile); TAME_HELPER_IMPL(const volatile &); TAME_HELPER_IMPL(const volatile &&); TAME_HELPER_IMPL(noexcept); TAME_HELPER_IMPL(& noexcept); TAME_HELPER_IMPL(&& noexcept); TAME_HELPER_IMPL(const noexcept); TAME_HELPER_IMPL(const & noexcept); TAME_HELPER_IMPL(const && noexcept); TAME_HELPER_IMPL(volatile noexcept); TAME_HELPER_IMPL(volatile & noexcept); TAME_HELPER_IMPL(volatile && noexcept); TAME_HELPER_IMPL(const volatile noexcept); TAME_HELPER_IMPL(const volatile & noexcept); TAME_HELPER_IMPL(const volatile && noexcept); #undef TAME_HELPER_IMPL template using tame_t = _tame_helper::type; template struct _is_func_helper : false_type {}; template struct _is_func_helper : true_type {}; template concept is_func = _is_func_helper>::value; template concept is_object = !is_void && !is_ref && !is_func; template struct _is_array_helper : false_type {}; template struct _is_array_helper : true_type {}; template struct _is_array_helper : true_type {}; template concept is_array = _is_array_helper::value; template struct _is_floating_point_helper : false_type {}; template<> struct _is_floating_point_helper : true_type {}; template<> struct _is_floating_point_helper : true_type {}; template concept is_floating_point = _is_floating_point_helper>::value; struct niche {}; template concept has_niche = constructible_from && requires (const T& value, niche n) { { value == n } -> same_as; }; template concept is_niche = same_as, niche>; } // namespace asl