#pragma once // IWYU pragma: private, include "rlbox.hpp" // IWYU pragma: friend "rlbox_.*\.hpp" #include #include namespace rlbox::detail { #define RLBOX_ENABLE_IF(...) std::enable_if_t<__VA_ARGS__>* = nullptr template constexpr bool true_v = true; template constexpr bool is_fundamental_or_enum_v = std::is_fundamental_v || std::is_enum_v; template constexpr bool is_basic_type_v = std::is_fundamental_v || std::is_enum_v || std::is_pointer_v; template using valid_return_t = std::conditional_t, void*, std::decay_t>; template using valid_param_t = std::conditional_t, void*, T>; namespace func_first_arg_detail { template Arg func_first_arg_t_helper(Ret (*)(Arg, Rest...)); template Arg func_first_arg_t_helper(Ret (F::*)(Arg, Rest...)); template Arg func_first_arg_t_helper(Ret (F::*)(Arg, Rest...) const); template decltype(func_first_arg_t_helper(&F::operator())) first_argument_helper(F); } template using func_first_arg_t = decltype(func_first_arg_detail::first_argument_helper(std::declval())); namespace func_arg_nums_v_detail { template constexpr size_t helper_two(T_Ret (*)(T_Args...)) { return sizeof...(T_Args); } template constexpr size_t helper() { constexpr T_Func* ptr = nullptr; return helper_two(ptr); } } template constexpr size_t func_arg_nums_v = func_arg_nums_v_detail::helper(); template using valid_array_el_t = std::conditional_t || std::is_function_v, int, T>; template constexpr bool is_func_ptr_v = (std::is_pointer_v && std::is_function_v>) || std::is_member_function_pointer_v; template constexpr bool is_func_or_func_ptr = std::is_function_v || is_func_ptr_v; template constexpr bool is_one_level_ptr_v = std::is_pointer_v && !std::is_pointer_v>; template using add_const_if_this_const_t = std::conditional_t>, std::add_const_t, T_Target>; template using remove_const_from_pointer = std::conditional_t< std::is_pointer_v, std::add_pointer_t>>, T>; template using add_const_from_pointer = std::conditional_t< std::is_pointer_v, std::remove_pointer_t>>, T>; template using remove_cv_ref_t = std::remove_cv_t>; template using c_to_std_array_t = std::conditional_t, std::array, std::extent_v>, T>; namespace std_array_to_c_arr_detail { template struct W { using type = T; }; template W std_array_to_c_arr_helper(std::array); template W std_array_to_c_arr_helper(T&&); } template using std_array_to_c_arr_t = typename decltype(std_array_to_c_arr_detail::std_array_to_c_arr_helper( std::declval()))::type; template using dereference_result_t = std::conditional_t, std::remove_pointer_t, std::remove_extent_t> // is_array >; template using value_type_t = std::conditional_t, c_to_std_array_t, T>; template using function_ptr_t = std::conditional_t && std::is_function_v>, T, int (*)(int)>; namespace is_c_or_std_array_detail { template struct is_c_or_std_array_helper; template struct is_c_or_std_array_helper>> : std::true_type {}; template std::true_type is_std_array_helper(std::array*); template std::false_type is_std_array_helper(T*); template constexpr bool is_std_array_v = decltype(is_std_array_helper(std::declval>()))::value; template struct is_c_or_std_array_helper>> : std::true_type {}; template struct is_c_or_std_array_helper< T, std::enable_if_t && !is_std_array_v>> : std::false_type {}; } template constexpr bool is_std_array_v = is_c_or_std_array_detail::is_std_array_v; template constexpr bool is_c_or_std_array_v = is_c_or_std_array_detail::is_c_or_std_array_helper::value; namespace std_array_el_detail { template struct W { using type = T; }; template W is_std_array_helper(std::array*); template W is_std_array_helper(T*); template using std_array_el_t = decltype(std_array_el_detail::is_std_array_helper( std::declval>)); } template using std_array_el_t = typename std_array_el_detail::std_array_el_t::type; namespace all_extents_same_detail { template struct all_extents_same_helper; template struct all_extents_same_helper< T1, T2, std::enable_if_t != std::rank_v>> : std::false_type {}; template struct all_extents_same_helper< T1, T2, std::enable_if_t == std::rank_v && !std::is_array_v && !std::is_array_v>> : std::true_type {}; template struct all_extents_same_helper< T1, T2, std::enable_if_t == std::rank_v && std::is_array_v && std::is_array_v && std::extent_v != std::extent_v>> : std::false_type {}; template struct all_extents_same_helper< T1, T2, std::enable_if_t == std::rank_v && std::is_array_v && std::is_array_v && std::extent_v == std::extent_v>> { static constexpr bool value = all_extents_same_helper, std::remove_extent_t>::value; }; } template constexpr bool all_extents_same = all_extents_same_detail::all_extents_same_helper::value; // remove all pointers/extent types namespace remove_all_pointers_detail { template struct remove_all_pointers { typedef T type; }; template struct remove_all_pointers { typedef typename remove_all_pointers::type type; }; } template using remove_all_pointers_t = typename remove_all_pointers_detail::remove_all_pointers::type; // remove all pointers/extent types namespace base_type_detail { template struct base_type { typedef T type; }; template struct base_type { typedef typename base_type::type type; }; template struct base_type { typedef typename base_type::type type; }; template struct base_type { typedef typename base_type::type type; }; } template using base_type_t = typename base_type_detail::base_type::type; // convert types namespace convert_detail { template struct convert_base_types_t_helper; template struct convert_base_types_t_helper< T, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType, std::enable_if_t && !std::is_const_v>> { using type = T_ShortType; }; template struct convert_base_types_t_helper< T, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType, std::enable_if_t && !std::is_const_v>> { using type = T_IntType; }; template struct convert_base_types_t_helper< T, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType, std::enable_if_t && !std::is_const_v>> { using type = T_LongType; }; template struct convert_base_types_t_helper< T, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType, std::enable_if_t && !std::is_const_v>> { using type = T_LongLongType; }; template struct convert_base_types_t_helper< T, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType, std::enable_if_t && !std::is_const_v>> { using type = T_PointerType; }; template struct convert_base_types_t_helper< T, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType, std::enable_if_t && !std::is_same_v && !std::is_same_v && !std::is_const_v && !std::is_enum_v>> { using type = std::make_unsigned_t< typename convert_base_types_t_helper, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType>::type>; }; template struct convert_base_types_t_helper< T, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType, std::enable_if_t<( std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_floating_point_v || std::is_enum_v)&&!std::is_const_v>> { using type = T; }; template struct convert_base_types_t_helper< T, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType, std::enable_if_t && !std::is_const_v>> { using type = typename convert_base_types_t_helper< std::remove_extent_t, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType>::type[std::extent_v]; }; template struct convert_base_types_t_helper>> { using type = std::add_const_t< typename convert_base_types_t_helper, T_ShortType, T_IntType, T_LongType, T_LongLongType, T_PointerType>::type>; }; } template using convert_base_types_t = typename convert_detail::convert_base_types_t_helper::type; namespace unsigned_int_of_size_t_detail { template struct unsigned_int_of_size_t_helper; template struct unsigned_int_of_size_t_helper> { using type = uint8_t; }; template struct unsigned_int_of_size_t_helper> { using type = uint16_t; }; template struct unsigned_int_of_size_t_helper> { using type = uint32_t; }; template struct unsigned_int_of_size_t_helper> { using type = uint64_t; }; } template using unsigned_int_of_size_t = typename unsigned_int_of_size_t_detail::unsigned_int_of_size_t_helper< T>::type; }