#pragma once // IWYU pragma: private, include "rlbox.hpp" // IWYU pragma: friend "rlbox_.*\.hpp" #include #include "rlbox_types.hpp" namespace rlbox::detail { #define rlbox_generate_wrapper_check(name) \ namespace detail_rlbox_is_##name \ { \ template \ struct unwrapper : std::false_type \ {}; \ \ template \ struct unwrapper> : std::true_type \ {}; \ } \ \ template \ constexpr bool rlbox_is_##name##_v = \ detail_rlbox_is_##name::unwrapper::value; \ RLBOX_REQUIRE_SEMI_COLON rlbox_generate_wrapper_check(tainted); rlbox_generate_wrapper_check(tainted_volatile); rlbox_generate_wrapper_check(tainted_opaque); rlbox_generate_wrapper_check(sandbox_callback); #undef rlbox_generate_wrapper_check namespace detail_rlbox_is_tainted_boolean_hint { template struct unwrapper : std::false_type {}; template<> struct unwrapper : std::true_type {}; } template constexpr bool rlbox_is_tainted_boolean_hint_v = detail_rlbox_is_tainted_boolean_hint::unwrapper::value; template constexpr bool rlbox_is_tainted_or_vol_v = rlbox_is_tainted_v || rlbox_is_tainted_volatile_v; template constexpr bool rlbox_is_tainted_or_opaque_v = rlbox_is_tainted_v || rlbox_is_tainted_opaque_v; // tainted_hint is NOT considered a wrapper type... This carries no particular // significant and is just a convention choice template constexpr bool rlbox_is_wrapper_v = rlbox_is_tainted_v || rlbox_is_tainted_volatile_v || rlbox_is_tainted_opaque_v || rlbox_is_sandbox_callback_v; namespace detail_rlbox_remove_wrapper { template struct unwrapper { using type = T; using type_sbx = void; }; template struct unwrapper> { using type = T; using type_sbx = T_Sbx; }; template struct unwrapper> { using type = T; using type_sbx = T_Sbx; }; template struct unwrapper> { using type = T; using type_sbx = T_Sbx; }; template struct unwrapper> { using type = T; using type_sbx = T_Sbx; }; } template using rlbox_remove_wrapper_t = typename detail_rlbox_remove_wrapper::unwrapper::type; template using rlbox_get_wrapper_sandbox_t = typename detail_rlbox_remove_wrapper::unwrapper::type_sbx; template using rlbox_tainted_opaque_to_tainted_t = std::conditional_t, tainted, T_Sbx>, T>; // https://stackoverflow.com/questions/34974844/check-if-a-type-is-from-a-particular-namespace namespace detail_is_member_of_rlbox_detail { template struct is_member_of_rlbox_detail_helper : std::false_type {}; template struct is_member_of_rlbox_detail_helper< T, decltype(struct_is_member_of_rlbox_detail(std::declval()))> : std::true_type {}; } template void struct_is_member_of_rlbox_detail(T&&); template constexpr auto is_member_of_rlbox_detail = detail_is_member_of_rlbox_detail::is_member_of_rlbox_detail_helper::value; // https://stackoverflow.com/questions/9644477/how-to-check-whether-a-class-has-specified-nested-class-definition-or-typedef-in namespace detail_has_member_using_can_grant_deny_access { template struct has_member_using_can_grant_deny_access : std::false_type {}; template struct has_member_using_can_grant_deny_access< T, std::void_t> : std::true_type {}; } template constexpr bool has_member_using_can_grant_deny_access_v = detail_has_member_using_can_grant_deny_access:: has_member_using_can_grant_deny_access::value; }