From 96f096465dad4aa24e6129bad29ab84c981d24c1 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Sun, 28 Apr 2024 18:03:42 +0800 Subject: [PATCH 1/4] name_of member --- iguana/detail/traits.hpp | 10 +++++++- iguana/reflection.hpp | 49 ++++++++++++++++++++++++++++++++++++++++ test/test.cpp | 18 +++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/iguana/detail/traits.hpp b/iguana/detail/traits.hpp index d3b9aac8..64f082e0 100644 --- a/iguana/detail/traits.hpp +++ b/iguana/detail/traits.hpp @@ -15,7 +15,6 @@ #include "iguana/define.h" - namespace iguana { template @@ -68,6 +67,15 @@ template struct has_type> : std::disjunction...> {}; +template +struct member_tratis {}; + +template +struct member_tratis { + using owner_type = Owner; + using value_type = T; +}; + template inline constexpr bool is_int64_v = std::is_same_v || std::is_same_v; diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index 41e15423..be71b2c1 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -910,6 +910,55 @@ constexpr const std::string_view get_name() { return M::name(); } +namespace detail { +template +constexpr bool get_index_imple() { + if constexpr (std::is_same_v< + typename member_tratis::value_type, + typename member_tratis::value_type>) { + if constexpr (ele == ptr) { + return true; + } + else { + return false; + } + } + else { + return false; + } +} + +#define member_index(ptr, tp, size) \ + [&](std::index_sequence) { \ + bool r = false; \ + size_t index = 0; \ + ((!r && (r = detail::get_index_imple(tp)>(), \ + !r ? index++ : index, true)), \ + ...); \ + return index; \ + } \ + (std::make_index_sequence{}); +} // namespace detail + +template +constexpr size_t index_of() { + using T = typename member_tratis::owner_type; + using M = Reflect_members; + constexpr auto tp = M::apply_impl(); + constexpr size_t Size = std::tuple_size_v; + constexpr size_t index = member_index(member, tp, Size); + static_assert(index < Size, "out of range"); + return index; +} + +template +constexpr auto name_of() { + using T = typename member_tratis::owner_type; + using M = Reflect_members; + constexpr auto s = M::arr()[index_of()]; + return std::string_view(s.data(), s.size()); +} + template constexpr const std::string_view get_fields() { using M = Reflect_members; diff --git a/test/test.cpp b/test/test.cpp index c3d75691..36ae5cde 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -821,6 +821,24 @@ TEST_CASE("parse some other char") { CHECK(p.name == "tom"); } +TEST_CASE("index_of name_of") { + constexpr size_t idx1 = iguana::index_of<&point_t::y>(); + static_assert(idx1 == 1); + constexpr size_t idx2 = iguana::index_of<&person::name>(); + static_assert(idx2 == 0); + + CHECK(idx1 == 1); + CHECK(idx2 == 0); + + constexpr auto s1 = iguana::name_of<&point_t::y>(); + static_assert(s1 == "y"); + constexpr auto s2 = iguana::name_of<&person::name>(); + static_assert(s2 == "name"); + + CHECK(s1 == "y"); + CHECK(s2 == "name"); +} + TEST_CASE("check some types") { using value_type = std::variant; constexpr auto map = iguana::get_iguana_struct_map(); From 6ea8972d0fd9ef96d7f21d58bcb1953e743aa814 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 29 Apr 2024 10:13:36 +0800 Subject: [PATCH 2/4] cpp17 --- iguana/reflection.hpp | 60 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index be71b2c1..a940631f 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -911,6 +911,7 @@ constexpr const std::string_view get_name() { } namespace detail { +#if __cplusplus < 201703L template constexpr bool get_index_imple() { if constexpr (std::is_same_v< @@ -928,25 +929,62 @@ constexpr bool get_index_imple() { } } -#define member_index(ptr, tp, size) \ - [&](std::index_sequence) { \ - bool r = false; \ - size_t index = 0; \ - ((!r && (r = detail::get_index_imple(tp)>(), \ - !r ? index++ : index, true)), \ - ...); \ - return index; \ - } \ - (std::make_index_sequence{}); +#define member_index(ptr, tp) \ + [&](std::index_sequence) { \ + bool r = false; \ + size_t index = 0; \ + ((void)(!r && (r = detail::get_index_imple(tp)>(), \ + !r ? index++ : index, true)), \ + ...); \ + return index; \ + } \ + (std::make_index_sequence>{}); +#else +constexpr bool get_index_imple(auto ptr, auto ele) { + if constexpr (std::is_same_v< + typename iguana::member_tratis::value_type, + typename iguana::member_tratis< + decltype(ele)>::value_type>) { + if (ele == ptr) { + return true; + } + else { + return false; + } + } + else { + return false; + } +} + +template +constexpr size_t member_index_impl(auto ptr, auto &tp, + std::index_sequence) { + bool r = false; + size_t index = 0; + ((void)(!r && (r = get_index_imple(ptr, std::get(tp)), + !r ? index++ : index, true)), + ...); + return index; +} + +constexpr size_t member_index(auto ptr, auto &tp) { + return member_index_impl( + ptr, tp, + std::make_index_sequence< + std::tuple_size_v>>{}); +} +#endif } // namespace detail template constexpr size_t index_of() { + using namespace detail; using T = typename member_tratis::owner_type; using M = Reflect_members; constexpr auto tp = M::apply_impl(); constexpr size_t Size = std::tuple_size_v; - constexpr size_t index = member_index(member, tp, Size); + constexpr size_t index = member_index(member, tp); static_assert(index < Size, "out of range"); return index; } From 91398aaf1b982c59d0e6451097fcc1e1e09d46ff Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 29 Apr 2024 10:16:31 +0800 Subject: [PATCH 3/4] 17 --- iguana/reflection.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index a940631f..efe303e3 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -940,7 +940,8 @@ constexpr bool get_index_imple() { } \ (std::make_index_sequence>{}); #else -constexpr bool get_index_imple(auto ptr, auto ele) { +template +constexpr bool get_index_imple(T ptr, U ele) { if constexpr (std::is_same_v< typename iguana::member_tratis::value_type, typename iguana::member_tratis< @@ -957,8 +958,8 @@ constexpr bool get_index_imple(auto ptr, auto ele) { } } -template -constexpr size_t member_index_impl(auto ptr, auto &tp, +template +constexpr size_t member_index_impl(T ptr, Tuple &tp, std::index_sequence) { bool r = false; size_t index = 0; @@ -968,7 +969,8 @@ constexpr size_t member_index_impl(auto ptr, auto &tp, return index; } -constexpr size_t member_index(auto ptr, auto &tp) { +template +constexpr size_t member_index(T ptr, Tuple &tp) { return member_index_impl( ptr, tp, std::make_index_sequence< From adfeb212082455a79c38f9cd9a98e0ad86bfa783 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 29 Apr 2024 10:24:42 +0800 Subject: [PATCH 4/4] for msvc --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48632f60..c6482c1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++20") add_compile_options(/utf-8) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) +add_compile_options("$<$:/bigobj>") +add_compile_options("$<$:/Zc:__cplusplus>") else() if(NOT LINKLIBC++)