Separate parameter/variable reflections.

This commit is contained in:
Dan Katz
2025-06-19 19:17:03 +03:00
parent bebe293731
commit 2a631b61e3
13 changed files with 237 additions and 141 deletions

View File

@@ -340,14 +340,12 @@ consteval auto is_entity_proxy(info) -> bool;
// function parameters (P3096)
consteval auto parameters_of(info) -> vector<info>;
consteval auto has_consistent_identifier(info) -> bool;
consteval auto any_identifier_of(info) -> string_view;
consteval auto u8any_identifier_of(info) -> u8string_view;
consteval auto has_ellipsis_parameter(info) -> bool;
consteval auto has_default_argument(info) -> bool;
consteval auto is_explicit_object_parameter(info) -> bool;
consteval auto is_function_parameter(info) -> bool;
consteval auto return_type_of(info) -> info;
consteval auto variable_of(info) -> info;
// annotations (P3394)
consteval auto annotations_of(info) -> vector<info>;
@@ -528,12 +526,12 @@ enum : unsigned {
// P3096 parameter reflection metafunctions
__metafn_get_ith_parameter_of,
__metafn_has_consistent_identifier,
__metafn_has_ellipsis_parameter,
__metafn_has_default_argument,
__metafn_is_explicit_object_parameter,
__metafn_is_function_parameter,
__metafn_return_type_of,
__metafn_variable_of,
// P3394 annotation metafunctions
__metafn_get_ith_annotation_of,
@@ -2082,20 +2080,6 @@ consteval auto parameters_of(info r) -> vector<info> {
return vector<info>{rng.begin(), rng.end()};
}
consteval auto has_consistent_identifier(info r) -> bool {
return __metafunction(detail::__metafn_has_consistent_identifier, r);
}
consteval auto any_identifier_of(info r) -> string_view {
return __metafunction(detail::__metafn_identifier_of, ^^const char *, r,
/*UTF8=*/false, /*EnforceConsistent=*/false);
}
consteval auto u8any_identifier_of(info r) -> u8string_view {
return __metafunction(detail::__metafn_identifier_of, ^^const char8_t *,
r, /*UTF8=*/true, /*EnforceConsistent=*/false);
}
consteval auto has_ellipsis_parameter(info r) -> bool {
return __metafunction(detail::__metafn_has_ellipsis_parameter, r);
}
@@ -2116,6 +2100,10 @@ consteval auto return_type_of(info r) -> info {
return __metafunction(detail::__metafn_return_type_of, r);
}
consteval auto variable_of(info r) -> info {
return __metafunction(detail::__metafn_variable_of, r);
}
#endif // __has_feature(parameter_reflection)
#if __has_feature(annotation_attributes)

View File

@@ -53,17 +53,17 @@ static_assert(parameters_of(type_of(^^fn)) ==
std::vector {^^int, ^^bool, ^^const S<int> &});
static_assert(type_of(parameters_of(^^fn)[0]) == ^^int);
static_assert(identifier_of(parameters_of(^^fn)[0]) == "a");
static_assert(has_consistent_identifier(parameters_of(^^fn)[0]));
static_assert(has_identifier(parameters_of(^^fn)[0]));
static_assert(!has_default_argument(parameters_of(^^fn)[0]));
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[0]));
static_assert(type_of(parameters_of(^^fn)[1]) == ^^bool);
static_assert(identifier_of(parameters_of(^^fn)[1]) == "b");
static_assert(has_consistent_identifier(parameters_of(^^fn)[1]));
static_assert(has_identifier(parameters_of(^^fn)[1]));
static_assert(!has_default_argument(parameters_of(^^fn)[1]));
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[1]));
static_assert(type_of(parameters_of(^^fn)[2]) == ^^const S<int> &);
static_assert(identifier_of(parameters_of(^^fn)[2]) == "s");
static_assert(has_consistent_identifier(parameters_of(^^fn)[2]));
static_assert(has_identifier(parameters_of(^^fn)[2]));
static_assert(!has_default_argument(parameters_of(^^fn)[2]));
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[2]));
static_assert(!has_ellipsis_parameter(^^fn));
@@ -91,7 +91,7 @@ constexpr auto ctor =
static_assert(parameters_of(ctor).size() == 1);
static_assert(type_of(parameters_of(ctor)[0]) == ^^int);
static_assert(identifier_of(parameters_of(ctor)[0]) == "a");
static_assert(has_consistent_identifier(parameters_of(ctor)[0]));
static_assert(has_identifier(parameters_of(ctor)[0]));
static_assert(!has_default_argument(parameters_of(ctor)[0]));
static_assert(!is_explicit_object_parameter(parameters_of(ctor)[0]));
static_assert(!has_ellipsis_parameter(ctor));
@@ -106,12 +106,12 @@ static_assert(parameters_of(^^Cls::fn).size() == 2);
static_assert(parameters_of(type_of(^^Cls::fn)) == std::vector {^^int, ^^bool});
static_assert(type_of(parameters_of(^^Cls::fn)[0]) == ^^int);
static_assert(identifier_of(parameters_of(^^Cls::fn)[0]) == "a");
static_assert(has_consistent_identifier(parameters_of(^^Cls::fn)[0]));
static_assert(has_identifier(parameters_of(^^Cls::fn)[0]));
static_assert(!has_default_argument(parameters_of(^^Cls::fn)[0]));
static_assert(!is_explicit_object_parameter(parameters_of(^^Cls::fn)[0]));
static_assert(type_of(parameters_of(^^Cls::fn)[1]) == ^^bool);
static_assert(identifier_of(parameters_of(^^Cls::fn)[1]) == "b");
static_assert(has_consistent_identifier(parameters_of(^^Cls::fn)[1]));
static_assert(has_identifier(parameters_of(^^Cls::fn)[1]));
static_assert(has_default_argument(parameters_of(^^Cls::fn)[1]));
static_assert(!is_explicit_object_parameter(parameters_of(^^Cls::fn)[1]));
static_assert(!has_ellipsis_parameter(^^Cls::fn));
@@ -123,12 +123,11 @@ static_assert(parameters_of(type_of(^^Cls::fn2)) ==
std::vector {^^Cls &, ^^int});
static_assert(type_of(parameters_of(^^Cls::fn2)[0]) == ^^Cls &);
static_assert(identifier_of(parameters_of(^^Cls::fn2)[0]) == "self");
static_assert(has_consistent_identifier(parameters_of(^^Cls::fn2)[0]));
static_assert(has_identifier(parameters_of(^^Cls::fn2)[0]));
static_assert(!has_default_argument(parameters_of(^^Cls::fn2)[0]));
static_assert(is_explicit_object_parameter(parameters_of(^^Cls::fn2)[0]));
static_assert(type_of(parameters_of(^^Cls::fn2)[1]) == ^^int);
static_assert(!has_identifier(parameters_of(^^Cls::fn2)[1]));
static_assert(has_consistent_identifier(parameters_of(^^Cls::fn2)[1]));
static_assert(!has_default_argument(parameters_of(^^Cls::fn2)[1]));
static_assert(has_ellipsis_parameter(^^Cls::fn2));
static_assert(has_ellipsis_parameter(type_of(^^Cls::fn2)));
@@ -139,7 +138,7 @@ static_assert(parameters_of(^^Cls::sfn).size() == 1);
static_assert(parameters_of(type_of(^^Cls::sfn)) == std::vector {^^int});
static_assert(type_of(parameters_of(^^Cls::sfn)[0]) == ^^int);
static_assert(identifier_of(parameters_of(^^Cls::sfn)[0]) == "a");
static_assert(has_consistent_identifier(parameters_of(^^Cls::sfn)[0]));
static_assert(has_identifier(parameters_of(^^Cls::sfn)[0]));
static_assert(!has_default_argument(parameters_of(^^Cls::sfn)[0]));
static_assert(!is_explicit_object_parameter(parameters_of(^^Cls::sfn)[0]));
static_assert(has_ellipsis_parameter(^^Cls::sfn));
@@ -163,17 +162,17 @@ consteval bool check() {
std::vector {^^int &&, ^^char &&, ^^bool &&});
static_assert(type_of(parameters_of(Fn)[0]) == ^^int &&);
static_assert(identifier_of(parameters_of(Fn)[0]) == "ts");
static_assert(has_consistent_identifier(parameters_of(Fn)[0]));
static_assert(has_identifier(parameters_of(Fn)[0]));
static_assert(!has_default_argument(parameters_of(Fn)[0]));
static_assert(!is_explicit_object_parameter(parameters_of(Fn)[0]));
static_assert(type_of(parameters_of(Fn)[1]) == ^^char &&);
static_assert(identifier_of(parameters_of(Fn)[1]) == "ts");
static_assert(has_consistent_identifier(parameters_of(Fn)[1]));
static_assert(has_identifier(parameters_of(Fn)[1]));
static_assert(!has_default_argument(parameters_of(Fn)[1]));
static_assert(!is_explicit_object_parameter(parameters_of(Fn)[1]));
static_assert(type_of(parameters_of(Fn)[2]) == ^^bool &&);
static_assert(identifier_of(parameters_of(Fn)[2]) == "ts");
static_assert(has_consistent_identifier(parameters_of(Fn)[2]));
static_assert(has_identifier(parameters_of(Fn)[2]));
static_assert(!has_default_argument(parameters_of(Fn)[2]));
static_assert(!is_explicit_object_parameter(parameters_of(Fn)[2]));
static_assert(!has_ellipsis_parameter(Fn));
@@ -199,12 +198,12 @@ static_assert(parameters_of(^^fn).size() == 2);
static_assert(parameters_of(type_of(^^fn)) == std::vector {^^int, ^^bool});
static_assert(type_of(parameters_of(^^fn)[0]) == ^^int);
static_assert(identifier_of(parameters_of(^^fn)[0]) == "a");
static_assert(has_consistent_identifier(parameters_of(^^fn)[0]));
static_assert(has_identifier(parameters_of(^^fn)[0]));
static_assert(!has_default_argument(parameters_of(^^fn)[0]));
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[0]));
static_assert(type_of(parameters_of(^^fn)[1]) == ^^bool);
static_assert(identifier_of(parameters_of(^^fn)[1]) == "b");
static_assert(has_consistent_identifier(parameters_of(^^fn)[1]));
static_assert(has_identifier(parameters_of(^^fn)[1]));
static_assert(has_default_argument(parameters_of(^^fn)[1]));
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[1]));
static_assert(!has_ellipsis_parameter(^^fn));
@@ -217,7 +216,7 @@ static_assert(!has_ellipsis_parameter(type_of(^^fn)));
namespace with_ambiguous_names {
void fn(int a1, bool b, char c1);
static_assert(has_consistent_identifier(parameters_of(^^fn)[2]));
static_assert(has_identifier(parameters_of(^^fn)[2]));
void fn(int a2, bool, char c2);
constexpr auto r_a2 = parameters_of(^^fn)[0];
@@ -230,16 +229,10 @@ constexpr auto r_a3 = parameters_of(^^fn)[0];
static_assert(parameters_of(^^fn).size() == 3);
static_assert(parameters_of(type_of(^^fn)) ==
std::vector {^^int, ^^bool, ^^char});
static_assert(any_identifier_of(parameters_of(^^fn)[0]) == "a1" ||
any_identifier_of(parameters_of(^^fn)[0]) == "a2" ||
any_identifier_of(parameters_of(^^fn)[0]) == "a3");
static_assert(!has_consistent_identifier(parameters_of(^^fn)[0]));
static_assert(any_identifier_of(parameters_of(^^fn)[1]) == "b");
static_assert(!has_identifier(parameters_of(^^fn)[0]));
static_assert(identifier_of(parameters_of(^^fn)[1]) == "b");
static_assert(has_consistent_identifier(parameters_of(^^fn)[1]));
static_assert(any_identifier_of(parameters_of(^^fn)[2]) == "c1" ||
any_identifier_of(parameters_of(^^fn)[2]) == "c2");
static_assert(!has_consistent_identifier(parameters_of(^^fn)[2]));
static_assert(has_identifier(parameters_of(^^fn)[1]));
static_assert(!has_identifier(parameters_of(^^fn)[2]));
static_assert(r_a2 == r_a3);
} // namespace with_ambiguous_names
@@ -289,4 +282,25 @@ void user(int) {
}
} // namespace mangle_reflection_of_function_parameter
// =================
// variable_of_tests
// =================
namespace variable_of_tests {
consteval int fn(int p) {
constexpr auto rp = parameters_of(^^fn)[0];
constexpr auto rv = variable_of(rp);
static_assert(is_function_parameter(rp));
static_assert(!is_function_parameter(rv));
static_assert(!is_variable(rp));
static_assert(is_variable(rv));
static_assert(^^p == rv);
return [:variable_of(parameters_of(^^fn)[0]):];
}
static_assert(fn(42) == 42);
} // namespace variable_of_tests
int main() { }