#pragma once namespace asl { template struct id { using type = T; }; 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 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 concept constructible = __is_constructible(T, Args...); template concept default_constructible = constructible; template concept copy_constructible = constructible>; template concept move_constructible = constructible>; template concept trivially_constructible = __is_trivially_constructible(T, Args...); template concept trivially_default_constructible = trivially_constructible; template concept trivially_copy_constructible = trivially_constructible>; template concept trivially_move_constructible = trivially_constructible>; template concept assignable = __is_assignable(T, Args...); template concept copy_assignable = assignable, as_lref_t>; template concept move_assignable = assignable, as_rref_t>; template concept trivially_assignable = __is_trivially_assignable(T, Args...); template concept trivially_copy_assignable = trivially_assignable, as_lref_t>; template concept trivially_move_assignable = trivially_assignable, as_rref_t>; template concept trivially_destructible = __is_trivially_destructible(T); using nullptr_t = decltype(nullptr); template struct un_ref { using type = T; }; template struct un_ref { using type = T; }; template struct un_ref { using type = T; }; template using un_ref_t = un_ref::type; template struct un_const { using type = T; }; template struct un_const { using type = T; }; template using un_const_t = un_const::type; template struct un_volatile { using type = T; }; template struct un_volatile { using type = T; }; template using un_volatile_t = un_volatile::type; template using un_qual_t = un_const_t>; template using un_qualref_t = un_qual_t>; template struct _is_same_helper : false_type {}; template struct _is_same_helper : true_type {}; template concept is_same = _is_same_helper::value && _is_same_helper::value; template struct _is_const_helper : false_type {}; template struct _is_const_helper : true_type {}; template concept is_const = _is_const_helper::value; template concept is_void = is_same, void>; template concept is_nullptr = is_same, nullptr_t>; template concept is_integral = __is_integral(T); template concept is_floating_point = __is_floating_point(T); template concept is_arithmetic = is_integral || is_floating_point; 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 concept is_class = __is_class(T); template concept is_union = __is_union(T); template concept is_enum = __is_enum(T); template struct _is_ptr_helper : false_type {}; template struct _is_ptr_helper : true_type {}; template concept is_ptr = _is_ptr_helper>::value; template struct _is_ref_helper { static constexpr bool lref = false; static constexpr bool rref = false; }; template struct _is_ref_helper { static constexpr bool lref = true; static constexpr bool rref = false; }; template struct _is_ref_helper { static constexpr bool lref = false; static constexpr bool rref = true; }; template concept is_lref = _is_ref_helper::lref; template concept is_rref = _is_ref_helper::rref; template concept is_ref = is_lref || is_rref; template concept is_func = !is_const && !is_ref; template struct _is_member_ptr_helper : false_type {}; template struct _is_member_ptr_helper : true_type {}; template struct _is_member_func_ptr_helper : false_type {}; template struct _is_member_func_ptr_helper : bool_constant> {}; template concept is_member_ptr = _is_member_ptr_helper>::value; template concept is_member_func_ptr = _is_member_func_ptr_helper>::value; template concept is_member_object_ptr = is_member_ptr && !is_member_func_ptr; template concept is_fundamental = is_arithmetic || is_void || is_nullptr; template concept is_compound = !is_fundamental; template concept is_scalar = (is_fundamental && !is_void) || is_enum || is_ptr || is_member_ptr; template concept is_object = is_scalar || is_class || is_union; template concept is_empty = is_void || __is_empty(T); struct empty {}; template using devoid_t = select_t, empty, T>; template struct _tame_helper { using type = F; }; #define ASL_TAME_IMPL(SUFFIX) \ template \ struct _tame_helper { using type = Ret(Args...); } ASL_TAME_IMPL(); ASL_TAME_IMPL(const); ASL_TAME_IMPL(volatile); ASL_TAME_IMPL(volatile const); ASL_TAME_IMPL(&&); ASL_TAME_IMPL(const &&); ASL_TAME_IMPL(volatile &&); ASL_TAME_IMPL(volatile const &&); ASL_TAME_IMPL(&); ASL_TAME_IMPL(const &); ASL_TAME_IMPL(volatile &); ASL_TAME_IMPL(volatile const &); ASL_TAME_IMPL(noexcept); ASL_TAME_IMPL(const noexcept); ASL_TAME_IMPL(volatile noexcept); ASL_TAME_IMPL(volatile const noexcept); ASL_TAME_IMPL(&& noexcept); ASL_TAME_IMPL(const && noexcept); ASL_TAME_IMPL(volatile && noexcept); ASL_TAME_IMPL(volatile const && noexcept); ASL_TAME_IMPL(& noexcept); ASL_TAME_IMPL(const & noexcept); ASL_TAME_IMPL(volatile & noexcept); ASL_TAME_IMPL(volatile const & noexcept); #undef ASL_TAME_IMPL template using tame_t = _tame_helper::type; template using as_raw_ptr_t = un_ref_t>*; } // namespace asl