From b8a60601761bdf9d2d59091acb445cca41bbcdd4 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Fri, 13 Sep 2024 16:13:17 +0800 Subject: [PATCH] get alias name by adl (#773) --- include/ylt/reflection/member_count.hpp | 9 ++-- include/ylt/reflection/member_names.hpp | 58 ++++++++++++++++++------- src/struct_xml/examples/main.cpp | 28 +++++------- 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/include/ylt/reflection/member_count.hpp b/include/ylt/reflection/member_count.hpp index 83783174..04d12a42 100644 --- a/include/ylt/reflection/member_count.hpp +++ b/include/ylt/reflection/member_count.hpp @@ -28,7 +28,9 @@ concept expected = requires(Type e) { e.has_value(); e.error(); requires std::is_same_v::value_type> || - requires(Type e) { e.value(); }; + requires(Type e) { + e.value(); + }; }; #else template @@ -72,8 +74,9 @@ constexpr bool optional = !expected && optional_impl::value; namespace internal { #if __cpp_concepts >= 201907L template -concept tuple_size = - requires(Type tuple) { std::tuple_size>::value; }; +concept tuple_size = requires(Type tuple) { + std::tuple_size>::value; +}; #else template struct tuple_size_impl : std::false_type {}; diff --git a/include/ylt/reflection/member_names.hpp b/include/ylt/reflection/member_names.hpp index 6afe7c33..e4a8c7bb 100644 --- a/include/ylt/reflection/member_names.hpp +++ b/include/ylt/reflection/member_names.hpp @@ -7,9 +7,6 @@ namespace ylt::reflection { -template -struct ylt_alias_struct; - template inline constexpr auto get_alias_field_names(); @@ -63,29 +60,51 @@ struct member_tratis { using value_type = T; }; +template +struct has_alias_struct_name_t : std::false_type {}; + +template +struct has_alias_struct_name_t< + T, std::void_t> + : std::true_type {}; + +template +struct has_inner_alias_struct_name_t : std::false_type {}; + +template +struct has_inner_alias_struct_name_t< + T, std::void_t> + : std::true_type {}; + +template +constexpr bool has_alias_struct_name_v = has_alias_struct_name_t::value; + +template +constexpr bool has_inner_alias_struct_name_v = + has_inner_alias_struct_name_t::value; + template struct has_alias_field_names_t : std::false_type {}; template struct has_alias_field_names_t< - T, std::void_t::get_alias_field_names())>> + T, std::void_t> : std::true_type {}; -template -inline constexpr bool has_alias_field_names_v = - has_alias_field_names_t::value; - template -struct has_alias_struct_names_t : std::false_type {}; +struct has_inner_alias_field_names_t : std::false_type {}; template -struct has_alias_struct_names_t< - T, std::void_t::get_alias_struct_name())>> +struct has_inner_alias_field_names_t< + T, std::void_t> : std::true_type {}; template -inline constexpr bool has_alias_struct_name_v = - has_alias_struct_names_t::value; +constexpr bool has_alias_field_names_v = has_alias_field_names_t::value; + +template +constexpr bool has_inner_alias_field_names_v = + has_inner_alias_field_names_t::value; template inline constexpr void init_arr_with_tuple(U& arr, std::index_sequence) { @@ -217,7 +236,10 @@ struct field_alias_t { template inline constexpr auto get_alias_field_names() { if constexpr (internal::has_alias_field_names_v) { - return ylt_alias_struct::get_alias_field_names(); + return get_alias_field_names((T*)nullptr); + } + else if constexpr (internal::has_inner_alias_field_names_v) { + return T::get_alias_field_names((T*)nullptr); } else { return std::array{}; @@ -227,7 +249,10 @@ inline constexpr auto get_alias_field_names() { template constexpr std::string_view get_struct_name() { if constexpr (internal::has_alias_struct_name_v) { - return ylt_alias_struct::get_alias_struct_name(); + return get_alias_struct_name((T*)nullptr); + } + else if constexpr (internal::has_inner_alias_struct_name_v) { + return T::get_alias_struct_name((T*)nullptr); } else { return type_string(); @@ -239,7 +264,8 @@ inline constexpr std::array> get_member_names() { auto arr = internal::get_member_names(); using U = ylt::reflection::remove_cvref_t; - if constexpr (internal::has_alias_field_names_v) { + if constexpr (internal::has_alias_field_names_v || + internal::has_inner_alias_field_names_v) { constexpr auto alias_arr = get_alias_field_names(); for (size_t i = 0; i < alias_arr.size(); i++) { arr[alias_arr[i].index] = alias_arr[i].alias_name; diff --git a/src/struct_xml/examples/main.cpp b/src/struct_xml/examples/main.cpp index dba3a8f5..ed0c1198 100644 --- a/src/struct_xml/examples/main.cpp +++ b/src/struct_xml/examples/main.cpp @@ -291,14 +291,13 @@ struct next_obj_t { }; YLT_REFL(next_obj_t, x, y); -template <> -struct ylt::reflection::ylt_alias_struct { - static constexpr std::string_view get_alias_struct_name() { return "next"; } - - static constexpr auto get_alias_field_names() { - return std::array{field_alias_t{"w", 0}, field_alias_t{"h", 1}}; - } -}; +constexpr std::string_view get_alias_struct_name(next_obj_t *) { + return "next"; +} +constexpr auto get_alias_field_names(next_obj_t *) { + using namespace ylt::reflection; + return std::array{field_alias_t{"w", 0}, field_alias_t{"h", 1}}; +} struct out_object { std::unique_ptr id; @@ -307,14 +306,11 @@ struct out_object { }; YLT_REFL(out_object, id, name, obj); -template <> -struct ylt::reflection::ylt_alias_struct { - static constexpr std::string_view get_alias_struct_name() { return "qi"; } - - static constexpr auto get_alias_field_names() { - return std::array{field_alias_t{"i", 0}, field_alias_t{"na", 1}}; - } -}; +constexpr std::string_view get_alias_struct_name(out_object *) { return "qi"; } +constexpr auto get_alias_field_names(out_object *) { + using namespace ylt::reflection; + return std::array{field_alias_t{"i", 0}, field_alias_t{"na", 1}}; +} void test_alias() { out_object m{std::make_unique(20), "tom", {21, 42}};