From 79a090af2f2a8feadb404c2d99867cb6999f6ecf Mon Sep 17 00:00:00 2001 From: qicosmos Date: Wed, 11 Sep 2024 17:38:24 +0800 Subject: [PATCH 1/6] simplify --- iguana/ylt/reflection/member_names.hpp | 26 +++++++------------------- test/test_cpp20.cpp | 6 +++--- test/test_xml.cpp | 4 ++-- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/iguana/ylt/reflection/member_names.hpp b/iguana/ylt/reflection/member_names.hpp index 72c94168..6afe7c33 100644 --- a/iguana/ylt/reflection/member_names.hpp +++ b/iguana/ylt/reflection/member_names.hpp @@ -88,8 +88,8 @@ inline constexpr bool has_alias_struct_name_v = has_alias_struct_names_t::value; template -inline constexpr void init_arr_with_tuple(const T& tp, U& arr, - std::index_sequence) { +inline constexpr void init_arr_with_tuple(U& arr, std::index_sequence) { + constexpr auto tp = struct_to_tuple(); ((arr[Is] = internal::get_member_name(tp))>()), ...); } @@ -106,10 +106,9 @@ get_member_names() { return type::refl_member_names(ylt::reflection::identity{}); } else { - constexpr auto tp = struct_to_tuple(); - std::array arr; #if __cplusplus >= 202002L + constexpr auto tp = struct_to_tuple(); [&](std::index_sequence) mutable { ((arr[Is] = internal::get_member_name(tp))>()), @@ -117,7 +116,7 @@ get_member_names() { } (std::make_index_sequence{}); #else - init_arr_with_tuple(tp, arr, std::make_index_sequence{}); + init_arr_with_tuple(arr, std::make_index_sequence{}); #endif return arr; } @@ -210,26 +209,15 @@ inline constexpr size_t index_of() { return names.size(); } -template struct field_alias_t { std::string_view alias_name; - inline static constexpr auto index = Idx; + size_t index; }; -template -inline constexpr auto get_alias_field_names_impl(Tuple& tp, - std::index_sequence) { - return std::array, sizeof...(Is)>{ - std::make_pair(std::tuple_element_t>::index, - std::get(tp).alias_name)...}; -} - template inline constexpr auto get_alias_field_names() { if constexpr (internal::has_alias_field_names_v) { - constexpr auto tp = ylt_alias_struct::get_alias_field_names(); - return get_alias_field_names_impl( - tp, std::make_index_sequence>{}); + return ylt_alias_struct::get_alias_field_names(); } else { return std::array{}; @@ -254,7 +242,7 @@ get_member_names() { if constexpr (internal::has_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].first] = alias_arr[i].second; + arr[alias_arr[i].index] = alias_arr[i].alias_name; } } return arr; diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index 1d915371..41a63623 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -23,7 +23,7 @@ struct ylt::reflection::ylt_alias_struct { static constexpr std::string_view get_alias_struct_name() { return "point"; } static constexpr auto get_alias_field_names() { - return std::make_tuple(field_alias_t<0>{"X"}, field_alias_t<1>{"Y"}); + return std::array{field_alias_t{"X", 0}, field_alias_t{"Y", 1}}; } }; struct test_variant { @@ -253,8 +253,8 @@ TEST_CASE("test xml") { constexpr auto names = ylt::reflection::get_member_names(); constexpr auto st_name = ylt::reflection::get_struct_name(); CHECK(names == std::array{"X", "Y"}); - CHECK(alias_names[0].second == "X"); - CHECK(alias_names[1].second == "Y"); + CHECK(alias_names[0].alias_name == "X"); + CHECK(alias_names[1].alias_name == "Y"); CHECK(st_name == "point"); constexpr auto name1 = ylt::reflection::get_struct_name(); diff --git a/test/test_xml.cpp b/test/test_xml.cpp index cdc63833..3105179e 100644 --- a/test/test_xml.cpp +++ b/test/test_xml.cpp @@ -739,7 +739,7 @@ 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::make_tuple(field_alias_t<0>{"w"}, field_alias_t<1>{"h"}); + return std::array{field_alias_t{"w", 0}, field_alias_t{"h", 1}}; } }; @@ -755,7 +755,7 @@ 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::make_tuple(field_alias_t<0>{"w"}, field_alias_t<1>{"h"}); + return std::array{field_alias_t{"w", 0}, field_alias_t{"h", 1}}; } }; From f38d004dd9845305fc4e39e158c6e8b5d4d790ad Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 12 Sep 2024 14:09:04 +0800 Subject: [PATCH 2/6] use adl function --- iguana/ylt/reflection/member_names.hpp | 55 ++++++++++++++++++++------ test/test_cpp20.cpp | 13 +++--- test/test_xml.cpp | 28 ++++++------- 3 files changed, 62 insertions(+), 34 deletions(-) diff --git a/iguana/ylt/reflection/member_names.hpp b/iguana/ylt/reflection/member_names.hpp index 6afe7c33..4ed2eaa9 100644 --- a/iguana/ylt/reflection/member_names.hpp +++ b/iguana/ylt/reflection/member_names.hpp @@ -64,28 +64,50 @@ struct member_tratis { }; template -struct has_alias_field_names_t : std::false_type {}; +struct has_alias_struct_name_t : std::false_type {}; template -struct has_alias_field_names_t< - T, std::void_t::get_alias_field_names())>> +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 -inline constexpr bool has_alias_field_names_v = - has_alias_field_names_t::value; +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> + : std::true_type {}; 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 +239,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 +252,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 +267,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/test/test_cpp20.cpp b/test/test_cpp20.cpp index 41a63623..0e8e2e58 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -15,17 +15,16 @@ YLT_REFL(point_t, x, y); struct point_t1 { int x; int y; -}; -YLT_REFL(point_t1, x, y); - -template <> -struct ylt::reflection::ylt_alias_struct { - static constexpr std::string_view get_alias_struct_name() { return "point"; } - static constexpr auto get_alias_field_names() { + static constexpr auto get_alias_field_names(point_t1*) { return std::array{field_alias_t{"X", 0}, field_alias_t{"Y", 1}}; } + static constexpr std::string_view get_alias_struct_name(point_t1*) { + return "point"; + } }; +YLT_REFL(point_t1, x, y); + struct test_variant { test_variant() = default; test_variant(int a, std::variant b, double c) diff --git a/test/test_xml.cpp b/test/test_xml.cpp index 3105179e..25be2322 100644 --- a/test/test_xml.cpp +++ b/test/test_xml.cpp @@ -734,14 +734,14 @@ 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"; } +inline constexpr std::string_view get_alias_struct_name(next_obj_t *) { + return "next"; +} - static constexpr auto get_alias_field_names() { - return std::array{field_alias_t{"w", 0}, field_alias_t{"h", 1}}; - } -}; +inline constexpr auto get_alias_field_names(next_obj_t *) { + return std::array{ylt::reflection::field_alias_t{"w", 0}, + ylt::reflection::field_alias_t{"h", 1}}; +} struct out_object { std::unique_ptr id; @@ -750,14 +750,14 @@ 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"; } +inline constexpr std::string_view get_alias_struct_name(out_object *) { + return "qi"; +} - static constexpr auto get_alias_field_names() { - return std::array{field_alias_t{"w", 0}, field_alias_t{"h", 1}}; - } -}; +inline constexpr auto get_alias_field_names(out_object *) { + return std::array{ylt::reflection::field_alias_t{"w", 0}, + ylt::reflection::field_alias_t{"h", 1}}; +} TEST_CASE("test alias") { out_object m{std::make_unique(20), "tom", {21, 42}}; From 0c4cd06d9374763a341ac1f9014cefe524cc302b Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 12 Sep 2024 14:35:00 +0800 Subject: [PATCH 3/6] add missed --- iguana/ylt/reflection/member_count.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/ylt/reflection/member_count.hpp b/iguana/ylt/reflection/member_count.hpp index e323c7ee..3932c580 100644 --- a/iguana/ylt/reflection/member_count.hpp +++ b/iguana/ylt/reflection/member_count.hpp @@ -47,7 +47,7 @@ constexpr bool expected = expected_impl::value; #if __cpp_concepts >= 201907L template -concept optional = requires(Type optional) { +concept optional = !expected && requires(Type optional) { optional.value(); optional.has_value(); optional.operator*(); From 6f45826ca68c232edfe4a1ff78d5f9c8f92e6eb8 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 12 Sep 2024 14:39:20 +0800 Subject: [PATCH 4/6] clean --- iguana/ylt/reflection/member_names.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/iguana/ylt/reflection/member_names.hpp b/iguana/ylt/reflection/member_names.hpp index 4ed2eaa9..e4a8c7bb 100644 --- a/iguana/ylt/reflection/member_names.hpp +++ b/iguana/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(); From 9337df026c2e86eac8b35531b2efed79cb7ee8fb Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 12 Sep 2024 16:50:44 +0800 Subject: [PATCH 5/6] update --- iguana/ylt/reflection/member_count.hpp | 20 +++++++++----------- iguana/ylt/reflection/member_ptr.hpp | 2 +- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/iguana/ylt/reflection/member_count.hpp b/iguana/ylt/reflection/member_count.hpp index 3932c580..83783174 100644 --- a/iguana/ylt/reflection/member_count.hpp +++ b/iguana/ylt/reflection/member_count.hpp @@ -11,7 +11,10 @@ #endif #include "user_reflect_macro.hpp" - +namespace struct_pack { +template +struct compatible; +} namespace ylt::reflection { template using remove_cvref_t = std::remove_cv_t>; @@ -25,9 +28,7 @@ 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 @@ -71,9 +72,8 @@ 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 {}; @@ -87,14 +87,12 @@ template constexpr bool tuple_size = tuple_size_impl::value; #endif -template -struct compatible; - template constexpr inline bool is_compatible_v = false; template -constexpr inline bool is_compatible_v> = true; +constexpr inline bool is_compatible_v> = + true; struct UniversalVectorType { template diff --git a/iguana/ylt/reflection/member_ptr.hpp b/iguana/ylt/reflection/member_ptr.hpp index fec004ec..1fa090e9 100644 --- a/iguana/ylt/reflection/member_ptr.hpp +++ b/iguana/ylt/reflection/member_ptr.hpp @@ -3,7 +3,7 @@ // modified based on: // https://github.com/getml/reflect-cpp/blob/main/include/rfl/internal/bind_fake_object_to_tuple.hpp -// thanks for alxn4's greate idea! +// thanks for alxn4's great idea! namespace ylt::reflection { namespace internal { From dc985865a51e287eb2462573e7ba11b1a0955777 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Fri, 13 Sep 2024 11:47:46 +0800 Subject: [PATCH 6/6] format --- iguana/ylt/reflection/member_count.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/ylt/reflection/member_count.hpp b/iguana/ylt/reflection/member_count.hpp index 83783174..04d12a42 100644 --- a/iguana/ylt/reflection/member_count.hpp +++ b/iguana/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 {};