From adbd25f5f8bdf2e8be663fbeeb345059ae7d99a8 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Mon, 7 Sep 2026 16:56:30 -0400 Subject: [PATCH] Check static properties with a single probe template `is_consteval` and the `static_prop` concept split one question into two checks that every call site had to run in sequence, once to confirm the member had the exact declared type and again to confirm its value was a constant expression. `static_prop_probe` answers both at once. Passing `X::member` as an `auto` non-type argument already requires a constant expression, and `is_same_v` pins the type exactly, since `auto` deduction drops the `const` that an implicit conversion would otherwise hide. Each call site loses a nested `if constexpr`. `is_is_direct_well_formed` reduced to a single requirement and folded into the `requires` blocks of `basic_convention` and `basic_reflection`, its only two callers. --- include/proxy/v4/detail/core.h | 71 +++++++++++++--------------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/include/proxy/v4/detail/core.h b/include/proxy/v4/detail/core.h index 4262904..12d7469 100644 --- a/include/proxy/v4/detail/core.h +++ b/include/proxy/v4/detail/core.h @@ -139,25 +139,21 @@ template using merge_tuples_t = flattening_merge_t, Tss...>; -template -consteval bool is_consteval(Expr) { - return requires { typename std::bool_constant<(Expr{}(), false)>; }; -} -template -concept static_prop = std::is_same_v; +template + requires(std::is_same_v) +struct static_prop_probe; template concept has_tuple_element = requires { typename std::tuple_element_t; }; template consteval bool is_tuple_like_well_formed() { if constexpr (requires { - { std::tuple_size::value } -> static_prop; + typename static_prop_probe::value>; }) { - if constexpr (is_consteval([] { return std::tuple_size::value; })) { - return [](std::index_sequence) { - return (has_tuple_element && ...); - }(std::make_index_sequence>{}); - } + return [](std::index_sequence) { + return (has_tuple_element && ...); + }(std::make_index_sequence>{}); } return false; } @@ -489,25 +485,12 @@ consteval void diagnose_proxiable_required_convention_not_implemented() { "not proxiable due to a required convention not implemented"); } -template -consteval bool is_is_direct_well_formed() { - if constexpr (requires { - { T::is_direct } -> static_prop; - }) { - if constexpr (is_consteval([] { return T::is_direct; })) { - return true; - } - } - return false; -} - template -concept basic_convention = - requires { - { typename C::dispatch_type() } noexcept; - typename C::overload_type; - } && is_is_direct_well_formed() && - extended_overload; +concept basic_convention = requires { + { typename C::dispatch_type() } noexcept; + typename C::overload_type; + typename static_prop_probe; +} && extended_overload; template concept basic_meta = @@ -521,7 +504,8 @@ concept meta = basic_meta && template concept basic_reflection = requires { typename R::reflector_type; -} && is_is_direct_well_formed() && basic_meta; + typename static_prop_probe; +} && basic_meta; template struct a11y_traits_impl @@ -808,21 +792,18 @@ consteval bool is_cl_well_formed(constraint_level cl) { template consteval bool is_facade_constraints_well_formed() { if constexpr (requires { - { F::max_size } -> static_prop; - { F::max_align } -> static_prop; - { F::copyability } -> static_prop; - { F::relocatability } -> static_prop; - { F::destructibility } -> static_prop; + typename static_prop_probe; + typename static_prop_probe; + typename static_prop_probe; + typename static_prop_probe; + typename static_prop_probe; }) { - if constexpr (is_consteval([] { - return std::tuple{F::max_size, F::max_align, F::copyability, - F::relocatability, F::destructibility}; - })) { - return is_layout_well_formed(F::max_size, F::max_align) && - is_cl_well_formed(F::copyability) && - is_cl_well_formed(F::relocatability) && - is_cl_well_formed(F::destructibility); - } + return is_layout_well_formed(F::max_size, F::max_align) && + is_cl_well_formed(F::copyability) && + is_cl_well_formed(F::relocatability) && + is_cl_well_formed(F::destructibility); } return false; }