From 41baccebd5e418f3bd787d63b2c5ea35c913927d Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 22 Aug 2024 16:33:58 +0800 Subject: [PATCH 01/44] json writer --- CMakeLists.txt | 5 ++- iguana/json_writer.hpp | 34 ++++++++------------ iguana/util.hpp | 9 ++++++ iguana/ylt/reflection/member_value.hpp | 11 +++++-- iguana/ylt/reflection/user_reflect_macro.hpp | 5 ++- test/test_cpp20.cpp | 26 +++++++++++++++ 6 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 test/test_cpp20.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ed7ad81b..45206a72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,7 @@ set(TEST_UTIL test/test_util.cpp) set(TEST_XMLNOTHROW test/test_xml_nothrow.cpp) set(TEST_PB test/test_pb.cpp) set(TEST_PROTO test/test_proto3.cpp) +set(TEST_CPP20 test/test_cpp20.cpp) set(PB_BENCHMARK benchmark/pb_benchmark.cpp) add_executable(json_example ${JSON_EXAMPLE}) @@ -105,6 +106,7 @@ add_executable(yaml_benchmark ${YAMLBENCH}) add_executable(test_nothrow ${TEST_NOTHROW}) add_executable(test_util ${TEST_UTIL}) add_executable(test_pb ${TEST_PB}) +add_executable(test_cpp20 ${TEST_CPP20}) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 9) @@ -166,4 +168,5 @@ add_test(NAME test_yaml COMMAND test_yaml) add_test(NAME test_nothrow COMMAND test_nothrow) add_test(NAME test_util COMMAND test_util) add_test(NAME test_xml_nothrow COMMAND test_xml_nothrow) -add_test(NAME test_pb COMMAND test_pb) \ No newline at end of file +add_test(NAME test_pb COMMAND test_pb) +add_test(NAME test_cpp20 COMMAND test_cpp20) diff --git a/iguana/json_writer.hpp b/iguana/json_writer.hpp index 498e0a2d..078e463f 100644 --- a/iguana/json_writer.hpp +++ b/iguana/json_writer.hpp @@ -9,7 +9,7 @@ namespace iguana { template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void to_json(T &&t, Stream &s); namespace detail { template @@ -122,7 +122,7 @@ IGUANA_INLINE void render_key(Stream &ss, T &&t) { } template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void to_json_impl(Stream &ss, T &&t) { to_json(std::forward(t), ss); } @@ -218,11 +218,9 @@ IGUANA_INLINE void to_json_impl(Stream &ss, const T &v) { ss.push_back(']'); } -constexpr auto write_json_key = [](auto &s, auto i, - auto &t) IGUANA__INLINE_LAMBDA { +constexpr auto write_json_key = [](auto &s, auto name) IGUANA__INLINE_LAMBDA { s.push_back('"'); // will be replaced by string_view later - constexpr auto name = get_name(); s.append(name.data(), name.size()); s.push_back('"'); }; @@ -267,28 +265,24 @@ IGUANA_INLINE void to_json_impl(Stream &s, T &&t) { } } // namespace detail template , int>> + std::enable_if_t, int>> IGUANA_INLINE void to_json(T &&t, Stream &s) { using namespace detail; s.push_back('{'); - for_each(std::forward(t), - [&t, &s](const auto &v, auto i) IGUANA__INLINE_LAMBDA { - using M = decltype(iguana_reflect_type(std::forward(t))); - constexpr auto Idx = decltype(i)::value; - constexpr auto Count = M::value(); - static_assert(Idx < Count); - - write_json_key(s, i, t); - s.push_back(':'); - to_json_impl(s, t.*v); - if (Idx < Count - 1) - IGUANA_LIKELY { s.push_back(','); } - }); + constexpr auto Count = + ylt::reflection::members_count_v>; + ylt::reflection::for_each(t, [&](auto &field, auto name, auto index) { + write_json_key(s, name); + s.push_back(':'); + to_json_impl(s, field); + if (index < Count - 1) + IGUANA_LIKELY { s.push_back(','); } + }); s.push_back('}'); } template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void to_json(T &&t, Stream &s) { using namespace detail; to_json_impl(s, t); diff --git a/iguana/util.hpp b/iguana/util.hpp index 1f08ed52..eb37ccbf 100644 --- a/iguana/util.hpp +++ b/iguana/util.hpp @@ -17,8 +17,17 @@ #include "error_code.h" #include "field_reflection.hpp" #include "reflection.hpp" +#include "ylt/reflection/member_value.hpp" +#include "ylt/reflection/user_reflect_macro.hpp" namespace iguana { +template +constexpr inline bool ylt_refletable_v = + ylt::reflection::is_ylt_refl_v || + std::is_aggregate_v>; + +template +constexpr inline bool non_ylt_refletable_v = !ylt_refletable_v; template inline constexpr bool char_v = std::is_same_v, char> || diff --git a/iguana/ylt/reflection/member_value.hpp b/iguana/ylt/reflection/member_value.hpp index 4f6ada49..80076b68 100644 --- a/iguana/ylt/reflection/member_value.hpp +++ b/iguana/ylt/reflection/member_value.hpp @@ -146,11 +146,18 @@ inline constexpr std::string_view name_of(T& t, Field& value) { return arr[index]; } +template +inline constexpr void visit_members_impl0(Visit&& func, U& arr, + std::index_sequence, + Args&... args) { + (func(args, arr[Is]), ...); +} + template inline constexpr void visit_members_impl(Visit&& func, U& arr, std::index_sequence, Args&... args) { - (func(args, arr[Is]), ...); + (func(args, arr[Is], Is), ...); } template @@ -172,7 +179,7 @@ inline constexpr void for_each(T&& t, Visit&& func) { } (std::make_index_sequence{}); #else - visit_members_impl(std::forward(func), arr, std::make_index_sequence{}, args...); + visit_members_impl0(std::forward(func), arr, std::make_index_sequence{}, args...); #endif }); } diff --git a/iguana/ylt/reflection/user_reflect_macro.hpp b/iguana/ylt/reflection/user_reflect_macro.hpp index 9aeee665..a129fcfd 100644 --- a/iguana/ylt/reflection/user_reflect_macro.hpp +++ b/iguana/ylt/reflection/user_reflect_macro.hpp @@ -6,6 +6,9 @@ #include "internal/arg_list_macro.hpp" namespace ylt::reflection { +template +using remove_cvref_t = std::remove_cv_t>; + template struct member_traits { using value_type = T; @@ -136,7 +139,7 @@ template struct is_ylt_refl : std::false_type {}; template -inline constexpr bool is_ylt_refl_v = is_ylt_refl::value; +inline constexpr bool is_ylt_refl_v = is_ylt_refl>::value; template struct is_ylt_refl>> diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp new file mode 100644 index 00000000..cb245f5c --- /dev/null +++ b/test/test_cpp20.cpp @@ -0,0 +1,26 @@ +#define DOCTEST_CONFIG_IMPLEMENT +#include "doctest.h" +#include "iguana/iguana.hpp" + +using namespace ylt::reflection; + +struct point_t { + int x; + int y; +}; + +#if __cplusplus < 202002L + YLT_REFL(point_t, x, y); +#endif + +TEST_CASE("test simple") { + point_t pt{1, 2}; + std::string str; + static_assert(iguana::ylt_refletable_v, "e"); + iguana::to_json(pt, str); + std::cout << str << "\n"; +} + +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) +int main(int argc, char **argv) { return doctest::Context(argc, argv).run(); } +DOCTEST_MSVC_SUPPRESS_WARNING_POP \ No newline at end of file From 2bb85321733e196bed7faaa2c088891257a142b0 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Fri, 23 Aug 2024 11:01:10 +0800 Subject: [PATCH 02/44] use ylt.reflection --- iguana/json_reader.hpp | 130 +-- iguana/json_writer.hpp | 17 +- iguana/util.hpp | 17 +- .../reflection/internal/arg_list_macro.hpp | 2 +- iguana/ylt/reflection/member_ptr.hpp | 4 +- iguana/ylt/reflection/member_value.hpp | 33 + test/test_cpp20.cpp | 18 +- test/test_headers1.h | 757 ++++++++++++++++++ test/unit_test.cpp | 51 +- 9 files changed, 921 insertions(+), 108 deletions(-) create mode 100644 test/test_headers1.h diff --git a/iguana/json_reader.hpp b/iguana/json_reader.hpp index d433f017..7678a7e0 100644 --- a/iguana/json_reader.hpp +++ b/iguana/json_reader.hpp @@ -4,7 +4,8 @@ #include "json_util.hpp" namespace iguana { -template , int> = 0> +template , int> = 0> IGUANA_INLINE void from_json(T &value, It &&it, It &&end); namespace detail { @@ -16,7 +17,8 @@ IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end); template , int> = 0> IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end); -template , int> = 0> +template , int> = 0> IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { from_json(value, it, end); } @@ -542,7 +544,7 @@ IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { } } // namespace detail -template , int>> +template , int>> IGUANA_INLINE void from_json(T &value, It &&it, It &&end) { skip_ws(it, end); match<'{'>(it, end); @@ -553,80 +555,82 @@ IGUANA_INLINE void from_json(T &value, It &&it, It &&end) { ++it; return; } - std::string_view key = detail::get_key(it, end); + constexpr auto Count = + ylt::reflection::members_count_v>; + if constexpr (Count > 0) { + std::string_view key = detail::get_key(it, end); #ifdef SEQUENTIAL_PARSE - bool parse_done = false; - for_each(value, [&](const auto member_ptr, auto i) IGUANA__INLINE_LAMBDA { - constexpr auto mkey = iguana::get_name(); - constexpr std::string_view st_key(mkey.data(), mkey.size()); - if (parse_done || (key != st_key)) - IGUANA_UNLIKELY { return; } - skip_ws(it, end); - match<':'>(it, end); - { - using namespace detail; - from_json_impl(value.*member_ptr, it, end); - } - - skip_ws(it, end); - if (*it == '}') - IGUANA_UNLIKELY { - ++it; - parse_done = true; - return; - } - else - IGUANA_LIKELY { match<','>(it, end); } - key = detail::get_key(it, end); - }); - if (parse_done) [[unlikely]] { - return; - } -#endif - while (it != end) { - static constexpr auto frozen_map = get_iguana_struct_map(); - if constexpr (frozen_map.size() > 0) { - const auto &member_it = frozen_map.find(key); + bool parse_done = false; + ylt::reflection::for_each(value, [&](auto &field, auto name, auto index) { + if (parse_done || (key != name)) + IGUANA_UNLIKELY { return; } skip_ws(it, end); match<':'>(it, end); - if (member_it != frozen_map.end()) - IGUANA_LIKELY { - std::visit( - [&](auto &&member_ptr) IGUANA__INLINE_LAMBDA { - using V = std::decay_t; - if constexpr (std::is_member_pointer_v) { - using namespace detail; - from_json_impl(value.*member_ptr, it, end); - } - else { - static_assert(!sizeof(V), "type not supported"); - } - }, - member_it->second); + { + using namespace detail; + from_json_impl(field, it, end); + } + + skip_ws(it, end); + if (*it == '}') + IGUANA_UNLIKELY { + ++it; + parse_done = true; + return; } else - IGUANA_UNLIKELY { + IGUANA_LIKELY { match<','>(it, end); } + key = detail::get_key(it, end); + }); + if (parse_done) [[unlikely]] { + return; + } +#endif + while (it != end) { + auto frozen_map = ylt::reflection::get_variant_map(value); + if (frozen_map.size() > 0) { + const auto &member_it = frozen_map.find(key); + skip_ws(it, end); + match<':'>(it, end); + if (member_it != frozen_map.end()) + IGUANA_LIKELY { + std::visit( + [&](auto &&member_ptr) IGUANA__INLINE_LAMBDA { + using V = std::decay_t; + if constexpr (std::is_pointer_v) { + using namespace detail; + from_json_impl(*member_ptr, it, end); + } + else { + static_assert(!sizeof(V), "type not supported"); + } + }, + member_it->second); + } + else + IGUANA_UNLIKELY { #ifdef THROW_UNKNOWN_KEY - throw std::runtime_error("Unknown key: " + std::string(key)); + throw std::runtime_error("Unknown key: " + std::string(key)); #else - detail::skip_object_value(it, end); + detail::skip_object_value(it, end); #endif + } + } + skip_ws(it, end); + if (*it == '}') + IGUANA_UNLIKELY { + ++it; + return; } + else + IGUANA_LIKELY { match<','>(it, end); } + key = detail::get_key(it, end); } - skip_ws(it, end); - if (*it == '}') - IGUANA_UNLIKELY { - ++it; - return; - } - else - IGUANA_LIKELY { match<','>(it, end); } - key = detail::get_key(it, end); } } template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void from_json(T &value, It &&it, It &&end) { using namespace detail; from_json_impl(value, it, end); diff --git a/iguana/json_writer.hpp b/iguana/json_writer.hpp index 078e463f..595a4b6d 100644 --- a/iguana/json_writer.hpp +++ b/iguana/json_writer.hpp @@ -271,13 +271,16 @@ IGUANA_INLINE void to_json(T &&t, Stream &s) { s.push_back('{'); constexpr auto Count = ylt::reflection::members_count_v>; - ylt::reflection::for_each(t, [&](auto &field, auto name, auto index) { - write_json_key(s, name); - s.push_back(':'); - to_json_impl(s, field); - if (index < Count - 1) - IGUANA_LIKELY { s.push_back(','); } - }); + if constexpr (Count > 0) { + ylt::reflection::for_each(t, [&](auto &field, auto name, auto index) { + write_json_key(s, name); + s.push_back(':'); + to_json_impl(s, field); + if (index < Count - 1) + IGUANA_LIKELY { s.push_back(','); } + }); + } + s.push_back('}'); } diff --git a/iguana/util.hpp b/iguana/util.hpp index eb37ccbf..509491ba 100644 --- a/iguana/util.hpp +++ b/iguana/util.hpp @@ -21,14 +21,6 @@ #include "ylt/reflection/user_reflect_macro.hpp" namespace iguana { -template -constexpr inline bool ylt_refletable_v = - ylt::reflection::is_ylt_refl_v || - std::is_aggregate_v>; - -template -constexpr inline bool non_ylt_refletable_v = !ylt_refletable_v; - template inline constexpr bool char_v = std::is_same_v, char> || std::is_same_v, char16_t> || @@ -152,6 +144,15 @@ constexpr inline bool refletable_v = is_reflection_v>; template constexpr inline bool non_refletable_v = !refletable_v; +template +constexpr inline bool ylt_refletable_v = + (ylt::reflection::is_ylt_refl_v || + std::is_aggregate_v< + ylt::reflection::remove_cvref_t>)&&!fixed_array_v; + +template +constexpr inline bool non_ylt_refletable_v = !ylt_refletable_v; + template constexpr inline bool plain_v = string_container_v || num_v || char_v || bool_v || enum_v; diff --git a/iguana/ylt/reflection/internal/arg_list_macro.hpp b/iguana/ylt/reflection/internal/arg_list_macro.hpp index 12cb82a1..b60ff393 100644 --- a/iguana/ylt/reflection/internal/arg_list_macro.hpp +++ b/iguana/ylt/reflection/internal/arg_list_macro.hpp @@ -1,7 +1,7 @@ #pragma once #include "common_macro.hpp" -#define WRAP_ARGS0(w, o) +#define WRAP_ARGS0(w, o, _0) #define WRAP_ARGS1(w, o, _1) w(o, _1) #include "generate/arg_list_macro_gen.hpp" diff --git a/iguana/ylt/reflection/member_ptr.hpp b/iguana/ylt/reflection/member_ptr.hpp index 2a847d8b..811df6db 100644 --- a/iguana/ylt/reflection/member_ptr.hpp +++ b/iguana/ylt/reflection/member_ptr.hpp @@ -124,8 +124,8 @@ inline constexpr decltype(auto) visit_members(T&& t, Visitor&& visitor) { std::forward(visitor)); } else if constexpr (is_inner_ylt_refl_v) { - return type::refl_object_to_tuple(std::forward(t), - std::forward(visitor)); + return t.refl_visit_members(std::forward(t), + std::forward(visitor)); } else { return internal::tuple_view(std::forward(t), diff --git a/iguana/ylt/reflection/member_value.hpp b/iguana/ylt/reflection/member_value.hpp index 80076b68..00f90abf 100644 --- a/iguana/ylt/reflection/member_value.hpp +++ b/iguana/ylt/reflection/member_value.hpp @@ -48,8 +48,41 @@ struct switch_helper { } } }; + +template +inline auto get_variant_type(std::tuple&) { + return std::variant>...>{}; +} + +inline constexpr frozen::string filter_str(const frozen::string& str) { + if (str.size() > 3 && str[0] == '_' && str[1] == '_' && str[2] == '_') { + auto ptr = str.data() + 3; + return frozen::string(ptr, str.size() - 3); + } + return str; +} + +template +inline constexpr auto get_variant_map_impl( + const std::array& arr, T&& t, + std::index_sequence) { + auto ref_tp = object_to_tuple(std::forward(t)); + using ValueType = decltype(get_variant_type(ref_tp)); + return frozen::unordered_map{ + {filter_str(arr[Is]), + ValueType{std::in_place_index, &std::get(ref_tp)}}...}; +} + } // namespace internal +template +inline constexpr auto get_variant_map(T&& t) { + using U = ylt::reflection::remove_cvref_t; + constexpr auto arr = ylt::reflection::member_names; + return internal::get_variant_map_impl(arr, std::forward(t), + std::make_index_sequence{}); +} + template inline Member& get(T& t, size_t index) { auto ref_tp = object_to_tuple(t); diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index cb245f5c..4460218b 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -1,4 +1,5 @@ #define DOCTEST_CONFIG_IMPLEMENT +// #define SEQUENTIAL_PARSE #include "doctest.h" #include "iguana/iguana.hpp" @@ -10,7 +11,7 @@ struct point_t { }; #if __cplusplus < 202002L - YLT_REFL(point_t, x, y); +YLT_REFL(point_t, x, y); #endif TEST_CASE("test simple") { @@ -19,8 +20,21 @@ TEST_CASE("test simple") { static_assert(iguana::ylt_refletable_v, "e"); iguana::to_json(pt, str); std::cout << str << "\n"; + auto map = ylt::reflection::get_variant_map(pt); + for (auto& [key, var] : map) { + std::cout << key.data() << "\n"; + std::visit( + [](auto ptr) { + std::cout << *ptr << "\n"; + }, + var); + } + + point_t pt1; + iguana::from_json(pt1, str); + std::cout << pt1.x << "\n"; } DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) -int main(int argc, char **argv) { return doctest::Context(argc, argv).run(); } +int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); } DOCTEST_MSVC_SUPPRESS_WARNING_POP \ No newline at end of file diff --git a/test/test_headers1.h b/test/test_headers1.h new file mode 100644 index 00000000..a61c2444 --- /dev/null +++ b/test/test_headers1.h @@ -0,0 +1,757 @@ +#pragma once +#include +#include +#include + +#include "iguana/ylt/reflection/user_reflect_macro.hpp" + +struct MyClass1 { + double member0; + double member1; + double member2; + double member3; + + bool operator==(MyClass1 const &rhs) const { + return member0 == rhs.member0 && member1 == rhs.member1 && + member2 == rhs.member2 && member3 == rhs.member3; + } +}; +YLT_REFL(MyClass1, member0, member1, member2, member3); + +struct MyClass2 { + unsigned member_unsigned0; + unsigned member_unsigned1; + signed member_signed; + + bool operator==(MyClass2 const &rhs) const { + return member_unsigned0 == rhs.member_unsigned0 && + member_unsigned1 == rhs.member_unsigned1 && + member_signed == rhs.member_signed; + } +}; +YLT_REFL(MyClass2, member_unsigned0, member_unsigned1, member_signed); + +struct person { + std::string name; + int age; +}; +YLT_REFL(person, name, age); + +// canada.json +struct property_t { + std::string name; +}; // Property +YLT_REFL(property_t, name); + +struct polygon_t { + std::string type; + std::vector>> coordinates; +}; // Polygon +YLT_REFL(polygon_t, type, coordinates); + +struct feature_t { + std::string type; + property_t properties; + polygon_t geometry; +}; // Feature +YLT_REFL(feature_t, type, properties, geometry); + +struct FeatureCollection { + std::string type; + std::vector features; +}; // FeatureCollection +YLT_REFL(FeatureCollection, type, features); + +// apache_builds.json +struct jobs_t { + std::string name; + std::string url; + std::string color; +}; +YLT_REFL(jobs_t, name, url, color); + +struct views_t { + std::string name; + std::string url; +}; +YLT_REFL(views_t, name, url); + +struct apache_empty_t {}; +YLT_REFL(apache_empty_t); + +struct apache_builds { + std::vector assignedLabels; + std::string mode; + std::string nodeDescription; + std::string nodeName; + int64_t numExecutors; + std::string description; + std::vector jobs; + apache_empty_t overallLoad; + views_t primaryView; + bool quietingDown; + int64_t slaveAgentPort; + apache_empty_t unlabeledLoad; + bool useCrumbs; + bool useSecurity; + std::vector views; +}; +YLT_REFL(apache_builds, assignedLabels, mode, nodeDescription, nodeName, + numExecutors, description, jobs, overallLoad, primaryView, + quietingDown, slaveAgentPort, unlabeledLoad, useCrumbs, useSecurity, + views); + +// citm_catalog.json +struct events_value_t { + std::optional description; + std::int64_t id; + std::optional logo; + std::string name; + std::vector subTopicIds; + std::optional subjectCode; + std::optional subtitle; + std::vector topicIds; +}; // events_value_t +YLT_REFL(events_value_t, description, id, logo, name, subTopicIds, subjectCode, + subtitle, topicIds); + +struct prices_element_t { + std::int64_t amount; + std::int64_t audienceSubCategoryId; + std::int64_t seatCategoryId; +}; // prices_element_t +YLT_REFL(prices_element_t, amount, audienceSubCategoryId, seatCategoryId); + +struct areas_element_t { + std::int64_t areaId; + std::vector blockIds; +}; // areas_element_t +YLT_REFL(areas_element_t, areaId, blockIds); + +struct seatCategories_element_t { + std::vector areas; + std::int64_t seatCategoryId; +}; // seatCategories_element_t +YLT_REFL(seatCategories_element_t, areas, seatCategoryId); + +struct performances_element_t { + std::int64_t eventId; + std::int64_t id; + std::optional logo; + std::optional name; + std::vector prices; + std::vector seatCategories; + std::optional seatMapImage; + std::int64_t start; + std::string venueCode; +}; // performances_element_t +YLT_REFL(performances_element_t, eventId, id, logo, name, prices, + seatCategories, seatMapImage, start, venueCode); + +struct venueNames_t { + std::string PLEYEL_PLEYEL; +}; // venueNames_t +YLT_REFL(venueNames_t, PLEYEL_PLEYEL); + +struct citm_object_t { + std::unordered_map areaNames; + std::unordered_map audienceSubCategoryNames; + apache_empty_t blockNames; + std::unordered_map events; + std::vector performances; + std::unordered_map seatCategoryNames; + std::unordered_map subTopicNames; + apache_empty_t subjectNames; + std::unordered_map topicNames; + std::unordered_map> topicSubTopics; + std::optional venueNames; +}; // citm_object_t +YLT_REFL(citm_object_t, areaNames, audienceSubCategoryNames, blockNames, events, + performances, seatCategoryNames, subTopicNames, subjectNames, + topicNames, topicSubTopics, venueNames); + +// gsoc-2018.json +struct sponsor_t { + std::string type; //@ + std::string name; + std::string disambiguatingDescription; + std::string description; + std::string url; + std::string logo; +}; +YLT_REFL(sponsor_t, type, name, disambiguatingDescription, description, url, + logo); + +struct author_t { + std::string type; //@ + std::string name; +}; +YLT_REFL(author_t, type, name); + +struct gsoc_element_t { + std::string context; //@ + std::string type; //@ + std::string name; + std::string description; + sponsor_t sponsor; + author_t author; +}; +YLT_REFL(gsoc_element_t, context, type, name, description, sponsor, author); + +using gsoc_object_t = std::map; + +// mesh.pretty.json +struct mesh_element_t { + std::vector indexRange; + std::vector usedBones; + std::vector vertexRange; +}; +YLT_REFL(mesh_element_t, indexRange, usedBones, vertexRange); + +struct mesh_t { + std::vector batches; + std::vector colors; + std::vector indices; + std::vector> influences; + apache_empty_t morphTargets; + std::vector normals; + std::vector positions; + std::vector tex0; +}; +YLT_REFL(mesh_t, batches, colors, indices, influences, morphTargets, normals, + positions, tex0); + +// random.json +struct friend_t { + int id; + std::string name; + std::string phone; +}; +YLT_REFL(friend_t, id, name, phone); + +struct random_element_t { + int id; + std::string avatar; + int age; + bool admin; + std::string name; + std::string company; + std::string phone; + std::string email; + std::string birthDate; + std::vector friends; + std::string field; +}; +YLT_REFL(random_element_t, id, avatar, age, admin, name, company, phone, email, + birthDate, friends, field); + +struct random_t { + int id; + std::string jsonrpc; + int total; + std::vector result; +}; +YLT_REFL(random_t, id, jsonrpc, total, result); + +// github_events.json +namespace githubEvents { +struct user_t { + std::string gists_url; + std::string gravatar_id; + std::string url; + std::string type; + std::string avatar_url; + std::string subscriptions_url; + std::string organizations_url; + std::string received_events_url; + std::string repos_url; + std::string login; + std::string starred_url; + int id; + std::string events_url; + std::string followers_url; + std::string following_url; +}; +YLT_REFL(user_t, gists_url, gravatar_id, url, type, avatar_url, + subscriptions_url, organizations_url, received_events_url, repos_url, + login, starred_url, id, events_url, followers_url, following_url); + +struct page_t { + std::string page_name; + std::string html_url; + std::string title; + std::string sha; + std::optional summary; + std::string action; +}; +YLT_REFL(page_t, page_name, html_url, title, sha, summary, action); + +struct pull_request_t { + std::optional html_url; + std::optional patch_url; + std::optional diff_url; +}; +YLT_REFL(pull_request_t, html_url, patch_url, diff_url); + +struct forkee_t { + std::string full_name; + std::string stargazers_url; + std::string clone_url; + bool fork; + std::string url; + std::string tags_url; + std::string description; + std::string merges_url; + int forks; + std::string language; + bool ___private; + std::string archive_url; + std::string collaborators_url; + std::string languages_url; + user_t owner; + std::string git_refs_url; + std::string labels_url; + std::string pushed_at; + std::string html_url; + std::string trees_url; + std::string forks_url; + std::string commits_url; + std::string branches_url; + std::string notifications_url; + std::string created_at; + bool has_issues; + std::string blobs_url; + std::string issues_url; + std::string compare_url; + int open_issues; + std::string contents_url; + std::string name; + std::string statuses_url; + std::string assignees_url; + int forks_count; + std::string updated_at; + std::string issue_events_url; + std::string ssh_url; + std::string subscribers_url; + std::optional mirror_url; + bool ___public; + bool has_wiki; + std::string git_commits_url; + std::string downloads_url; + int id; + std::string pulls_url; + bool has_downloads; + std::string issue_comment_url; + int watchers_count; + std::optional homepage; + std::string hooks_url; + std::string subscription_url; + std::string milestones_url; + std::string events_url; + std::string svn_url; + std::string git_tags_url; + std::string teams_url; + std::string comments_url; + int open_issues_count; + std::string keys_url; + std::string contributors_url; + int size; + int watchers; + std::string git_url; +}; +YLT_REFL(forkee_t, full_name, stargazers_url, clone_url, fork, url, tags_url, + description, merges_url, forks, language, ___private, archive_url, + collaborators_url, languages_url, owner, git_refs_url, labels_url, + pushed_at, html_url, trees_url, forks_url, commits_url, branches_url, + notifications_url, created_at, has_issues, blobs_url, issues_url, + open_issues, contents_url, name, statuses_url, assignees_url, + forks_count, updated_at, issue_events_url, ssh_url, subscribers_url, + mirror_url, ___public, has_wiki, git_commits_url, downloads_url, id, + pulls_url, has_downloads, issue_comment_url, watchers_count, homepage, + hooks_url, subscription_url, milestones_url, events_url, svn_url, + git_tags_url, teams_url, comments_url, open_issues_count, keys_url, + contributors_url, size, watchers, git_url, compare_url); + +struct issue_t { + user_t user; + std::string url; + std::vector labels; + std::string html_url; + std::string labels_url; + pull_request_t pull_request; + std::string created_at; + std::optional closed_at; + std::optional milestone; + std::string title; + std::string body; + std::string updated_at; + int number; + std::string state; + std::optional assignee; + int id; + int comments; + std::string events_url; + std::string comments_url; +}; +YLT_REFL(issue_t, user, url, labels, html_url, labels_url, pull_request, + created_at, closed_at, milestone, title, body, updated_at, number, + state, assignee, id, comments, events_url, comments_url); + +struct comment_t { + user_t user; + std::string url; + std::string issue_url; + std::string created_at; + std::string body; + std::string updated_at; + int id; +}; +YLT_REFL(comment_t, user, url, issue_url, created_at, body, updated_at, id); + +struct actor_org_t { + std::string gravatar_id; + std::string login; + std::string avatar_url; + std::string url; + int id; +}; +YLT_REFL(actor_org_t, gravatar_id, login, avatar_url, url, id); + +struct repo_t { + std::string url; + int id; + std::string name; +}; +YLT_REFL(repo_t, url, id, name); + +struct author_t { + std::string email; + std::string name; +}; +YLT_REFL(author_t, email, name); + +struct commit_t { + std::string url; + std::string message; + bool distinct; + std::string sha; + author_t author; +}; +YLT_REFL(commit_t, url, message, distinct, sha, author); + +struct payload_t { + std::optional> commits; + std::optional distinct_size; + std::optional ref; + std::optional push_id; + std::optional head; + std::optional before; + std::optional size; + std::optional forkee; + std::optional> pages; + std::optional action; + std::optional comment; + std::optional issue; + std::optional description; + std::optional master_branch; + + std::optional ref_type; +}; +YLT_REFL(payload_t, commits, distinct_size, ref, push_id, head, before, size, + forkee, pages, action, comment, issue, description, master_branch, + ref_type); + +struct event_t { + std::string type; + std::string created_at; + std::optional actor; + repo_t repo; + bool ___public; + std::optional org; + payload_t payload; + std::string id; +}; +YLT_REFL(event_t, type, created_at, actor, repo, ___public, org, payload, id); + +using events_t = std::vector; +} // namespace githubEvents + +namespace marine_ik { +struct image_element_t { + std::string url; + std::string uuid; + std::string name; +}; +YLT_REFL(image_element_t, url, uuid, name); + +struct item_t { + std::string name; + std::string type; + std::string uuid; +}; +YLT_REFL(item_t, name, type, uuid); + +struct key_element_t { + std::array rot; + float time{}; + std::array scl; + std::array pos; +}; +YLT_REFL(key_element_t, rot, time, scl, pos); + +struct hierarchy_element_t { + int parent; + std::vector keys; +}; +YLT_REFL(hierarchy_element_t, parent, keys); + +struct geo_anim_element_t { + std::vector hierarchy; + float length{}; + int fps{}; + std::string name; +}; +YLT_REFL(geo_anim_element_t, hierarchy, length, fps, name); + +struct bone_element_t { + int parent; + std::array pos; + std::array rotq; + std::array scl; + std::string name; +}; +YLT_REFL(bone_element_t, parent, pos, rotq, scl, name); + +struct geo_meta_data_t { + int uvs; + int version; + int faces; + std::string generator; + int normals; + int bones; + int vertices; +}; +YLT_REFL(geo_meta_data_t, uvs, version, faces, generator, normals, bones, + vertices); + +struct geo_data_t { + std::vector> uvs; + std::vector animations; + std::vector vertices; + geo_meta_data_t metadata; + std::string name; + std::vector skinWeights; + std::vector skinIndices; + int influencesPerVertex{}; + std::vector normals; + std::vector bones; + std::vector faces; +}; +YLT_REFL(geo_data_t, uvs, animations, vertices, metadata, name, skinWeights, + skinIndices, influencesPerVertex, normals, bones, faces); + +struct geometry_element_t { + std::string type; + std::string uuid; + geo_data_t data; +}; +YLT_REFL(geometry_element_t, type, uuid, data); + +struct texture_element_t { + std::array repeat; + std::array wrap; + int anisotropy{}; + std::string image; + std::string name; + int mapping{}; + int minFilter{}; + std::string uuid; + int magFilter{}; +}; +YLT_REFL(texture_element_t, repeat, wrap, anisotropy, image, name, mapping, + minFilter, uuid, magFilter); + +struct meta_data_t { + std::string sourceFile; + std::string generator; + std::string type; + float version{}; +}; +YLT_REFL(meta_data_t, sourceFile, generator, type, version); + +struct material_element_t : item_t { + int vertexColors{}; + std::string blending; + std::string map; + bool transparent{}; + bool depthTest{}; + int color; + int shininess; + int emissive; + bool depthWrite{}; + int specular{}; +}; +YLT_REFL(material_element_t, vertexColors, name, type, uuid, blending, map, + transparent, depthTest, color, shininess, emissive, depthWrite, + specular); + +struct obj_child_t : item_t { + std::array matrix; + bool visible{}; + std::string material; + bool castShadow{}; + bool receiveShadow{}; + std::string geometry; +}; +YLT_REFL(obj_child_t, name, uuid, matrix, visible, type, material, castShadow, + receiveShadow, geometry); + +struct object_t { + std::vector children; + std::string type; + std::array matrix; + std::string uuid; +}; +YLT_REFL(object_t, children, type, matrix, uuid); + +struct animation_element_t { + std::vector tracks; + int fps; + std::string name; +}; +YLT_REFL(animation_element_t, tracks, fps, name); + +struct marine_ik_t { + std::vector images; + std::vector geometries; + std::vector textures; + meta_data_t metadata; + std::vector materials; + object_t object; + std::vector animations; +}; +YLT_REFL(marine_ik_t, images, geometries, textures, metadata, materials, object, + animations); +} // namespace marine_ik + +// instruments.json +struct sample_element { + int c5_samplerate; + int global_volume; + std::string legacy_filename; + int length; + int loop_end; + int loop_start; + std::string name; + int pan; + int sustain_end; + int sustain_start; + int vibrato_depth; + int vibrato_rate; + int vibrato_sweep; + int vibrato_type; + int volume; +}; +YLT_REFL(sample_element, c5_samplerate, global_volume, legacy_filename, length, + loop_end, loop_start, name, pan, sustain_end, sustain_start, + vibrato_depth, vibrato_rate, vibrato_sweep, vibrato_type, volume); + +struct data_t { + int channel; + int fxcmd; + int fxparam; + int instr; + int note; + int row; + int volcmd; + int volval; +}; +YLT_REFL(data_t, channel, fxcmd, fxparam, instr, note, row, volcmd, volval); + +struct pattern_element { + std::optional> data; + std::string name; + int rows; + int rows_per_beat; + int rows_per_measure; +}; +YLT_REFL(pattern_element, data, name, rows, rows_per_beat, rows_per_measure); + +struct node_t { + int tick; + int value; +}; +YLT_REFL(node_t, tick, value); + +struct panning_envelope_t { + int loop_end; + int loop_start; + std::vector nodes; + int release_node; + int sustain_end; + int sustain_start; +}; +YLT_REFL(panning_envelope_t, loop_end, loop_start, nodes, release_node, + sustain_end, sustain_start); + +struct instrument_element { + int default_filter_cutoff; + bool default_filter_cutoff_enabled; + int default_filter_mode; + int default_filter_resonance; + bool default_filter_resonance_enabled; + int default_pan; + int duplicate_check_type; + int duplicate_note_action; + int fadeout; + int global_volume; + int graph_insert; + std::string legacy_filename; + int midi_bank; + int midi_channel; + int midi_drum_set; + int midi_program; + std::string name; + int new_note_action; + std::optional note_map; + panning_envelope_t panning_envelope; + panning_envelope_t pitch_envelope; + + int pitch_pan_center; + int pitch_pan_separation; + int pitch_to_tempo_lock; + int random_cutoff_weight; + int random_pan_weight; + int random_resonance_weight; + int random_volume_weight; + std::optional sample_map; + std::optional tuning; + + panning_envelope_t volume_envelope; + int volume_ramp_down; + int volume_ramp_up; +}; +YLT_REFL(instrument_element, default_filter_cutoff, + default_filter_cutoff_enabled, default_filter_mode, + default_filter_resonance, default_filter_resonance_enabled, + default_pan, duplicate_check_type, duplicate_note_action, fadeout, + global_volume, graph_insert, legacy_filename, midi_bank, midi_channel, + midi_drum_set, midi_program, name, new_note_action, note_map, + panning_envelope, pitch_envelope, pitch_pan_center, + pitch_pan_separation, pitch_to_tempo_lock, random_cutoff_weight, + random_pan_weight, random_resonance_weight, random_volume_weight, + sample_map, tuning, volume_envelope, volume_ramp_down, volume_ramp_up); + +struct instruments_t { + std::optional graphstate; + std::vector instruments; + std::optional message; + std::string name; + std::optional orderlist; + std::vector patterns; + std::optional pluginstate; + std::vector samples; + int version; +}; +YLT_REFL(instruments_t, graphstate, instruments, message, name, orderlist, + patterns, pluginstate, samples, version); diff --git a/test/unit_test.cpp b/test/unit_test.cpp index ca58851d..a85a1a55 100644 --- a/test/unit_test.cpp +++ b/test/unit_test.cpp @@ -3,8 +3,8 @@ #include #include -#include "iguana/reflection.hpp" #define DOCTEST_CONFIG_IMPLEMENT +// #define SEQUENTIAL_PARSE #include #include #include @@ -12,7 +12,7 @@ #include "doctest.h" #include "iguana/json_reader.hpp" -#include "test_headers.h" +#include "test_headers1.h" TEST_CASE("test parse item num_t") { { @@ -243,7 +243,7 @@ struct test_enum_t { Color g; Color h; }; -REFLECTION(test_enum_t, a, b, c, d, e, f, g, h); +YLT_REFL(test_enum_t, a, b, c, d, e, f, g, h); #if defined(__clang__) || defined(_MSC_VER) || \ (defined(__GNUC__) && __GNUC__ > 8) @@ -303,10 +303,11 @@ TEST_CASE("test parse item char") { CHECK(test == 'c'); } { - // std::string str{"\""}; - // char test{}; - // CHECK_THROWS(iguana::from_json(test, str.begin(), str.end())); - } { + std::string str{"\""}; + char test{}; + CHECK_THROWS(iguana::from_json(test, str.begin(), str.end())); + } + { std::string str{R"("\)"}; char test{}; CHECK_THROWS_WITH(iguana::from_json(test, str.begin(), str.end()), @@ -405,22 +406,22 @@ TEST_CASE("test parse item optional") { struct optional_t { std::optional p; }; -REFLECTION(optional_t, p); +YLT_REFL(optional_t, p); struct struct_test_t { int32_t value; }; -REFLECTION(struct_test_t, value); +YLT_REFL(struct_test_t, value); struct struct_container_t { std::vector values; }; -REFLECTION(struct_container_t, values); +YLT_REFL(struct_container_t, values); struct struct_container_1_t { std::optional val; }; // entities_t -REFLECTION(struct_container_1_t, val); +YLT_REFL(struct_container_1_t, val); TEST_CASE("test optional") { { @@ -472,7 +473,7 @@ TEST_CASE("test optional") { } struct empty_t {}; -REFLECTION_EMPTY(empty_t); +YLT_REFL(empty_t); TEST_CASE("test empty struct") { empty_t t; @@ -489,7 +490,7 @@ struct keyword_t { std::string ___protected; std::string ___class; }; -REFLECTION(keyword_t, ___private, ___protected, ___public, ___class); +YLT_REFL(keyword_t, ___private, ___protected, ___public, ___class); TEST_CASE("test keyword") { std::string ss = @@ -507,7 +508,7 @@ struct config_actor_type { std::string make; std::string config; }; -REFLECTION(config_actor_type, id, make, config); +YLT_REFL(config_actor_type, id, make, config); struct config_app_json_type { long id = 0; @@ -515,7 +516,7 @@ struct config_app_json_type { std::string loglevel; std::vector actors; }; -REFLECTION(config_app_json_type, id, threads, loglevel, actors); +YLT_REFL(config_app_json_type, id, threads, loglevel, actors); TEST_CASE("test long") { config_app_json_type app{1234}; @@ -686,7 +687,7 @@ struct book_t { std::optional edition; std::vector author; }; -REFLECTION(book_t, title, edition, author); +YLT_REFL(book_t, title, edition, author); TEST_CASE("test the string_view") { { std::string str = R"("C++ \ntemplates")"; @@ -773,7 +774,7 @@ struct st_char_t { char b[5]; char c[5]; }; -REFLECTION(st_char_t, a, b, c); +YLT_REFL(st_char_t, a, b, c); TEST_CASE("test char") { std::string str = R"( { @@ -816,7 +817,7 @@ TEST_CASE("test char") { struct fixed_vector_arr_t { std::vector a[4]; }; -REFLECTION(fixed_vector_arr_t, a); +YLT_REFL(fixed_vector_arr_t, a); TEST_CASE("test fixed array") { std::string str = R"( { @@ -854,7 +855,7 @@ struct vector_bool_t { std::vector a; bool b; }; -REFLECTION(vector_bool_t, a, b); +YLT_REFL(vector_bool_t, a, b); TEST_CASE("test vector") { std::string str = R"({ "a": [true, false], @@ -880,7 +881,7 @@ struct test_numeric_t { std::vector arr; iguana::numeric_str num; }; -REFLECTION(test_numeric_t, arr, num); +YLT_REFL(test_numeric_t, arr, num); TEST_CASE("test numeric string") { std::string str = R"( { "arr": [1.5 , 2.4 , 3.7], @@ -909,7 +910,7 @@ struct test_uint8_t { int8_t b; char c; }; -REFLECTION(test_uint8_t, a, b, c); +YLT_REFL(test_uint8_t, a, b, c); TEST_CASE("test uint8 and int8") { std::string str = R"( { @@ -944,10 +945,10 @@ class some_object { some_object(int i, std::string str) : id(i), name(str) {} int get_id() const { return id; } std::string get_name() const { return name; } - REFLECTION(some_object, id, name); + YLT_REFL(some_object, id, name); }; -TEST_CASE("test inner reflection") { +TEST_CASE("test inner YLT_REFL") { some_object obj{20, "tom"}; std::string str; iguana::to_json(obj, str); @@ -964,7 +965,7 @@ struct Contents_t { std::shared_ptr>> vec_s; std::string b; }; -REFLECTION(Contents_t, vec, vec_s, b); +YLT_REFL(Contents_t, vec, vec_s, b); TEST_CASE("test smart_ptr") { std::string str = R"( @@ -993,7 +994,7 @@ struct person1 { std::shared_ptr name; std::shared_ptr age; }; -REFLECTION(person1, name, age); +YLT_REFL(person1, name, age); TEST_CASE("test smart point issue 223") { person1 p{std::make_shared("tom"), From 2490267aa7c5533b3322e311a289593354c48378 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Fri, 23 Aug 2024 16:40:36 +0800 Subject: [PATCH 03/44] update json example --- example/json_example.cpp | 17 +++++++++-------- iguana/ylt/reflection/member_value.hpp | 22 +++++++++++++--------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/example/json_example.cpp b/example/json_example.cpp index 4d18fa37..6ffc468b 100644 --- a/example/json_example.cpp +++ b/example/json_example.cpp @@ -14,7 +14,6 @@ inline char* to_chars_float(T value, char* buffer) { #include #include -//#include namespace client { struct person { @@ -22,20 +21,20 @@ struct person { int64_t age; }; -REFLECTION(person, name, age); +YLT_REFL(person, name, age); } // namespace client struct MyStruct { uint64_t a; }; -REFLECTION(MyStruct, a); +YLT_REFL(MyStruct, a); struct student { int id; std::string name; int age; }; -REFLECTION(student, id, name, age); +YLT_REFL(student, id, name, age); void test() { MyStruct p = {5566777755311}; @@ -82,7 +81,7 @@ struct book_t { std::string_view edition; std::vector author; }; -REFLECTION(book_t, title, edition, author); +YLT_REFL(book_t, title, edition, author); void test_str_view() { { @@ -108,6 +107,8 @@ void test_str_view() { namespace my_space { struct my_struct { + my_struct() = default; + my_struct(int a, int b, int c) : x(a), y(b), z(c) {} int x, y, z; bool operator==(const my_struct& o) const { return x == o.x && y == o.y && z == o.z; @@ -134,11 +135,11 @@ struct nest { } }; -REFLECTION(nest, name, value); +YLT_REFL(nest, name, value); void user_defined_struct_example() { { - my_space::my_struct v{1, 2, 3}, v2; + my_space::my_struct v{7, 8, 9}, v2; std::string s; iguana::to_json(v, s); std::cout << s << std::endl; @@ -159,7 +160,7 @@ struct test_float_t { double a; float b; }; -REFLECTION(test_float_t, a, b); +YLT_REFL(test_float_t, a, b); void user_defined_tochars_example() { test_float_t t{2.011111, 2.54}; diff --git a/iguana/ylt/reflection/member_value.hpp b/iguana/ylt/reflection/member_value.hpp index 00f90abf..3bc3d5b6 100644 --- a/iguana/ylt/reflection/member_value.hpp +++ b/iguana/ylt/reflection/member_value.hpp @@ -179,17 +179,20 @@ inline constexpr std::string_view name_of(T& t, Field& value) { return arr[index]; } -template -inline constexpr void visit_members_impl0(Visit&& func, U& arr, +template +inline constexpr void visit_members_impl0(Visit&& func, std::index_sequence, Args&... args) { + constexpr auto arr = member_names; (func(args, arr[Is]), ...); } -template -inline constexpr void visit_members_impl(Visit&& func, U& arr, +template +inline constexpr void visit_members_impl(Visit&& func, std::index_sequence, Args&... args) { + constexpr auto arr = member_names; (func(args, arr[Is], Is), ...); } @@ -203,16 +206,16 @@ inline constexpr void for_each(T&& t, Visit&& func) { }); } else { - constexpr auto arr = member_names; if constexpr (std::is_invocable_v) { visit_members(t, [&](auto&... args) { #if __cplusplus >= 202002L [&](std::index_sequence) mutable { + constexpr auto arr = member_names; (func(args, arr[Is]), ...); } - (std::make_index_sequence{}); + (std::make_index_sequence{}); #else - visit_members_impl0(std::forward(func), arr, std::make_index_sequence{}, args...); + visit_members_impl0(std::forward(func), std::make_index_sequence{}, args...); #endif }); } @@ -221,11 +224,12 @@ inline constexpr void for_each(T&& t, Visit&& func) { visit_members(t, [&](auto&... args) { #if __cplusplus >= 202002L [&](std::index_sequence) mutable { + constexpr auto arr = member_names; (func(args, arr[Is], Is), ...); } - (std::make_index_sequence{}); + (std::make_index_sequence{}); #else - visit_members_impl(std::forward(func), arr, std::make_index_sequence{}, args...); + visit_members_impl(std::forward(func), std::make_index_sequence{}, args...); #endif }); } From 2fad0dbd2fefe9e588169d79b9bfcbe150113796 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 26 Aug 2024 10:31:56 +0800 Subject: [PATCH 04/44] update json example --- CMakeLists.txt | 2 +- example/json_example.cpp | 4 +- iguana/json_reader.hpp | 15 +- iguana/util.hpp | 3 +- iguana/ylt/reflection/member_value.hpp | 12 +- iguana/ylt/reflection/user_reflect_macro.hpp | 12 + test/{test.cpp => test_some.cpp} | 217 +++++++++---------- 7 files changed, 142 insertions(+), 123 deletions(-) rename test/{test.cpp => test_some.cpp} (86%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45206a72..cb0c82ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ set(YAML_EXAMPLE example/yaml_example.cpp ) -set(TEST_SOME test/test.cpp) +set(TEST_SOME test/test_some.cpp) set(TEST_UT test/unit_test.cpp) set(TEST_JSON_FILES test/test_json_files.cpp) set(TEST_XML test/test_xml.cpp) diff --git a/example/json_example.cpp b/example/json_example.cpp index 6ffc468b..184817aa 100644 --- a/example/json_example.cpp +++ b/example/json_example.cpp @@ -107,14 +107,14 @@ void test_str_view() { namespace my_space { struct my_struct { - my_struct() = default; - my_struct(int a, int b, int c) : x(a), y(b), z(c) {} int x, y, z; bool operator==(const my_struct& o) const { return x == o.x && y == o.y && z == o.z; } }; +void ylt_custom_reflect(my_struct*) {} + template inline void to_json_impl(Stream& s, const my_struct& t) { iguana::to_json(*(int(*)[3]) & t, s); diff --git a/iguana/json_reader.hpp b/iguana/json_reader.hpp index 7678a7e0..769c05a0 100644 --- a/iguana/json_reader.hpp +++ b/iguana/json_reader.hpp @@ -8,6 +8,14 @@ template , int> = 0> IGUANA_INLINE void from_json(T &value, It &&it, It &&end); +template , int> = 0> +IGUANA_INLINE void from_json(T &value, const View &view); + +template , int> = 0> +IGUANA_INLINE void from_json(T &value, const View &view); + namespace detail { template , int>> +IGUANA_INLINE void from_json(T &value, const View &view) { + from_json(value, std::begin(view), std::end(view)); +} + template , int> = 0> + std::enable_if_t, int>> IGUANA_INLINE void from_json(T &value, const View &view) { from_json(value, std::begin(view), std::end(view)); } diff --git a/iguana/util.hpp b/iguana/util.hpp index 509491ba..bbb27c2e 100644 --- a/iguana/util.hpp +++ b/iguana/util.hpp @@ -148,7 +148,8 @@ template constexpr inline bool ylt_refletable_v = (ylt::reflection::is_ylt_refl_v || std::is_aggregate_v< - ylt::reflection::remove_cvref_t>)&&!fixed_array_v; + ylt::reflection::remove_cvref_t>)&&!fixed_array_v && + !ylt::reflection::is_custom_refl_v; template constexpr inline bool non_ylt_refletable_v = !ylt_refletable_v; diff --git a/iguana/ylt/reflection/member_value.hpp b/iguana/ylt/reflection/member_value.hpp index 3bc3d5b6..a73afa4a 100644 --- a/iguana/ylt/reflection/member_value.hpp +++ b/iguana/ylt/reflection/member_value.hpp @@ -63,9 +63,9 @@ inline constexpr frozen::string filter_str(const frozen::string& str) { } template -inline constexpr auto get_variant_map_impl( - const std::array& arr, T&& t, - std::index_sequence) { +inline constexpr auto get_variant_map_impl(T&& t, std::index_sequence) { + using U = ylt::reflection::remove_cvref_t; + constexpr auto arr = ylt::reflection::member_names; auto ref_tp = object_to_tuple(std::forward(t)); using ValueType = decltype(get_variant_type(ref_tp)); return frozen::unordered_map{ @@ -77,10 +77,8 @@ inline constexpr auto get_variant_map_impl( template inline constexpr auto get_variant_map(T&& t) { - using U = ylt::reflection::remove_cvref_t; - constexpr auto arr = ylt::reflection::member_names; - return internal::get_variant_map_impl(arr, std::forward(t), - std::make_index_sequence{}); + return internal::get_variant_map_impl( + std::forward(t), std::make_index_sequence>{}); } template diff --git a/iguana/ylt/reflection/user_reflect_macro.hpp b/iguana/ylt/reflection/user_reflect_macro.hpp index a129fcfd..a4f93b89 100644 --- a/iguana/ylt/reflection/user_reflect_macro.hpp +++ b/iguana/ylt/reflection/user_reflect_macro.hpp @@ -148,4 +148,16 @@ struct is_ylt_refl>> template struct is_ylt_refl>> : std::true_type { }; + +template +struct is_custom_reflect : std::false_type {}; + +template +struct is_custom_reflect< + T, std::void_t> + : std::true_type {}; + +template +inline constexpr bool is_custom_refl_v = + is_custom_reflect>::value; } // namespace ylt::reflection diff --git a/test/test.cpp b/test/test_some.cpp similarity index 86% rename from test/test.cpp rename to test/test_some.cpp index e45fe7f4..e844551c 100644 --- a/test/test.cpp +++ b/test/test_some.cpp @@ -1,8 +1,3 @@ -#include -#include -#include - -#include "iguana/reflection.hpp" #define DOCTEST_CONFIG_IMPLEMENT #include #include @@ -18,7 +13,7 @@ struct point_t { int x; double y; }; -REFLECTION(point_t, x, y); +YLT_REFL(point_t, x, y); struct person { std::string name; @@ -27,74 +22,74 @@ struct person { return name == rhs.name && ok == rhs.ok; } }; -REFLECTION(person, name, ok); +YLT_REFL(person, name, ok); struct bool_t { bool ok; }; -REFLECTION(bool_t, ok); +YLT_REFL(bool_t, ok); struct optional_t { std::optional p; }; -REFLECTION(optional_t, p); +YLT_REFL(optional_t, p); struct char_t { char ch; }; -REFLECTION(char_t, ch); +YLT_REFL(char_t, ch); // nested object struct simple_nested_t { int id; person p; }; -REFLECTION(simple_nested_t, id, p); +YLT_REFL(simple_nested_t, id, p); // c array struct arr_t { int arr[2]; }; -REFLECTION(arr_t, arr); +YLT_REFL(arr_t, arr); // std array struct std_array_t { std::array arr; }; -REFLECTION(std_array_t, arr); +YLT_REFL(std_array_t, arr); // vector struct vector_t { std::vector arr; }; -REFLECTION(vector_t, arr); +YLT_REFL(vector_t, arr); struct two_fields_t { std::array a; std::vector v; }; -REFLECTION(two_fields_t, a, v); +YLT_REFL(two_fields_t, a, v); struct map_t { std::map map1; std::unordered_map map2; }; -REFLECTION(map_t, map1, map2); +YLT_REFL(map_t, map1, map2); struct list_t { std::list lst; }; -REFLECTION(list_t, lst); +YLT_REFL(list_t, lst); struct forward_list_t { std::forward_list lst; }; -REFLECTION(forward_list_t, lst); +YLT_REFL(forward_list_t, lst); struct deque_t { std::deque lst; }; -REFLECTION(deque_t, lst); +YLT_REFL(deque_t, lst); struct fixed_name_object_t { std::string name0{}; @@ -103,13 +98,13 @@ struct fixed_name_object_t { std::string name3{}; std::string name4{}; }; -REFLECTION(fixed_name_object_t, name0, name1, name2, name3, name4); +YLT_REFL(fixed_name_object_t, name0, name1, name2, name3, name4); struct nested_object_t { std::vector> v3s{}; std::string id{}; }; -REFLECTION(nested_object_t, v3s, id); +YLT_REFL(nested_object_t, v3s, id); struct another_object_t { std::string string{}; @@ -117,7 +112,7 @@ struct another_object_t { bool boolean{}; nested_object_t nested_object{}; }; -REFLECTION(another_object_t, string, another_string, boolean, nested_object); +YLT_REFL(another_object_t, string, another_string, boolean, nested_object); struct json0_obj_t { // fixed_object_t fixed_object{}; @@ -129,18 +124,18 @@ struct json0_obj_t { bool boolean{}; bool another_bool{}; }; -REFLECTION(json0_obj_t, fixed_name_object, another_object, string_array, string, +YLT_REFL(json0_obj_t, fixed_name_object, another_object, string_array, string, number, boolean, another_bool); struct tuple_t { std::tuple tp; }; -REFLECTION(tuple_t, tp); +YLT_REFL(tuple_t, tp); struct test_double_t { double val; }; -REFLECTION(test_double_t, val); +YLT_REFL(test_double_t, val); struct test_empty_t {}; REFLECTION_EMPTY(test_empty_t); @@ -151,7 +146,7 @@ struct test { long long id; bool error; }; -REFLECTION(test, username, password, id, error); +YLT_REFL(test, username, password, id, error); template void get_value_test_helper(const std::string &json_str, const T &expect) { @@ -188,7 +183,7 @@ struct nest_t { std::variant var; std::variant var2; }; -REFLECTION(nest_t, name, value, var, var2); +YLT_REFL(nest_t, name, value, var, var2); TEST_CASE("test throw while parsing an illegal number") { #if defined(__clang__) || defined(_MSC_VER) || \ @@ -227,7 +222,7 @@ struct my_variant_t { std::string name; std::variant var; }; -REFLECTION(my_variant_t, name, var); +YLT_REFL(my_variant_t, name, var); TEST_CASE("test variant") { std::variant var; @@ -855,103 +850,103 @@ struct some_test_t { int id1; std::string name; }; -REFLECTION(some_test_t, id1, name); +YLT_REFL(some_test_t, id1, name); struct dummy_nest_t { int id; some_test_t t; }; -REFLECTION(dummy_nest_t, id, t); +YLT_REFL(dummy_nest_t, id, t); struct some_test_t1 { int id; std::string name; }; -REFLECTION(some_test_t1, id, name); +YLT_REFL(some_test_t1, id, name); struct dummy_nest_t1 { int id; some_test_t1 t; }; -REFLECTION(dummy_nest_t1, id, t); - -TEST_CASE("partial from json") { - constexpr size_t count1 = - iguana::duplicate_count(); // field + name == 2 - static_assert(count1 == 2); - constexpr size_t count2 = - iguana::duplicate_count(); - static_assert(count2 == 2); - constexpr size_t count3 = - iguana::duplicate_count(); - static_assert(count3 == 2); - - constexpr size_t count5 = iguana::duplicate_count< - dummy_nest_t1, &dummy_nest_t1::id>(); // has duplicate field "id": 1 id - // field + more than one name "id" - static_assert(count5 == 3); - constexpr size_t count4 = - iguana::duplicate_count(); // &person::name is not belong - // to dummy_nest_t - static_assert(count4 == 1); - - dummy_nest_t t{42, {43, "tom"}}; - std::string str; - iguana::to_json(t, str); - - { - dummy_nest_t t1; - iguana::from_json<&dummy_nest_t::id>(t1, str); - CHECK(t1.id == 42); - } - { - dummy_nest_t t1; - iguana::from_json<&dummy_nest_t::t>(t1, str); - CHECK(t1.t.name == "tom"); - } - - { - some_test_t t1; - iguana::from_json<&some_test_t::name, dummy_nest_t>(t1, str); - CHECK(t1.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 index_arr = iguana::indexs_of<&point_t::x, &point_t::y>(); - constexpr auto name_arr = iguana::names_of<&point_t::x, &point_t::y>(); - - CHECK(index_arr == std::array{0, 1}); - CHECK(name_arr == std::array{"x", "y"}); - - 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(); - static_assert(map.size() == 2); - static_assert(map.at("x") == - value_type{std::in_place_index_t<0>{}, &point_t::x}); - static_assert(map.at("y") == - value_type{std::in_place_index_t<1>{}, &point_t::y}); -} +YLT_REFL(dummy_nest_t1, id, t); + +// TEST_CASE("partial from json") { +// constexpr size_t count1 = +// iguana::duplicate_count(); // field + name == 2 +// static_assert(count1 == 2); +// constexpr size_t count2 = +// iguana::duplicate_count(); +// static_assert(count2 == 2); +// constexpr size_t count3 = +// iguana::duplicate_count(); +// static_assert(count3 == 2); + +// constexpr size_t count5 = iguana::duplicate_count< +// dummy_nest_t1, &dummy_nest_t1::id>(); // has duplicate field "id": 1 id +// // field + more than one name "id" +// static_assert(count5 == 3); +// constexpr size_t count4 = +// iguana::duplicate_count(); // &person::name is not belong +// // to dummy_nest_t +// static_assert(count4 == 1); + +// dummy_nest_t t{42, {43, "tom"}}; +// std::string str; +// iguana::to_json(t, str); + +// { +// dummy_nest_t t1; +// iguana::from_json<&dummy_nest_t::id>(t1, str); +// CHECK(t1.id == 42); +// } +// { +// dummy_nest_t t1; +// iguana::from_json<&dummy_nest_t::t>(t1, str); +// CHECK(t1.t.name == "tom"); +// } + +// { +// some_test_t t1; +// iguana::from_json<&some_test_t::name, dummy_nest_t>(t1, str); +// CHECK(t1.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 index_arr = iguana::indexs_of<&point_t::x, &point_t::y>(); +// constexpr auto name_arr = iguana::names_of<&point_t::x, &point_t::y>(); + +// CHECK(index_arr == std::array{0, 1}); +// CHECK(name_arr == std::array{"x", "y"}); + +// 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(); +// static_assert(map.size() == 2); +// static_assert(map.at("x") == +// value_type{std::in_place_index_t<0>{}, &point_t::x}); +// static_assert(map.at("y") == +// value_type{std::in_place_index_t<1>{}, &point_t::y}); +// } enum class Status { STOP = 10, START }; namespace iguana { @@ -1059,7 +1054,7 @@ struct nest { } }; -REFLECTION(nest, name, value); +YLT_REFL(nest, name, value); void example1() { my_space::my_struct v{1, 2, 3}, v2; From 0050e2f41f564c3cded18f88d827232f7e7b72a1 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 26 Aug 2024 11:38:32 +0800 Subject: [PATCH 05/44] fix some compile --- benchmark/json_benchmark.cpp | 30 +++-- benchmark/json_benchmark.h | 252 +++++++++++++++++------------------ example/example.cpp | 8 +- iguana/detail/pb_type.hpp | 1 + iguana/json_reader.hpp | 8 +- iguana/json_util.hpp | 1 - iguana/json_writer.hpp | 20 +-- test/test_json_files.cpp | 3 +- test/test_pb.cpp | 41 +++--- test/test_some.cpp | 14 +- 10 files changed, 194 insertions(+), 184 deletions(-) diff --git a/benchmark/json_benchmark.cpp b/benchmark/json_benchmark.cpp index 8aca099f..c9ac82e2 100644 --- a/benchmark/json_benchmark.cpp +++ b/benchmark/json_benchmark.cpp @@ -1,7 +1,7 @@ #include "json_benchmark.h" class ScopedTimer { -public: + public: ScopedTimer(const char *name) : m_name(name), m_beg(std::chrono::high_resolution_clock::now()) {} ScopedTimer(const char *name, uint64_t &ns) : ScopedTimer(name) { @@ -18,7 +18,7 @@ class ScopedTimer { << std::setw(12) << dur.count() << " ns\n"; } -private: + private: const char *m_name; std::chrono::time_point m_beg; uint64_t *m_ns = nullptr; @@ -60,7 +60,8 @@ struct fixed_name_object_t { std::string name4{}; #ifdef HAS_RAPIDJSON - template void Serialize(Writer &writer) const { + template + void Serialize(Writer &writer) const { writer.StartObject(); writer.String("name0"); writer.String(name0); @@ -76,14 +77,15 @@ struct fixed_name_object_t { } #endif }; -REFLECTION(fixed_name_object_t, name0, name1, name2, name3, name4); +YLT_REFL(fixed_name_object_t, name0, name1, name2, name3, name4); struct nested_object_t { std::vector> v3s{}; std::string id{}; #ifdef HAS_RAPIDJSON - template void Serialize(Writer &writer) const { + template + void Serialize(Writer &writer) const { writer.StartObject(); writer.String("v3s"); writer.StartArray(); @@ -103,7 +105,7 @@ struct nested_object_t { } #endif }; -REFLECTION(nested_object_t, v3s, id); +YLT_REFL(nested_object_t, v3s, id); struct another_object_t { std::string string{}; @@ -112,7 +114,8 @@ struct another_object_t { nested_object_t nested_object{}; #ifdef HAS_RAPIDJSON - template void Serialize(Writer &writer) const { + template + void Serialize(Writer &writer) const { writer.StartObject(); writer.String("string"); writer.String(string); @@ -126,7 +129,7 @@ struct another_object_t { } #endif }; -REFLECTION(another_object_t, string, another_string, boolean, nested_object); +YLT_REFL(another_object_t, string, another_string, boolean, nested_object); struct obj_t { // fixed_object_t fixed_object{}; @@ -139,7 +142,8 @@ struct obj_t { bool another_bool{}; #ifdef HAS_RAPIDJSON - template void Serialize(Writer &writer) const { + template + void Serialize(Writer &writer) const { writer.StartObject(); writer.String("fixed_name_object"); fixed_name_object.Serialize(writer); @@ -167,8 +171,8 @@ struct obj_t { } #endif }; -REFLECTION(obj_t, fixed_name_object, another_object, string_array, string, - number, boolean, another_bool); +YLT_REFL(obj_t, fixed_name_object, another_object, string_array, string, number, + boolean, another_bool); obj_t create_object() { fixed_name_object_t fix_obj = {"James", "Abraham", "Susan", "Frank", @@ -283,7 +287,9 @@ void test_from_json_file() { for (auto &pair : test_map) { auto content = iguana::json_file_content(pair.first); std::visit( - [&](auto &&arg) { test_from_json(pair.first, arg, content, 10); }, + [&](auto &&arg) { + test_from_json(pair.first, arg, content, 10); + }, pair.second); } } diff --git a/benchmark/json_benchmark.h b/benchmark/json_benchmark.h index aaf67857..e623d423 100644 --- a/benchmark/json_benchmark.h +++ b/benchmark/json_benchmark.h @@ -1,13 +1,14 @@ #pragma once -#include "iguana/json_reader.hpp" -#include "iguana/json_writer.hpp" -#include "iguana/value.hpp" #include #include #include #include #include #include + +#include "iguana/json_reader.hpp" +#include "iguana/json_writer.hpp" +#include "iguana/value.hpp" #ifdef HAS_RAPIDJSON #include #include @@ -16,27 +17,27 @@ // canada.json struct property_t { std::string_view name; -}; // Property -REFLECTION(property_t, name); +}; // Property +YLT_REFL(property_t, name); struct polygon_t { std::string_view type; std::vector>> coordinates; -}; // Polygon -REFLECTION(polygon_t, type, coordinates); +}; // Polygon +YLT_REFL(polygon_t, type, coordinates); struct feature_t { std::string_view type; property_t properties; polygon_t geometry; -}; // Feature -REFLECTION(feature_t, type, properties, geometry); +}; // Feature +YLT_REFL(feature_t, type, properties, geometry); struct FeatureCollection { std::string_view type; std::vector features; -}; // FeatureCollection -REFLECTION(FeatureCollection, type, features); +}; // FeatureCollection +YLT_REFL(FeatureCollection, type, features); // apache_builds.json struct jobs_t { @@ -44,16 +45,16 @@ struct jobs_t { std::string_view url; std::string_view color; }; -REFLECTION(jobs_t, name, url, color); +YLT_REFL(jobs_t, name, url, color); struct views_t { std::string_view name; std::string_view url; }; -REFLECTION(views_t, name, url); +YLT_REFL(views_t, name, url); struct apache_empty_t {}; -REFLECTION_EMPTY(apache_empty_t); +YLT_REFL(apache_empty_t); struct apache_builds { std::vector assignedLabels; @@ -72,10 +73,10 @@ struct apache_builds { bool useSecurity; std::vector views; }; -REFLECTION(apache_builds, assignedLabels, mode, nodeDescription, nodeName, - numExecutors, description, jobs, overallLoad, primaryView, - quietingDown, slaveAgentPort, unlabeledLoad, useCrumbs, useSecurity, - views); +YLT_REFL(apache_builds, assignedLabels, mode, nodeDescription, nodeName, + numExecutors, description, jobs, overallLoad, primaryView, + quietingDown, slaveAgentPort, unlabeledLoad, useCrumbs, useSecurity, + views); // citm_catalog.json struct events_value_t { @@ -87,28 +88,28 @@ struct events_value_t { std::optional subjectCode; std::optional subtitle; std::vector topicIds; -}; // events_value_t -REFLECTION(events_value_t, description, id, logo, name, subTopicIds, - subjectCode, subtitle, topicIds); +}; // events_value_t +YLT_REFL(events_value_t, description, id, logo, name, subTopicIds, subjectCode, + subtitle, topicIds); struct prices_element_t { iguana::numeric_str amount; iguana::numeric_str audienceSubCategoryId; iguana::numeric_str seatCategoryId; -}; // prices_element_t -REFLECTION(prices_element_t, amount, audienceSubCategoryId, seatCategoryId); +}; // prices_element_t +YLT_REFL(prices_element_t, amount, audienceSubCategoryId, seatCategoryId); struct areas_element_t { iguana::numeric_str areaId; std::vector blockIds; -}; // areas_element_t -REFLECTION(areas_element_t, areaId, blockIds); +}; // areas_element_t +YLT_REFL(areas_element_t, areaId, blockIds); struct seatCategories_element_t { std::vector areas; iguana::numeric_str seatCategoryId; -}; // seatCategories_element_t -REFLECTION(seatCategories_element_t, areas, seatCategoryId); +}; // seatCategories_element_t +YLT_REFL(seatCategories_element_t, areas, seatCategoryId); struct performances_element_t { iguana::numeric_str eventId; @@ -120,14 +121,14 @@ struct performances_element_t { std::optional seatMapImage; iguana::numeric_str start; std::string_view venueCode; -}; // performances_element_t -REFLECTION(performances_element_t, eventId, id, logo, name, prices, - seatCategories, seatMapImage, start, venueCode); +}; // performances_element_t +YLT_REFL(performances_element_t, eventId, id, logo, name, prices, + seatCategories, seatMapImage, start, venueCode); struct venueNames_t { std::string_view PLEYEL_PLEYEL; -}; // venueNames_t -REFLECTION(venueNames_t, PLEYEL_PLEYEL); +}; // venueNames_t +YLT_REFL(venueNames_t, PLEYEL_PLEYEL); struct citm_object_t { std::unordered_map areaNames; @@ -143,38 +144,38 @@ struct citm_object_t { std::unordered_map> topicSubTopics; std::optional venueNames; -}; // citm_object_t -REFLECTION(citm_object_t, areaNames, audienceSubCategoryNames, blockNames, - events, performances, seatCategoryNames, subTopicNames, subjectNames, - topicNames, topicSubTopics, venueNames); +}; // citm_object_t +YLT_REFL(citm_object_t, areaNames, audienceSubCategoryNames, blockNames, events, + performances, seatCategoryNames, subTopicNames, subjectNames, + topicNames, topicSubTopics, venueNames); // gsoc-2018.json struct sponsor_t { - std::string_view type; //@ + std::string_view type; //@ std::string_view name; std::string_view disambiguatingDescription; std::string_view description; std::string_view url; std::string_view logo; }; -REFLECTION(sponsor_t, type, name, disambiguatingDescription, description, url, - logo); +YLT_REFL(sponsor_t, type, name, disambiguatingDescription, description, url, + logo); struct author_t { - std::string_view type; //@ + std::string_view type; //@ std::string_view name; }; -REFLECTION(author_t, type, name); +YLT_REFL(author_t, type, name); struct gsoc_element_t { - std::string_view context; //@ - std::string_view type; //@ + std::string_view context; //@ + std::string_view type; //@ std::string_view name; std::string_view description; sponsor_t sponsor; author_t author; }; -REFLECTION(gsoc_element_t, context, type, name, description, sponsor, author); +YLT_REFL(gsoc_element_t, context, type, name, description, sponsor, author); using gsoc_object_t = std::map; @@ -184,7 +185,7 @@ struct mesh_element_t { std::vector usedBones; std::vector vertexRange; }; -REFLECTION(mesh_element_t, indexRange, usedBones, vertexRange); +YLT_REFL(mesh_element_t, indexRange, usedBones, vertexRange); struct mesh_t { std::vector batches; @@ -196,8 +197,8 @@ struct mesh_t { std::vector positions; std::vector tex0; }; -REFLECTION(mesh_t, batches, colors, indices, influences, morphTargets, normals, - positions, tex0); +YLT_REFL(mesh_t, batches, colors, indices, influences, morphTargets, normals, + positions, tex0); // random.json struct friend_t { @@ -205,7 +206,7 @@ struct friend_t { std::string_view name; std::string_view phone; }; -REFLECTION(friend_t, id, name, phone); +YLT_REFL(friend_t, id, name, phone); struct random_element_t { iguana::numeric_str id; @@ -220,8 +221,8 @@ struct random_element_t { std::vector friends; std::string_view field; }; -REFLECTION(random_element_t, id, avatar, age, admin, name, company, phone, - email, birthDate, friends, field); +YLT_REFL(random_element_t, id, avatar, age, admin, name, company, phone, email, + birthDate, friends, field); struct random_t { iguana::numeric_str id; @@ -229,7 +230,7 @@ struct random_t { iguana::numeric_str total; std::vector result; }; -REFLECTION(random_t, id, jsonrpc, total, result); +YLT_REFL(random_t, id, jsonrpc, total, result); // github_events.json namespace githubEvents { @@ -250,9 +251,9 @@ struct user_t { std::string_view followers_url; std::string_view following_url; }; -REFLECTION(user_t, gists_url, gravatar_id, url, type, avatar_url, - subscriptions_url, organizations_url, received_events_url, repos_url, - login, starred_url, id, events_url, followers_url, following_url); +YLT_REFL(user_t, gists_url, gravatar_id, url, type, avatar_url, + subscriptions_url, organizations_url, received_events_url, repos_url, + login, starred_url, id, events_url, followers_url, following_url); struct page_t { std::string_view page_name; @@ -262,14 +263,14 @@ struct page_t { std::optional summary; std::string_view action; }; -REFLECTION(page_t, page_name, html_url, title, sha, summary, action); +YLT_REFL(page_t, page_name, html_url, title, sha, summary, action); struct pull_request_t { std::optional html_url; std::optional patch_url; std::optional diff_url; }; -REFLECTION(pull_request_t, html_url, patch_url, diff_url); +YLT_REFL(pull_request_t, html_url, patch_url, diff_url); struct forkee_t { std::string_view full_name; @@ -337,18 +338,18 @@ struct forkee_t { iguana::numeric_str watchers; std::string_view git_url; }; -REFLECTION(forkee_t, full_name, stargazers_url, clone_url, fork, url, tags_url, - description, merges_url, forks, language, ___private, archive_url, - collaborators_url, languages_url, owner, git_refs_url, labels_url, - pushed_at, html_url, trees_url, forks_url, commits_url, branches_url, - notifications_url, created_at, has_issues, blobs_url, issues_url, - open_issues, contents_url, name, statuses_url, assignees_url, - forks_count, updated_at, issue_events_url, ssh_url, subscribers_url, - mirror_url, ___public, has_wiki, git_commits_url, downloads_url, id, - pulls_url, has_downloads, issue_comment_url, watchers_count, - homepage, hooks_url, subscription_url, milestones_url, events_url, - svn_url, git_tags_url, teams_url, comments_url, open_issues_count, - keys_url, contributors_url, size, watchers, git_url, compare_url); +YLT_REFL(forkee_t, full_name, stargazers_url, clone_url, fork, url, tags_url, + description, merges_url, forks, language, ___private, archive_url, + collaborators_url, languages_url, owner, git_refs_url, labels_url, + pushed_at, html_url, trees_url, forks_url, commits_url, branches_url, + notifications_url, created_at, has_issues, blobs_url, issues_url, + open_issues, contents_url, name, statuses_url, assignees_url, + forks_count, updated_at, issue_events_url, ssh_url, subscribers_url, + mirror_url, ___public, has_wiki, git_commits_url, downloads_url, id, + pulls_url, has_downloads, issue_comment_url, watchers_count, homepage, + hooks_url, subscription_url, milestones_url, events_url, svn_url, + git_tags_url, teams_url, comments_url, open_issues_count, keys_url, + contributors_url, size, watchers, git_url, compare_url); struct issue_t { user_t user; @@ -371,9 +372,9 @@ struct issue_t { std::string_view events_url; std::string_view comments_url; }; -REFLECTION(issue_t, user, url, labels, html_url, labels_url, pull_request, - created_at, closed_at, milestone, title, body, updated_at, number, - state, assignee, id, comments, events_url, comments_url); +YLT_REFL(issue_t, user, url, labels, html_url, labels_url, pull_request, + created_at, closed_at, milestone, title, body, updated_at, number, + state, assignee, id, comments, events_url, comments_url); struct comment_t { user_t user; @@ -384,7 +385,7 @@ struct comment_t { std::string_view updated_at; iguana::numeric_str id; }; -REFLECTION(comment_t, user, url, issue_url, created_at, body, updated_at, id); +YLT_REFL(comment_t, user, url, issue_url, created_at, body, updated_at, id); struct actor_org_t { std::string_view gravatar_id; @@ -393,20 +394,20 @@ struct actor_org_t { std::string_view url; iguana::numeric_str id; }; -REFLECTION(actor_org_t, gravatar_id, login, avatar_url, url, id); +YLT_REFL(actor_org_t, gravatar_id, login, avatar_url, url, id); struct repo_t { std::string_view url; iguana::numeric_str id; std::string_view name; }; -REFLECTION(repo_t, url, id, name); +YLT_REFL(repo_t, url, id, name); struct author_t { std::string_view email; std::string_view name; }; -REFLECTION(author_t, email, name); +YLT_REFL(author_t, email, name); struct commit_t { std::string_view url; @@ -415,7 +416,7 @@ struct commit_t { std::string_view sha; author_t author; }; -REFLECTION(commit_t, url, message, distinct, sha, author); +YLT_REFL(commit_t, url, message, distinct, sha, author); struct payload_t { std::optional> commits; @@ -435,9 +436,9 @@ struct payload_t { std::optional ref_type; }; -REFLECTION(payload_t, commits, distinct_size, ref, push_id, head, before, size, - forkee, pages, action, comment, issue, description, master_branch, - ref_type); +YLT_REFL(payload_t, commits, distinct_size, ref, push_id, head, before, size, + forkee, pages, action, comment, issue, description, master_branch, + ref_type); struct event_t { std::string_view type; @@ -449,10 +450,10 @@ struct event_t { payload_t payload; std::string_view id; }; -REFLECTION(event_t, type, created_at, actor, repo, ___public, org, payload, id); +YLT_REFL(event_t, type, created_at, actor, repo, ___public, org, payload, id); using events_t = std::vector; -} // namespace githubEvents +} // namespace githubEvents namespace marine_ik { struct image_element_t { @@ -460,14 +461,14 @@ struct image_element_t { std::string_view uuid; std::string_view name; }; -REFLECTION(image_element_t, url, uuid, name); +YLT_REFL(image_element_t, url, uuid, name); struct item_t { std::string_view name; std::string_view type; std::string_view uuid; }; -REFLECTION(item_t, name, type, uuid); +YLT_REFL(item_t, name, type, uuid); struct key_element_t { std::array rot; @@ -475,13 +476,13 @@ struct key_element_t { std::array scl; std::array pos; }; -REFLECTION(key_element_t, rot, time, scl, pos); +YLT_REFL(key_element_t, rot, time, scl, pos); struct hierarchy_element_t { iguana::numeric_str parent; std::vector keys; }; -REFLECTION(hierarchy_element_t, parent, keys); +YLT_REFL(hierarchy_element_t, parent, keys); struct geo_anim_element_t { std::vector hierarchy; @@ -489,7 +490,7 @@ struct geo_anim_element_t { iguana::numeric_str fps{}; std::string_view name; }; -REFLECTION(geo_anim_element_t, hierarchy, length, fps, name); +YLT_REFL(geo_anim_element_t, hierarchy, length, fps, name); struct bone_element_t { iguana::numeric_str parent; @@ -498,7 +499,7 @@ struct bone_element_t { std::array scl; std::string_view name; }; -REFLECTION(bone_element_t, parent, pos, rotq, scl, name); +YLT_REFL(bone_element_t, parent, pos, rotq, scl, name); struct geo_meta_data_t { iguana::numeric_str uvs; @@ -509,8 +510,8 @@ struct geo_meta_data_t { iguana::numeric_str bones; iguana::numeric_str vertices; }; -REFLECTION(geo_meta_data_t, uvs, version, faces, generator, normals, bones, - vertices); +YLT_REFL(geo_meta_data_t, uvs, version, faces, generator, normals, bones, + vertices); struct geo_data_t { std::vector> uvs; @@ -525,15 +526,15 @@ struct geo_data_t { std::vector bones; std::vector faces; }; -REFLECTION(geo_data_t, uvs, animations, vertices, metadata, name, skinWeights, - skinIndices, influencesPerVertex, normals, bones, faces); +YLT_REFL(geo_data_t, uvs, animations, vertices, metadata, name, skinWeights, + skinIndices, influencesPerVertex, normals, bones, faces); struct geometry_element_t { std::string_view type; std::string_view uuid; geo_data_t data; }; -REFLECTION(geometry_element_t, type, uuid, data); +YLT_REFL(geometry_element_t, type, uuid, data); struct texture_element_t { std::array repeat; @@ -546,8 +547,8 @@ struct texture_element_t { std::string_view uuid; iguana::numeric_str magFilter{}; }; -REFLECTION(texture_element_t, repeat, wrap, anisotropy, image, name, mapping, - minFilter, uuid, magFilter); +YLT_REFL(texture_element_t, repeat, wrap, anisotropy, image, name, mapping, + minFilter, uuid, magFilter); struct meta_data_t { std::string_view sourceFile; @@ -555,7 +556,7 @@ struct meta_data_t { std::string_view type; iguana::numeric_str version{}; }; -REFLECTION(meta_data_t, sourceFile, generator, type, version); +YLT_REFL(meta_data_t, sourceFile, generator, type, version); struct material_element_t : item_t { iguana::numeric_str vertexColors{}; @@ -569,9 +570,9 @@ struct material_element_t : item_t { bool depthWrite{}; iguana::numeric_str specular{}; }; -REFLECTION(material_element_t, vertexColors, name, type, uuid, blending, map, - transparent, depthTest, color, shininess, emissive, depthWrite, - specular); +YLT_REFL(material_element_t, vertexColors, name, type, uuid, blending, map, + transparent, depthTest, color, shininess, emissive, depthWrite, + specular); struct obj_child_t : item_t { std::array matrix; @@ -581,8 +582,8 @@ struct obj_child_t : item_t { bool receiveShadow{}; std::string_view geometry; }; -REFLECTION(obj_child_t, name, uuid, matrix, visible, type, material, castShadow, - receiveShadow, geometry); +YLT_REFL(obj_child_t, name, uuid, matrix, visible, type, material, castShadow, + receiveShadow, geometry); struct object_t { std::vector children; @@ -590,14 +591,14 @@ struct object_t { std::array matrix; std::string_view uuid; }; -REFLECTION(object_t, children, type, matrix, uuid); +YLT_REFL(object_t, children, type, matrix, uuid); struct animation_element_t { std::vector tracks; iguana::numeric_str fps; std::string_view name; }; -REFLECTION(animation_element_t, tracks, fps, name); +YLT_REFL(animation_element_t, tracks, fps, name); struct marine_ik_t { std::vector images; @@ -608,9 +609,9 @@ struct marine_ik_t { object_t object; std::vector animations; }; -REFLECTION(marine_ik_t, images, geometries, textures, metadata, materials, - object, animations); -} // namespace marine_ik +YLT_REFL(marine_ik_t, images, geometries, textures, metadata, materials, object, + animations); +} // namespace marine_ik // instruments.json struct sample_element { @@ -630,9 +631,9 @@ struct sample_element { iguana::numeric_str vibrato_type; iguana::numeric_str volume; }; -REFLECTION(sample_element, c5_samplerate, global_volume, legacy_filename, - length, loop_end, loop_start, name, pan, sustain_end, sustain_start, - vibrato_depth, vibrato_rate, vibrato_sweep, vibrato_type, volume); +YLT_REFL(sample_element, c5_samplerate, global_volume, legacy_filename, length, + loop_end, loop_start, name, pan, sustain_end, sustain_start, + vibrato_depth, vibrato_rate, vibrato_sweep, vibrato_type, volume); struct data_t { iguana::numeric_str channel; @@ -644,7 +645,7 @@ struct data_t { iguana::numeric_str volcmd; iguana::numeric_str volval; }; -REFLECTION(data_t, channel, fxcmd, fxparam, instr, note, row, volcmd, volval); +YLT_REFL(data_t, channel, fxcmd, fxparam, instr, note, row, volcmd, volval); struct pattern_element { std::optional> data; @@ -653,13 +654,13 @@ struct pattern_element { iguana::numeric_str rows_per_beat; iguana::numeric_str rows_per_measure; }; -REFLECTION(pattern_element, data, name, rows, rows_per_beat, rows_per_measure); +YLT_REFL(pattern_element, data, name, rows, rows_per_beat, rows_per_measure); struct node_t { iguana::numeric_str tick; iguana::numeric_str value; }; -REFLECTION(node_t, tick, value); +YLT_REFL(node_t, tick, value); struct panning_envelope_t { iguana::numeric_str loop_end; @@ -669,8 +670,8 @@ struct panning_envelope_t { iguana::numeric_str sustain_end; iguana::numeric_str sustain_start; }; -REFLECTION(panning_envelope_t, loop_end, loop_start, nodes, release_node, - sustain_end, sustain_start); +YLT_REFL(panning_envelope_t, loop_end, loop_start, nodes, release_node, + sustain_end, sustain_start); struct instrument_element { iguana::numeric_str default_filter_cutoff; @@ -709,17 +710,16 @@ struct instrument_element { iguana::numeric_str volume_ramp_down; iguana::numeric_str volume_ramp_up; }; -REFLECTION(instrument_element, default_filter_cutoff, - default_filter_cutoff_enabled, default_filter_mode, - default_filter_resonance, default_filter_resonance_enabled, - default_pan, duplicate_check_type, duplicate_note_action, fadeout, - global_volume, graph_insert, legacy_filename, midi_bank, - midi_channel, midi_drum_set, midi_program, name, new_note_action, - note_map, panning_envelope, pitch_envelope, pitch_pan_center, - pitch_pan_separation, pitch_to_tempo_lock, random_cutoff_weight, - random_pan_weight, random_resonance_weight, random_volume_weight, - sample_map, tuning, volume_envelope, volume_ramp_down, - volume_ramp_up); +YLT_REFL(instrument_element, default_filter_cutoff, + default_filter_cutoff_enabled, default_filter_mode, + default_filter_resonance, default_filter_resonance_enabled, + default_pan, duplicate_check_type, duplicate_note_action, fadeout, + global_volume, graph_insert, legacy_filename, midi_bank, midi_channel, + midi_drum_set, midi_program, name, new_note_action, note_map, + panning_envelope, pitch_envelope, pitch_pan_center, + pitch_pan_separation, pitch_to_tempo_lock, random_cutoff_weight, + random_pan_weight, random_resonance_weight, random_volume_weight, + sample_map, tuning, volume_envelope, volume_ramp_down, volume_ramp_up); struct instruments_t { std::optional graphstate; @@ -732,5 +732,5 @@ struct instruments_t { std::vector samples; iguana::numeric_str version; }; -REFLECTION(instruments_t, graphstate, instruments, message, name, orderlist, - patterns, pluginstate, samples, version); +YLT_REFL(instruments_t, graphstate, instruments, message, name, orderlist, + patterns, pluginstate, samples, version); diff --git a/example/example.cpp b/example/example.cpp index d5b65522..f7cdd06e 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -8,19 +8,19 @@ struct person { std::string name; int age; }; -REFLECTION(person, name, age) +YLT_REFL(person, name, age) struct one_t { int id; }; -REFLECTION(one_t, id); +YLT_REFL(one_t, id); struct two { std::string name; one_t one; int age; }; -REFLECTION(two, name, one, age); +YLT_REFL(two, name, one, age); struct composit_t { int a; @@ -31,7 +31,7 @@ struct composit_t { double f; std::vector g; }; -REFLECTION(composit_t, a, b, c, d, e, f, g); +YLT_REFL(composit_t, a, b, c, d, e, f, g); void test_json() { person p; diff --git a/iguana/detail/pb_type.hpp b/iguana/detail/pb_type.hpp index 2d17cb8e..d9a2c791 100644 --- a/iguana/detail/pb_type.hpp +++ b/iguana/detail/pb_type.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include namespace iguana { diff --git a/iguana/json_reader.hpp b/iguana/json_reader.hpp index 769c05a0..a65039c8 100644 --- a/iguana/json_reader.hpp +++ b/iguana/json_reader.hpp @@ -96,10 +96,10 @@ IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { } } -template , int> = 0> -IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { - from_json_impl(value.val, it, end); -} +// template , int> = +// 0> IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { +// from_json_impl(value.val, it, end); +// } template , int> = 0> IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { diff --git a/iguana/json_util.hpp b/iguana/json_util.hpp index 5887599f..f1bf3a33 100644 --- a/iguana/json_util.hpp +++ b/iguana/json_util.hpp @@ -3,7 +3,6 @@ #pragma once -#include "detail/pb_type.hpp" #include "util.hpp" #include "value.hpp" diff --git a/iguana/json_writer.hpp b/iguana/json_writer.hpp index 595a4b6d..c56e4c24 100644 --- a/iguana/json_writer.hpp +++ b/iguana/json_writer.hpp @@ -76,11 +76,11 @@ IGUANA_INLINE void to_json_impl(Stream &ss, T value) { ss.append(temp, p - temp); } -template , int> = 0> -IGUANA_INLINE void to_json_impl(Stream &ss, T value) { - to_json_impl(ss, value.val); -} +// template , int> = 0> +// IGUANA_INLINE void to_json_impl(Stream &ss, T value) { +// to_json_impl(ss, value.val); +// } template , int> = 0> @@ -109,11 +109,11 @@ IGUANA_INLINE void render_key(Stream &ss, const T &t) { ss.push_back('"'); } -template , int> = 0> -IGUANA_INLINE void render_key(Stream &ss, const T &t) { - render_key(ss, t.val); -} +// template , int> = 0> +// IGUANA_INLINE void render_key(Stream &ss, const T &t) { +// render_key(ss, t.val); +// } template , int> = 0> diff --git a/test/test_json_files.cpp b/test/test_json_files.cpp index 1cf61a10..f7751a03 100644 --- a/test/test_json_files.cpp +++ b/test/test_json_files.cpp @@ -2,7 +2,6 @@ #include #include -#include "iguana/reflection.hpp" #include "iguana/value.hpp" #define DOCTEST_CONFIG_IMPLEMENT #include @@ -13,7 +12,7 @@ #include #include "doctest.h" -#include "test_headers.h" +#include "test_headers1.h" TEST_CASE("test canada.json") { std::cout << std::filesystem::current_path().string() << "\n"; diff --git a/test/test_pb.cpp b/test/test_pb.cpp index 7e85aa1b..d09ee6ed 100644 --- a/test/test_pb.cpp +++ b/test/test_pb.cpp @@ -5,6 +5,7 @@ #include #include "iguana/pb_writer.hpp" +#include "iguana/reflection.hpp" #define DOCTEST_CONFIG_IMPLEMENT #include "doctest.h" @@ -108,7 +109,7 @@ struct test_pb_st6 { }; REFLECTION(test_pb_st6, x, y); -struct pair_t : public iguana::base_impl { +struct pair_t : public iguana::base_impl { pair_t() = default; pair_t(int a, int b) : x(a), y(b) {} int x; @@ -242,7 +243,7 @@ struct numer_st PUBLIC(numer_st) { }; REFLECTION(numer_st, a, b, c); -struct MyPerson : public iguana::base_impl { +struct MyPerson : public iguana::base_impl { MyPerson() = default; MyPerson(std::string s, int d) : name(s), age(d) {} std::string name; @@ -397,19 +398,19 @@ TEST_CASE("test reflection") { std::any_cast>(mvariant_any); assert(mvariant == temp_variant); } - { - // to_json is an const member_function now - MyPerson const p1{"xiaoming", 10}; - std::string str; - p1.to_json(str); + // { + // // to_json is an const member_function now + // MyPerson const p1{"xiaoming", 10}; + // std::string str; + // p1.to_json(str); - // p1.to_pb(str); // compile failed + // // p1.to_pb(str); // compile failed - MyPerson p2; - p2.from_json(str); + // MyPerson p2; + // p2.from_json(str); - assert(p1 == p2); - } + // assert(p1 == p2); + // } { auto t = iguana::create_instance("pair_t"); t->set_field_value("x", 12); @@ -437,15 +438,15 @@ TEST_CASE("test reflection") { CHECK(st->x == s.x); CHECK(st->y == s.y); - std::string json; - t->to_json(json); - std::cout << json << "\n"; + // std::string json; + // t->to_json(json); + // std::cout << json << "\n"; - s = {}; - s.from_json(json); - std::cout << s.x << " " << s.y << "\n"; - CHECK(st->x == s.x); - CHECK(st->y == s.y); + // s = {}; + // s.from_json(json); + // std::cout << s.x << " " << s.y << "\n"; + // CHECK(st->x == s.x); + // CHECK(st->y == s.y); std::string yaml; t->to_yaml(yaml); diff --git a/test/test_some.cpp b/test/test_some.cpp index e844551c..f634b102 100644 --- a/test/test_some.cpp +++ b/test/test_some.cpp @@ -1,5 +1,4 @@ #define DOCTEST_CONFIG_IMPLEMENT -#include #include #include #include @@ -125,7 +124,7 @@ struct json0_obj_t { bool another_bool{}; }; YLT_REFL(json0_obj_t, fixed_name_object, another_object, string_array, string, - number, boolean, another_bool); + number, boolean, another_bool); struct tuple_t { std::tuple tp; @@ -883,12 +882,15 @@ YLT_REFL(dummy_nest_t1, id, t); // static_assert(count3 == 2); // constexpr size_t count5 = iguana::duplicate_count< -// dummy_nest_t1, &dummy_nest_t1::id>(); // has duplicate field "id": 1 id -// // field + more than one name "id" +// dummy_nest_t1, &dummy_nest_t1::id>(); // has duplicate field "id": 1 +// id +// // field + more than one name +// "id" // static_assert(count5 == 3); // constexpr size_t count4 = // iguana::duplicate_count(); // &person::name is not belong +// &person::name>(); // &person::name is not +// belong // // to dummy_nest_t // static_assert(count4 == 1); @@ -1034,6 +1036,8 @@ struct my_struct { } }; +void ylt_custom_reflect(my_struct *) {} + template inline void to_json_impl(Stream &s, const my_struct &t) { iguana::to_json(*(int(*)[3]) & t, s); From df852d03e5ff39965a0c97254492b35762868421 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 26 Aug 2024 11:40:38 +0800 Subject: [PATCH 06/44] rename --- test/test_headers.h | 253 +++++++------ test/test_headers1.h | 757 --------------------------------------- test/test_json_files.cpp | 2 +- test/unit_test.cpp | 2 +- 4 files changed, 128 insertions(+), 886 deletions(-) delete mode 100644 test/test_headers1.h diff --git a/test/test_headers.h b/test/test_headers.h index d921cee4..a61c2444 100644 --- a/test/test_headers.h +++ b/test/test_headers.h @@ -3,7 +3,7 @@ #include #include -#include "iguana/reflection.hpp" +#include "iguana/ylt/reflection/user_reflect_macro.hpp" struct MyClass1 { double member0; @@ -16,7 +16,7 @@ struct MyClass1 { member2 == rhs.member2 && member3 == rhs.member3; } }; -REFLECTION(MyClass1, member0, member1, member2, member3); +YLT_REFL(MyClass1, member0, member1, member2, member3); struct MyClass2 { unsigned member_unsigned0; @@ -29,38 +29,38 @@ struct MyClass2 { member_signed == rhs.member_signed; } }; -REFLECTION(MyClass2, member_unsigned0, member_unsigned1, member_signed); +YLT_REFL(MyClass2, member_unsigned0, member_unsigned1, member_signed); struct person { std::string name; int age; }; -REFLECTION(person, name, age); +YLT_REFL(person, name, age); // canada.json struct property_t { std::string name; -}; // Property -REFLECTION(property_t, name); +}; // Property +YLT_REFL(property_t, name); struct polygon_t { std::string type; std::vector>> coordinates; -}; // Polygon -REFLECTION(polygon_t, type, coordinates); +}; // Polygon +YLT_REFL(polygon_t, type, coordinates); struct feature_t { std::string type; property_t properties; polygon_t geometry; -}; // Feature -REFLECTION(feature_t, type, properties, geometry); +}; // Feature +YLT_REFL(feature_t, type, properties, geometry); struct FeatureCollection { std::string type; std::vector features; -}; // FeatureCollection -REFLECTION(FeatureCollection, type, features); +}; // FeatureCollection +YLT_REFL(FeatureCollection, type, features); // apache_builds.json struct jobs_t { @@ -68,16 +68,16 @@ struct jobs_t { std::string url; std::string color; }; -REFLECTION(jobs_t, name, url, color); +YLT_REFL(jobs_t, name, url, color); struct views_t { std::string name; std::string url; }; -REFLECTION(views_t, name, url); +YLT_REFL(views_t, name, url); struct apache_empty_t {}; -REFLECTION_EMPTY(apache_empty_t); +YLT_REFL(apache_empty_t); struct apache_builds { std::vector assignedLabels; @@ -96,10 +96,10 @@ struct apache_builds { bool useSecurity; std::vector views; }; -REFLECTION(apache_builds, assignedLabels, mode, nodeDescription, nodeName, - numExecutors, description, jobs, overallLoad, primaryView, - quietingDown, slaveAgentPort, unlabeledLoad, useCrumbs, useSecurity, - views); +YLT_REFL(apache_builds, assignedLabels, mode, nodeDescription, nodeName, + numExecutors, description, jobs, overallLoad, primaryView, + quietingDown, slaveAgentPort, unlabeledLoad, useCrumbs, useSecurity, + views); // citm_catalog.json struct events_value_t { @@ -111,28 +111,28 @@ struct events_value_t { std::optional subjectCode; std::optional subtitle; std::vector topicIds; -}; // events_value_t -REFLECTION(events_value_t, description, id, logo, name, subTopicIds, - subjectCode, subtitle, topicIds); +}; // events_value_t +YLT_REFL(events_value_t, description, id, logo, name, subTopicIds, subjectCode, + subtitle, topicIds); struct prices_element_t { std::int64_t amount; std::int64_t audienceSubCategoryId; std::int64_t seatCategoryId; -}; // prices_element_t -REFLECTION(prices_element_t, amount, audienceSubCategoryId, seatCategoryId); +}; // prices_element_t +YLT_REFL(prices_element_t, amount, audienceSubCategoryId, seatCategoryId); struct areas_element_t { std::int64_t areaId; std::vector blockIds; -}; // areas_element_t -REFLECTION(areas_element_t, areaId, blockIds); +}; // areas_element_t +YLT_REFL(areas_element_t, areaId, blockIds); struct seatCategories_element_t { std::vector areas; std::int64_t seatCategoryId; -}; // seatCategories_element_t -REFLECTION(seatCategories_element_t, areas, seatCategoryId); +}; // seatCategories_element_t +YLT_REFL(seatCategories_element_t, areas, seatCategoryId); struct performances_element_t { std::int64_t eventId; @@ -144,14 +144,14 @@ struct performances_element_t { std::optional seatMapImage; std::int64_t start; std::string venueCode; -}; // performances_element_t -REFLECTION(performances_element_t, eventId, id, logo, name, prices, - seatCategories, seatMapImage, start, venueCode); +}; // performances_element_t +YLT_REFL(performances_element_t, eventId, id, logo, name, prices, + seatCategories, seatMapImage, start, venueCode); struct venueNames_t { std::string PLEYEL_PLEYEL; -}; // venueNames_t -REFLECTION(venueNames_t, PLEYEL_PLEYEL); +}; // venueNames_t +YLT_REFL(venueNames_t, PLEYEL_PLEYEL); struct citm_object_t { std::unordered_map areaNames; @@ -165,38 +165,38 @@ struct citm_object_t { std::unordered_map topicNames; std::unordered_map> topicSubTopics; std::optional venueNames; -}; // citm_object_t -REFLECTION(citm_object_t, areaNames, audienceSubCategoryNames, blockNames, - events, performances, seatCategoryNames, subTopicNames, subjectNames, - topicNames, topicSubTopics, venueNames); +}; // citm_object_t +YLT_REFL(citm_object_t, areaNames, audienceSubCategoryNames, blockNames, events, + performances, seatCategoryNames, subTopicNames, subjectNames, + topicNames, topicSubTopics, venueNames); // gsoc-2018.json struct sponsor_t { - std::string type; //@ + std::string type; //@ std::string name; std::string disambiguatingDescription; std::string description; std::string url; std::string logo; }; -REFLECTION(sponsor_t, type, name, disambiguatingDescription, description, url, - logo); +YLT_REFL(sponsor_t, type, name, disambiguatingDescription, description, url, + logo); struct author_t { - std::string type; //@ + std::string type; //@ std::string name; }; -REFLECTION(author_t, type, name); +YLT_REFL(author_t, type, name); struct gsoc_element_t { - std::string context; //@ - std::string type; //@ + std::string context; //@ + std::string type; //@ std::string name; std::string description; sponsor_t sponsor; author_t author; }; -REFLECTION(gsoc_element_t, context, type, name, description, sponsor, author); +YLT_REFL(gsoc_element_t, context, type, name, description, sponsor, author); using gsoc_object_t = std::map; @@ -206,7 +206,7 @@ struct mesh_element_t { std::vector usedBones; std::vector vertexRange; }; -REFLECTION(mesh_element_t, indexRange, usedBones, vertexRange); +YLT_REFL(mesh_element_t, indexRange, usedBones, vertexRange); struct mesh_t { std::vector batches; @@ -218,8 +218,8 @@ struct mesh_t { std::vector positions; std::vector tex0; }; -REFLECTION(mesh_t, batches, colors, indices, influences, morphTargets, normals, - positions, tex0); +YLT_REFL(mesh_t, batches, colors, indices, influences, morphTargets, normals, + positions, tex0); // random.json struct friend_t { @@ -227,7 +227,7 @@ struct friend_t { std::string name; std::string phone; }; -REFLECTION(friend_t, id, name, phone); +YLT_REFL(friend_t, id, name, phone); struct random_element_t { int id; @@ -242,8 +242,8 @@ struct random_element_t { std::vector friends; std::string field; }; -REFLECTION(random_element_t, id, avatar, age, admin, name, company, phone, - email, birthDate, friends, field); +YLT_REFL(random_element_t, id, avatar, age, admin, name, company, phone, email, + birthDate, friends, field); struct random_t { int id; @@ -251,7 +251,7 @@ struct random_t { int total; std::vector result; }; -REFLECTION(random_t, id, jsonrpc, total, result); +YLT_REFL(random_t, id, jsonrpc, total, result); // github_events.json namespace githubEvents { @@ -272,9 +272,9 @@ struct user_t { std::string followers_url; std::string following_url; }; -REFLECTION(user_t, gists_url, gravatar_id, url, type, avatar_url, - subscriptions_url, organizations_url, received_events_url, repos_url, - login, starred_url, id, events_url, followers_url, following_url); +YLT_REFL(user_t, gists_url, gravatar_id, url, type, avatar_url, + subscriptions_url, organizations_url, received_events_url, repos_url, + login, starred_url, id, events_url, followers_url, following_url); struct page_t { std::string page_name; @@ -284,14 +284,14 @@ struct page_t { std::optional summary; std::string action; }; -REFLECTION(page_t, page_name, html_url, title, sha, summary, action); +YLT_REFL(page_t, page_name, html_url, title, sha, summary, action); struct pull_request_t { std::optional html_url; std::optional patch_url; std::optional diff_url; }; -REFLECTION(pull_request_t, html_url, patch_url, diff_url); +YLT_REFL(pull_request_t, html_url, patch_url, diff_url); struct forkee_t { std::string full_name; @@ -359,18 +359,18 @@ struct forkee_t { int watchers; std::string git_url; }; -REFLECTION(forkee_t, full_name, stargazers_url, clone_url, fork, url, tags_url, - description, merges_url, forks, language, ___private, archive_url, - collaborators_url, languages_url, owner, git_refs_url, labels_url, - pushed_at, html_url, trees_url, forks_url, commits_url, branches_url, - notifications_url, created_at, has_issues, blobs_url, issues_url, - open_issues, contents_url, name, statuses_url, assignees_url, - forks_count, updated_at, issue_events_url, ssh_url, subscribers_url, - mirror_url, ___public, has_wiki, git_commits_url, downloads_url, id, - pulls_url, has_downloads, issue_comment_url, watchers_count, - homepage, hooks_url, subscription_url, milestones_url, events_url, - svn_url, git_tags_url, teams_url, comments_url, open_issues_count, - keys_url, contributors_url, size, watchers, git_url, compare_url); +YLT_REFL(forkee_t, full_name, stargazers_url, clone_url, fork, url, tags_url, + description, merges_url, forks, language, ___private, archive_url, + collaborators_url, languages_url, owner, git_refs_url, labels_url, + pushed_at, html_url, trees_url, forks_url, commits_url, branches_url, + notifications_url, created_at, has_issues, blobs_url, issues_url, + open_issues, contents_url, name, statuses_url, assignees_url, + forks_count, updated_at, issue_events_url, ssh_url, subscribers_url, + mirror_url, ___public, has_wiki, git_commits_url, downloads_url, id, + pulls_url, has_downloads, issue_comment_url, watchers_count, homepage, + hooks_url, subscription_url, milestones_url, events_url, svn_url, + git_tags_url, teams_url, comments_url, open_issues_count, keys_url, + contributors_url, size, watchers, git_url, compare_url); struct issue_t { user_t user; @@ -393,9 +393,9 @@ struct issue_t { std::string events_url; std::string comments_url; }; -REFLECTION(issue_t, user, url, labels, html_url, labels_url, pull_request, - created_at, closed_at, milestone, title, body, updated_at, number, - state, assignee, id, comments, events_url, comments_url); +YLT_REFL(issue_t, user, url, labels, html_url, labels_url, pull_request, + created_at, closed_at, milestone, title, body, updated_at, number, + state, assignee, id, comments, events_url, comments_url); struct comment_t { user_t user; @@ -406,7 +406,7 @@ struct comment_t { std::string updated_at; int id; }; -REFLECTION(comment_t, user, url, issue_url, created_at, body, updated_at, id); +YLT_REFL(comment_t, user, url, issue_url, created_at, body, updated_at, id); struct actor_org_t { std::string gravatar_id; @@ -415,20 +415,20 @@ struct actor_org_t { std::string url; int id; }; -REFLECTION(actor_org_t, gravatar_id, login, avatar_url, url, id); +YLT_REFL(actor_org_t, gravatar_id, login, avatar_url, url, id); struct repo_t { std::string url; int id; std::string name; }; -REFLECTION(repo_t, url, id, name); +YLT_REFL(repo_t, url, id, name); struct author_t { std::string email; std::string name; }; -REFLECTION(author_t, email, name); +YLT_REFL(author_t, email, name); struct commit_t { std::string url; @@ -437,7 +437,7 @@ struct commit_t { std::string sha; author_t author; }; -REFLECTION(commit_t, url, message, distinct, sha, author); +YLT_REFL(commit_t, url, message, distinct, sha, author); struct payload_t { std::optional> commits; @@ -457,9 +457,9 @@ struct payload_t { std::optional ref_type; }; -REFLECTION(payload_t, commits, distinct_size, ref, push_id, head, before, size, - forkee, pages, action, comment, issue, description, master_branch, - ref_type); +YLT_REFL(payload_t, commits, distinct_size, ref, push_id, head, before, size, + forkee, pages, action, comment, issue, description, master_branch, + ref_type); struct event_t { std::string type; @@ -471,10 +471,10 @@ struct event_t { payload_t payload; std::string id; }; -REFLECTION(event_t, type, created_at, actor, repo, ___public, org, payload, id); +YLT_REFL(event_t, type, created_at, actor, repo, ___public, org, payload, id); using events_t = std::vector; -} // namespace githubEvents +} // namespace githubEvents namespace marine_ik { struct image_element_t { @@ -482,14 +482,14 @@ struct image_element_t { std::string uuid; std::string name; }; -REFLECTION(image_element_t, url, uuid, name); +YLT_REFL(image_element_t, url, uuid, name); struct item_t { std::string name; std::string type; std::string uuid; }; -REFLECTION(item_t, name, type, uuid); +YLT_REFL(item_t, name, type, uuid); struct key_element_t { std::array rot; @@ -497,13 +497,13 @@ struct key_element_t { std::array scl; std::array pos; }; -REFLECTION(key_element_t, rot, time, scl, pos); +YLT_REFL(key_element_t, rot, time, scl, pos); struct hierarchy_element_t { int parent; std::vector keys; }; -REFLECTION(hierarchy_element_t, parent, keys); +YLT_REFL(hierarchy_element_t, parent, keys); struct geo_anim_element_t { std::vector hierarchy; @@ -511,7 +511,7 @@ struct geo_anim_element_t { int fps{}; std::string name; }; -REFLECTION(geo_anim_element_t, hierarchy, length, fps, name); +YLT_REFL(geo_anim_element_t, hierarchy, length, fps, name); struct bone_element_t { int parent; @@ -520,7 +520,7 @@ struct bone_element_t { std::array scl; std::string name; }; -REFLECTION(bone_element_t, parent, pos, rotq, scl, name); +YLT_REFL(bone_element_t, parent, pos, rotq, scl, name); struct geo_meta_data_t { int uvs; @@ -531,8 +531,8 @@ struct geo_meta_data_t { int bones; int vertices; }; -REFLECTION(geo_meta_data_t, uvs, version, faces, generator, normals, bones, - vertices); +YLT_REFL(geo_meta_data_t, uvs, version, faces, generator, normals, bones, + vertices); struct geo_data_t { std::vector> uvs; @@ -547,15 +547,15 @@ struct geo_data_t { std::vector bones; std::vector faces; }; -REFLECTION(geo_data_t, uvs, animations, vertices, metadata, name, skinWeights, - skinIndices, influencesPerVertex, normals, bones, faces); +YLT_REFL(geo_data_t, uvs, animations, vertices, metadata, name, skinWeights, + skinIndices, influencesPerVertex, normals, bones, faces); struct geometry_element_t { std::string type; std::string uuid; geo_data_t data; }; -REFLECTION(geometry_element_t, type, uuid, data); +YLT_REFL(geometry_element_t, type, uuid, data); struct texture_element_t { std::array repeat; @@ -568,8 +568,8 @@ struct texture_element_t { std::string uuid; int magFilter{}; }; -REFLECTION(texture_element_t, repeat, wrap, anisotropy, image, name, mapping, - minFilter, uuid, magFilter); +YLT_REFL(texture_element_t, repeat, wrap, anisotropy, image, name, mapping, + minFilter, uuid, magFilter); struct meta_data_t { std::string sourceFile; @@ -577,7 +577,7 @@ struct meta_data_t { std::string type; float version{}; }; -REFLECTION(meta_data_t, sourceFile, generator, type, version); +YLT_REFL(meta_data_t, sourceFile, generator, type, version); struct material_element_t : item_t { int vertexColors{}; @@ -591,9 +591,9 @@ struct material_element_t : item_t { bool depthWrite{}; int specular{}; }; -REFLECTION(material_element_t, vertexColors, name, type, uuid, blending, map, - transparent, depthTest, color, shininess, emissive, depthWrite, - specular); +YLT_REFL(material_element_t, vertexColors, name, type, uuid, blending, map, + transparent, depthTest, color, shininess, emissive, depthWrite, + specular); struct obj_child_t : item_t { std::array matrix; @@ -603,8 +603,8 @@ struct obj_child_t : item_t { bool receiveShadow{}; std::string geometry; }; -REFLECTION(obj_child_t, name, uuid, matrix, visible, type, material, castShadow, - receiveShadow, geometry); +YLT_REFL(obj_child_t, name, uuid, matrix, visible, type, material, castShadow, + receiveShadow, geometry); struct object_t { std::vector children; @@ -612,14 +612,14 @@ struct object_t { std::array matrix; std::string uuid; }; -REFLECTION(object_t, children, type, matrix, uuid); +YLT_REFL(object_t, children, type, matrix, uuid); struct animation_element_t { std::vector tracks; int fps; std::string name; }; -REFLECTION(animation_element_t, tracks, fps, name); +YLT_REFL(animation_element_t, tracks, fps, name); struct marine_ik_t { std::vector images; @@ -630,9 +630,9 @@ struct marine_ik_t { object_t object; std::vector animations; }; -REFLECTION(marine_ik_t, images, geometries, textures, metadata, materials, - object, animations); -} // namespace marine_ik +YLT_REFL(marine_ik_t, images, geometries, textures, metadata, materials, object, + animations); +} // namespace marine_ik // instruments.json struct sample_element { @@ -652,9 +652,9 @@ struct sample_element { int vibrato_type; int volume; }; -REFLECTION(sample_element, c5_samplerate, global_volume, legacy_filename, - length, loop_end, loop_start, name, pan, sustain_end, sustain_start, - vibrato_depth, vibrato_rate, vibrato_sweep, vibrato_type, volume); +YLT_REFL(sample_element, c5_samplerate, global_volume, legacy_filename, length, + loop_end, loop_start, name, pan, sustain_end, sustain_start, + vibrato_depth, vibrato_rate, vibrato_sweep, vibrato_type, volume); struct data_t { int channel; @@ -666,7 +666,7 @@ struct data_t { int volcmd; int volval; }; -REFLECTION(data_t, channel, fxcmd, fxparam, instr, note, row, volcmd, volval); +YLT_REFL(data_t, channel, fxcmd, fxparam, instr, note, row, volcmd, volval); struct pattern_element { std::optional> data; @@ -675,13 +675,13 @@ struct pattern_element { int rows_per_beat; int rows_per_measure; }; -REFLECTION(pattern_element, data, name, rows, rows_per_beat, rows_per_measure); +YLT_REFL(pattern_element, data, name, rows, rows_per_beat, rows_per_measure); struct node_t { int tick; int value; }; -REFLECTION(node_t, tick, value); +YLT_REFL(node_t, tick, value); struct panning_envelope_t { int loop_end; @@ -691,8 +691,8 @@ struct panning_envelope_t { int sustain_end; int sustain_start; }; -REFLECTION(panning_envelope_t, loop_end, loop_start, nodes, release_node, - sustain_end, sustain_start); +YLT_REFL(panning_envelope_t, loop_end, loop_start, nodes, release_node, + sustain_end, sustain_start); struct instrument_element { int default_filter_cutoff; @@ -731,17 +731,16 @@ struct instrument_element { int volume_ramp_down; int volume_ramp_up; }; -REFLECTION(instrument_element, default_filter_cutoff, - default_filter_cutoff_enabled, default_filter_mode, - default_filter_resonance, default_filter_resonance_enabled, - default_pan, duplicate_check_type, duplicate_note_action, fadeout, - global_volume, graph_insert, legacy_filename, midi_bank, - midi_channel, midi_drum_set, midi_program, name, new_note_action, - note_map, panning_envelope, pitch_envelope, pitch_pan_center, - pitch_pan_separation, pitch_to_tempo_lock, random_cutoff_weight, - random_pan_weight, random_resonance_weight, random_volume_weight, - sample_map, tuning, volume_envelope, volume_ramp_down, - volume_ramp_up); +YLT_REFL(instrument_element, default_filter_cutoff, + default_filter_cutoff_enabled, default_filter_mode, + default_filter_resonance, default_filter_resonance_enabled, + default_pan, duplicate_check_type, duplicate_note_action, fadeout, + global_volume, graph_insert, legacy_filename, midi_bank, midi_channel, + midi_drum_set, midi_program, name, new_note_action, note_map, + panning_envelope, pitch_envelope, pitch_pan_center, + pitch_pan_separation, pitch_to_tempo_lock, random_cutoff_weight, + random_pan_weight, random_resonance_weight, random_volume_weight, + sample_map, tuning, volume_envelope, volume_ramp_down, volume_ramp_up); struct instruments_t { std::optional graphstate; @@ -754,5 +753,5 @@ struct instruments_t { std::vector samples; int version; }; -REFLECTION(instruments_t, graphstate, instruments, message, name, orderlist, - patterns, pluginstate, samples, version); +YLT_REFL(instruments_t, graphstate, instruments, message, name, orderlist, + patterns, pluginstate, samples, version); diff --git a/test/test_headers1.h b/test/test_headers1.h deleted file mode 100644 index a61c2444..00000000 --- a/test/test_headers1.h +++ /dev/null @@ -1,757 +0,0 @@ -#pragma once -#include -#include -#include - -#include "iguana/ylt/reflection/user_reflect_macro.hpp" - -struct MyClass1 { - double member0; - double member1; - double member2; - double member3; - - bool operator==(MyClass1 const &rhs) const { - return member0 == rhs.member0 && member1 == rhs.member1 && - member2 == rhs.member2 && member3 == rhs.member3; - } -}; -YLT_REFL(MyClass1, member0, member1, member2, member3); - -struct MyClass2 { - unsigned member_unsigned0; - unsigned member_unsigned1; - signed member_signed; - - bool operator==(MyClass2 const &rhs) const { - return member_unsigned0 == rhs.member_unsigned0 && - member_unsigned1 == rhs.member_unsigned1 && - member_signed == rhs.member_signed; - } -}; -YLT_REFL(MyClass2, member_unsigned0, member_unsigned1, member_signed); - -struct person { - std::string name; - int age; -}; -YLT_REFL(person, name, age); - -// canada.json -struct property_t { - std::string name; -}; // Property -YLT_REFL(property_t, name); - -struct polygon_t { - std::string type; - std::vector>> coordinates; -}; // Polygon -YLT_REFL(polygon_t, type, coordinates); - -struct feature_t { - std::string type; - property_t properties; - polygon_t geometry; -}; // Feature -YLT_REFL(feature_t, type, properties, geometry); - -struct FeatureCollection { - std::string type; - std::vector features; -}; // FeatureCollection -YLT_REFL(FeatureCollection, type, features); - -// apache_builds.json -struct jobs_t { - std::string name; - std::string url; - std::string color; -}; -YLT_REFL(jobs_t, name, url, color); - -struct views_t { - std::string name; - std::string url; -}; -YLT_REFL(views_t, name, url); - -struct apache_empty_t {}; -YLT_REFL(apache_empty_t); - -struct apache_builds { - std::vector assignedLabels; - std::string mode; - std::string nodeDescription; - std::string nodeName; - int64_t numExecutors; - std::string description; - std::vector jobs; - apache_empty_t overallLoad; - views_t primaryView; - bool quietingDown; - int64_t slaveAgentPort; - apache_empty_t unlabeledLoad; - bool useCrumbs; - bool useSecurity; - std::vector views; -}; -YLT_REFL(apache_builds, assignedLabels, mode, nodeDescription, nodeName, - numExecutors, description, jobs, overallLoad, primaryView, - quietingDown, slaveAgentPort, unlabeledLoad, useCrumbs, useSecurity, - views); - -// citm_catalog.json -struct events_value_t { - std::optional description; - std::int64_t id; - std::optional logo; - std::string name; - std::vector subTopicIds; - std::optional subjectCode; - std::optional subtitle; - std::vector topicIds; -}; // events_value_t -YLT_REFL(events_value_t, description, id, logo, name, subTopicIds, subjectCode, - subtitle, topicIds); - -struct prices_element_t { - std::int64_t amount; - std::int64_t audienceSubCategoryId; - std::int64_t seatCategoryId; -}; // prices_element_t -YLT_REFL(prices_element_t, amount, audienceSubCategoryId, seatCategoryId); - -struct areas_element_t { - std::int64_t areaId; - std::vector blockIds; -}; // areas_element_t -YLT_REFL(areas_element_t, areaId, blockIds); - -struct seatCategories_element_t { - std::vector areas; - std::int64_t seatCategoryId; -}; // seatCategories_element_t -YLT_REFL(seatCategories_element_t, areas, seatCategoryId); - -struct performances_element_t { - std::int64_t eventId; - std::int64_t id; - std::optional logo; - std::optional name; - std::vector prices; - std::vector seatCategories; - std::optional seatMapImage; - std::int64_t start; - std::string venueCode; -}; // performances_element_t -YLT_REFL(performances_element_t, eventId, id, logo, name, prices, - seatCategories, seatMapImage, start, venueCode); - -struct venueNames_t { - std::string PLEYEL_PLEYEL; -}; // venueNames_t -YLT_REFL(venueNames_t, PLEYEL_PLEYEL); - -struct citm_object_t { - std::unordered_map areaNames; - std::unordered_map audienceSubCategoryNames; - apache_empty_t blockNames; - std::unordered_map events; - std::vector performances; - std::unordered_map seatCategoryNames; - std::unordered_map subTopicNames; - apache_empty_t subjectNames; - std::unordered_map topicNames; - std::unordered_map> topicSubTopics; - std::optional venueNames; -}; // citm_object_t -YLT_REFL(citm_object_t, areaNames, audienceSubCategoryNames, blockNames, events, - performances, seatCategoryNames, subTopicNames, subjectNames, - topicNames, topicSubTopics, venueNames); - -// gsoc-2018.json -struct sponsor_t { - std::string type; //@ - std::string name; - std::string disambiguatingDescription; - std::string description; - std::string url; - std::string logo; -}; -YLT_REFL(sponsor_t, type, name, disambiguatingDescription, description, url, - logo); - -struct author_t { - std::string type; //@ - std::string name; -}; -YLT_REFL(author_t, type, name); - -struct gsoc_element_t { - std::string context; //@ - std::string type; //@ - std::string name; - std::string description; - sponsor_t sponsor; - author_t author; -}; -YLT_REFL(gsoc_element_t, context, type, name, description, sponsor, author); - -using gsoc_object_t = std::map; - -// mesh.pretty.json -struct mesh_element_t { - std::vector indexRange; - std::vector usedBones; - std::vector vertexRange; -}; -YLT_REFL(mesh_element_t, indexRange, usedBones, vertexRange); - -struct mesh_t { - std::vector batches; - std::vector colors; - std::vector indices; - std::vector> influences; - apache_empty_t morphTargets; - std::vector normals; - std::vector positions; - std::vector tex0; -}; -YLT_REFL(mesh_t, batches, colors, indices, influences, morphTargets, normals, - positions, tex0); - -// random.json -struct friend_t { - int id; - std::string name; - std::string phone; -}; -YLT_REFL(friend_t, id, name, phone); - -struct random_element_t { - int id; - std::string avatar; - int age; - bool admin; - std::string name; - std::string company; - std::string phone; - std::string email; - std::string birthDate; - std::vector friends; - std::string field; -}; -YLT_REFL(random_element_t, id, avatar, age, admin, name, company, phone, email, - birthDate, friends, field); - -struct random_t { - int id; - std::string jsonrpc; - int total; - std::vector result; -}; -YLT_REFL(random_t, id, jsonrpc, total, result); - -// github_events.json -namespace githubEvents { -struct user_t { - std::string gists_url; - std::string gravatar_id; - std::string url; - std::string type; - std::string avatar_url; - std::string subscriptions_url; - std::string organizations_url; - std::string received_events_url; - std::string repos_url; - std::string login; - std::string starred_url; - int id; - std::string events_url; - std::string followers_url; - std::string following_url; -}; -YLT_REFL(user_t, gists_url, gravatar_id, url, type, avatar_url, - subscriptions_url, organizations_url, received_events_url, repos_url, - login, starred_url, id, events_url, followers_url, following_url); - -struct page_t { - std::string page_name; - std::string html_url; - std::string title; - std::string sha; - std::optional summary; - std::string action; -}; -YLT_REFL(page_t, page_name, html_url, title, sha, summary, action); - -struct pull_request_t { - std::optional html_url; - std::optional patch_url; - std::optional diff_url; -}; -YLT_REFL(pull_request_t, html_url, patch_url, diff_url); - -struct forkee_t { - std::string full_name; - std::string stargazers_url; - std::string clone_url; - bool fork; - std::string url; - std::string tags_url; - std::string description; - std::string merges_url; - int forks; - std::string language; - bool ___private; - std::string archive_url; - std::string collaborators_url; - std::string languages_url; - user_t owner; - std::string git_refs_url; - std::string labels_url; - std::string pushed_at; - std::string html_url; - std::string trees_url; - std::string forks_url; - std::string commits_url; - std::string branches_url; - std::string notifications_url; - std::string created_at; - bool has_issues; - std::string blobs_url; - std::string issues_url; - std::string compare_url; - int open_issues; - std::string contents_url; - std::string name; - std::string statuses_url; - std::string assignees_url; - int forks_count; - std::string updated_at; - std::string issue_events_url; - std::string ssh_url; - std::string subscribers_url; - std::optional mirror_url; - bool ___public; - bool has_wiki; - std::string git_commits_url; - std::string downloads_url; - int id; - std::string pulls_url; - bool has_downloads; - std::string issue_comment_url; - int watchers_count; - std::optional homepage; - std::string hooks_url; - std::string subscription_url; - std::string milestones_url; - std::string events_url; - std::string svn_url; - std::string git_tags_url; - std::string teams_url; - std::string comments_url; - int open_issues_count; - std::string keys_url; - std::string contributors_url; - int size; - int watchers; - std::string git_url; -}; -YLT_REFL(forkee_t, full_name, stargazers_url, clone_url, fork, url, tags_url, - description, merges_url, forks, language, ___private, archive_url, - collaborators_url, languages_url, owner, git_refs_url, labels_url, - pushed_at, html_url, trees_url, forks_url, commits_url, branches_url, - notifications_url, created_at, has_issues, blobs_url, issues_url, - open_issues, contents_url, name, statuses_url, assignees_url, - forks_count, updated_at, issue_events_url, ssh_url, subscribers_url, - mirror_url, ___public, has_wiki, git_commits_url, downloads_url, id, - pulls_url, has_downloads, issue_comment_url, watchers_count, homepage, - hooks_url, subscription_url, milestones_url, events_url, svn_url, - git_tags_url, teams_url, comments_url, open_issues_count, keys_url, - contributors_url, size, watchers, git_url, compare_url); - -struct issue_t { - user_t user; - std::string url; - std::vector labels; - std::string html_url; - std::string labels_url; - pull_request_t pull_request; - std::string created_at; - std::optional closed_at; - std::optional milestone; - std::string title; - std::string body; - std::string updated_at; - int number; - std::string state; - std::optional assignee; - int id; - int comments; - std::string events_url; - std::string comments_url; -}; -YLT_REFL(issue_t, user, url, labels, html_url, labels_url, pull_request, - created_at, closed_at, milestone, title, body, updated_at, number, - state, assignee, id, comments, events_url, comments_url); - -struct comment_t { - user_t user; - std::string url; - std::string issue_url; - std::string created_at; - std::string body; - std::string updated_at; - int id; -}; -YLT_REFL(comment_t, user, url, issue_url, created_at, body, updated_at, id); - -struct actor_org_t { - std::string gravatar_id; - std::string login; - std::string avatar_url; - std::string url; - int id; -}; -YLT_REFL(actor_org_t, gravatar_id, login, avatar_url, url, id); - -struct repo_t { - std::string url; - int id; - std::string name; -}; -YLT_REFL(repo_t, url, id, name); - -struct author_t { - std::string email; - std::string name; -}; -YLT_REFL(author_t, email, name); - -struct commit_t { - std::string url; - std::string message; - bool distinct; - std::string sha; - author_t author; -}; -YLT_REFL(commit_t, url, message, distinct, sha, author); - -struct payload_t { - std::optional> commits; - std::optional distinct_size; - std::optional ref; - std::optional push_id; - std::optional head; - std::optional before; - std::optional size; - std::optional forkee; - std::optional> pages; - std::optional action; - std::optional comment; - std::optional issue; - std::optional description; - std::optional master_branch; - - std::optional ref_type; -}; -YLT_REFL(payload_t, commits, distinct_size, ref, push_id, head, before, size, - forkee, pages, action, comment, issue, description, master_branch, - ref_type); - -struct event_t { - std::string type; - std::string created_at; - std::optional actor; - repo_t repo; - bool ___public; - std::optional org; - payload_t payload; - std::string id; -}; -YLT_REFL(event_t, type, created_at, actor, repo, ___public, org, payload, id); - -using events_t = std::vector; -} // namespace githubEvents - -namespace marine_ik { -struct image_element_t { - std::string url; - std::string uuid; - std::string name; -}; -YLT_REFL(image_element_t, url, uuid, name); - -struct item_t { - std::string name; - std::string type; - std::string uuid; -}; -YLT_REFL(item_t, name, type, uuid); - -struct key_element_t { - std::array rot; - float time{}; - std::array scl; - std::array pos; -}; -YLT_REFL(key_element_t, rot, time, scl, pos); - -struct hierarchy_element_t { - int parent; - std::vector keys; -}; -YLT_REFL(hierarchy_element_t, parent, keys); - -struct geo_anim_element_t { - std::vector hierarchy; - float length{}; - int fps{}; - std::string name; -}; -YLT_REFL(geo_anim_element_t, hierarchy, length, fps, name); - -struct bone_element_t { - int parent; - std::array pos; - std::array rotq; - std::array scl; - std::string name; -}; -YLT_REFL(bone_element_t, parent, pos, rotq, scl, name); - -struct geo_meta_data_t { - int uvs; - int version; - int faces; - std::string generator; - int normals; - int bones; - int vertices; -}; -YLT_REFL(geo_meta_data_t, uvs, version, faces, generator, normals, bones, - vertices); - -struct geo_data_t { - std::vector> uvs; - std::vector animations; - std::vector vertices; - geo_meta_data_t metadata; - std::string name; - std::vector skinWeights; - std::vector skinIndices; - int influencesPerVertex{}; - std::vector normals; - std::vector bones; - std::vector faces; -}; -YLT_REFL(geo_data_t, uvs, animations, vertices, metadata, name, skinWeights, - skinIndices, influencesPerVertex, normals, bones, faces); - -struct geometry_element_t { - std::string type; - std::string uuid; - geo_data_t data; -}; -YLT_REFL(geometry_element_t, type, uuid, data); - -struct texture_element_t { - std::array repeat; - std::array wrap; - int anisotropy{}; - std::string image; - std::string name; - int mapping{}; - int minFilter{}; - std::string uuid; - int magFilter{}; -}; -YLT_REFL(texture_element_t, repeat, wrap, anisotropy, image, name, mapping, - minFilter, uuid, magFilter); - -struct meta_data_t { - std::string sourceFile; - std::string generator; - std::string type; - float version{}; -}; -YLT_REFL(meta_data_t, sourceFile, generator, type, version); - -struct material_element_t : item_t { - int vertexColors{}; - std::string blending; - std::string map; - bool transparent{}; - bool depthTest{}; - int color; - int shininess; - int emissive; - bool depthWrite{}; - int specular{}; -}; -YLT_REFL(material_element_t, vertexColors, name, type, uuid, blending, map, - transparent, depthTest, color, shininess, emissive, depthWrite, - specular); - -struct obj_child_t : item_t { - std::array matrix; - bool visible{}; - std::string material; - bool castShadow{}; - bool receiveShadow{}; - std::string geometry; -}; -YLT_REFL(obj_child_t, name, uuid, matrix, visible, type, material, castShadow, - receiveShadow, geometry); - -struct object_t { - std::vector children; - std::string type; - std::array matrix; - std::string uuid; -}; -YLT_REFL(object_t, children, type, matrix, uuid); - -struct animation_element_t { - std::vector tracks; - int fps; - std::string name; -}; -YLT_REFL(animation_element_t, tracks, fps, name); - -struct marine_ik_t { - std::vector images; - std::vector geometries; - std::vector textures; - meta_data_t metadata; - std::vector materials; - object_t object; - std::vector animations; -}; -YLT_REFL(marine_ik_t, images, geometries, textures, metadata, materials, object, - animations); -} // namespace marine_ik - -// instruments.json -struct sample_element { - int c5_samplerate; - int global_volume; - std::string legacy_filename; - int length; - int loop_end; - int loop_start; - std::string name; - int pan; - int sustain_end; - int sustain_start; - int vibrato_depth; - int vibrato_rate; - int vibrato_sweep; - int vibrato_type; - int volume; -}; -YLT_REFL(sample_element, c5_samplerate, global_volume, legacy_filename, length, - loop_end, loop_start, name, pan, sustain_end, sustain_start, - vibrato_depth, vibrato_rate, vibrato_sweep, vibrato_type, volume); - -struct data_t { - int channel; - int fxcmd; - int fxparam; - int instr; - int note; - int row; - int volcmd; - int volval; -}; -YLT_REFL(data_t, channel, fxcmd, fxparam, instr, note, row, volcmd, volval); - -struct pattern_element { - std::optional> data; - std::string name; - int rows; - int rows_per_beat; - int rows_per_measure; -}; -YLT_REFL(pattern_element, data, name, rows, rows_per_beat, rows_per_measure); - -struct node_t { - int tick; - int value; -}; -YLT_REFL(node_t, tick, value); - -struct panning_envelope_t { - int loop_end; - int loop_start; - std::vector nodes; - int release_node; - int sustain_end; - int sustain_start; -}; -YLT_REFL(panning_envelope_t, loop_end, loop_start, nodes, release_node, - sustain_end, sustain_start); - -struct instrument_element { - int default_filter_cutoff; - bool default_filter_cutoff_enabled; - int default_filter_mode; - int default_filter_resonance; - bool default_filter_resonance_enabled; - int default_pan; - int duplicate_check_type; - int duplicate_note_action; - int fadeout; - int global_volume; - int graph_insert; - std::string legacy_filename; - int midi_bank; - int midi_channel; - int midi_drum_set; - int midi_program; - std::string name; - int new_note_action; - std::optional note_map; - panning_envelope_t panning_envelope; - panning_envelope_t pitch_envelope; - - int pitch_pan_center; - int pitch_pan_separation; - int pitch_to_tempo_lock; - int random_cutoff_weight; - int random_pan_weight; - int random_resonance_weight; - int random_volume_weight; - std::optional sample_map; - std::optional tuning; - - panning_envelope_t volume_envelope; - int volume_ramp_down; - int volume_ramp_up; -}; -YLT_REFL(instrument_element, default_filter_cutoff, - default_filter_cutoff_enabled, default_filter_mode, - default_filter_resonance, default_filter_resonance_enabled, - default_pan, duplicate_check_type, duplicate_note_action, fadeout, - global_volume, graph_insert, legacy_filename, midi_bank, midi_channel, - midi_drum_set, midi_program, name, new_note_action, note_map, - panning_envelope, pitch_envelope, pitch_pan_center, - pitch_pan_separation, pitch_to_tempo_lock, random_cutoff_weight, - random_pan_weight, random_resonance_weight, random_volume_weight, - sample_map, tuning, volume_envelope, volume_ramp_down, volume_ramp_up); - -struct instruments_t { - std::optional graphstate; - std::vector instruments; - std::optional message; - std::string name; - std::optional orderlist; - std::vector patterns; - std::optional pluginstate; - std::vector samples; - int version; -}; -YLT_REFL(instruments_t, graphstate, instruments, message, name, orderlist, - patterns, pluginstate, samples, version); diff --git a/test/test_json_files.cpp b/test/test_json_files.cpp index f7751a03..035c5b48 100644 --- a/test/test_json_files.cpp +++ b/test/test_json_files.cpp @@ -12,7 +12,7 @@ #include #include "doctest.h" -#include "test_headers1.h" +#include "test_headers.h" TEST_CASE("test canada.json") { std::cout << std::filesystem::current_path().string() << "\n"; diff --git a/test/unit_test.cpp b/test/unit_test.cpp index a85a1a55..92d265b4 100644 --- a/test/unit_test.cpp +++ b/test/unit_test.cpp @@ -12,7 +12,7 @@ #include "doctest.h" #include "iguana/json_reader.hpp" -#include "test_headers1.h" +#include "test_headers.h" TEST_CASE("test parse item num_t") { { From 3ccb25395ade34d9eec4085e6401f01f9f39246d Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 26 Aug 2024 16:25:07 +0800 Subject: [PATCH 07/44] index_of --- iguana/detail/traits.hpp | 1 + iguana/json_reader.hpp | 25 ------------------------- iguana/ylt/reflection/member_value.hpp | 22 ++++++++++++++++++++++ test/test_reflection.cpp | 4 ++++ 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/iguana/detail/traits.hpp b/iguana/detail/traits.hpp index 57a9fa45..a62d3238 100644 --- a/iguana/detail/traits.hpp +++ b/iguana/detail/traits.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "iguana/define.h" diff --git a/iguana/json_reader.hpp b/iguana/json_reader.hpp index a65039c8..56eb1272 100644 --- a/iguana/json_reader.hpp +++ b/iguana/json_reader.hpp @@ -666,31 +666,6 @@ IGUANA_INLINE void from_json(T &value, const View &view) { from_json(value, std::begin(view), std::end(view)); } -template < - auto member, - typename Parant = typename member_tratis::owner_type, - typename T> -IGUANA_INLINE void from_json(T &value, std::string_view str) { - constexpr size_t duplicate_count = - iguana::duplicate_count, member>(); - static_assert(duplicate_count != 1, "the member is not belong to the object"); - static_assert(duplicate_count == 2, "has duplicate field name"); - - constexpr auto name = name_of(); - constexpr size_t index = index_of(); - constexpr size_t member_count = member_count_of(); - str = str.substr(str.find(name) + name.size()); - size_t pos = str.find(":") + 1; - if constexpr (index == member_count - 1) { // last field - str = str.substr(pos, str.find("}") - pos + 1); - } - else { - str = str.substr(pos, str.find(",") - pos); - } - - detail::from_json_impl(value.*member, std::begin(str), std::end(str)); -} - template , int> = 0> IGUANA_INLINE void from_json(T &value, const View &view, diff --git a/iguana/ylt/reflection/member_value.hpp b/iguana/ylt/reflection/member_value.hpp index a73afa4a..f5781e1a 100644 --- a/iguana/ylt/reflection/member_value.hpp +++ b/iguana/ylt/reflection/member_value.hpp @@ -31,6 +31,15 @@ struct is_variant : std::false_type {}; template struct is_variant> : std::true_type {}; +template +struct member_tratis {}; + +template +struct member_tratis { + using owner_type = Owner; + using value_type = T; +}; + struct switch_helper { template static constexpr size_t run(Member& member, Tuple& t) { @@ -154,6 +163,19 @@ inline constexpr auto& get(T& t) { } #endif +template +inline constexpr size_t index_of() { + using T = typename internal::member_tratis::owner_type; + constexpr auto name = field_string(); + constexpr auto names = member_names; + for (size_t i = 0; i < names.size(); i++) { + if (name == names[i]) { + return i; + } + } + return names.size(); +} + template inline size_t index_of(T& t, Field& value) { const auto& offset_arr = member_offsets; diff --git a/test/test_reflection.cpp b/test/test_reflection.cpp index cc3c2c32..059b0dce 100644 --- a/test/test_reflection.cpp +++ b/test/test_reflection.cpp @@ -308,6 +308,10 @@ YLT_REFL(simple2, color, id, str, age); TEST_CASE("test macros") { static_assert(!std::is_aggregate_v); simple2 t{2, 10, "hello reflection", 6}; + constexpr auto idx = index_of<&simple2::age>(); + static_assert(idx == 3); + constexpr auto idx2 = index_of<&simple2::id>(); + static_assert(idx2 == 1); constexpr auto arr = member_names; static_assert(arr.size() == 4); constexpr auto map = member_names_map; From 987805180f625b17527e2ee91d974733f8683d0f Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 26 Aug 2024 17:24:11 +0800 Subject: [PATCH 08/44] use ylt refl --- iguana/json_reader.hpp | 36 +++++++++++++++++++----------------- iguana/json_util.hpp | 1 + iguana/json_writer.hpp | 21 +++++++++++---------- iguana/reflection.hpp | 6 ++++++ iguana/util.hpp | 15 ++++++++++----- iguana/xml_util.hpp | 1 + iguana/yaml_util.hpp | 1 + test/test_some.cpp | 34 +++++++++++++++++----------------- 8 files changed, 66 insertions(+), 49 deletions(-) diff --git a/iguana/json_reader.hpp b/iguana/json_reader.hpp index 56eb1272..9542ccf4 100644 --- a/iguana/json_reader.hpp +++ b/iguana/json_reader.hpp @@ -414,18 +414,20 @@ IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) { match<'['>(it, end); skip_ws(it, end); - for_each(value, [&](auto &v, auto i) IGUANA__INLINE_LAMBDA { - constexpr auto I = decltype(i)::value; - if (it == end || *it == ']') { - return; - } - if constexpr (I != 0) { - match<','>(it, end); - skip_ws(it, end); - } - from_json_impl(v, it, end); - skip_ws(it, end); - }); + foreach_tuple( + [&](auto &v, auto i) IGUANA__INLINE_LAMBDA { + constexpr auto I = decltype(i)::value; + if (it == end || *it == ']') { + return; + } + if constexpr (I != 0) { + match<','>(it, end); + skip_ws(it, end); + } + from_json_impl(v, it, end); + skip_ws(it, end); + }, + value); match<']'>(it, end); } @@ -896,10 +898,10 @@ IGUANA_INLINE void from_json_file(T &value, const std::string &filename, } } -template -IGUANA_INLINE void from_json_adl(iguana_adl_t *p, T &t, - std::string_view pb_str) { - iguana::from_json(t, pb_str); -} +// template +// IGUANA_INLINE void from_json_adl(iguana_adl_t *p, T &t, +// std::string_view pb_str) { +// iguana::from_json(t, pb_str); +// } } // namespace iguana diff --git a/iguana/json_util.hpp b/iguana/json_util.hpp index f1bf3a33..a27efb0d 100644 --- a/iguana/json_util.hpp +++ b/iguana/json_util.hpp @@ -3,6 +3,7 @@ #pragma once +#include "detail/string_stream.hpp" #include "util.hpp" #include "value.hpp" diff --git a/iguana/json_writer.hpp b/iguana/json_writer.hpp index c56e4c24..0b5f980b 100644 --- a/iguana/json_writer.hpp +++ b/iguana/json_writer.hpp @@ -242,13 +242,14 @@ IGUANA_INLINE void to_json_impl(Stream &s, T &&t) { using U = typename std::decay_t; s.push_back('['); constexpr size_t size = std::tuple_size_v; - for_each(std::forward(t), - [&s, size](auto &v, auto i) IGUANA__INLINE_LAMBDA { - to_json_impl(s, v); + foreach_tuple( + [&s, size](auto &v, auto i) IGUANA__INLINE_LAMBDA { + to_json_impl(s, v); - if (i != size - 1) - IGUANA_LIKELY { s.push_back(','); } - }); + if (i != size - 1) + IGUANA_LIKELY { s.push_back(','); } + }, + std::forward(t)); s.push_back(']'); } @@ -291,10 +292,10 @@ IGUANA_INLINE void to_json(T &&t, Stream &s) { to_json_impl(s, t); } -template -IGUANA_INLINE void to_json_adl(iguana_adl_t *p, T &t, std::string &pb_str) { - to_json(t, pb_str); -} +// template +// IGUANA_INLINE void to_json_adl(iguana_adl_t *p, T &t, std::string &pb_str) { +// to_json(t, pb_str); +// } } // namespace iguana #endif // SERIALIZE_JSON_HPP diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index 474e27fa..e22995a3 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -828,6 +828,12 @@ struct is_reflection : std::false_type {}; template inline constexpr bool is_reflection_v = is_reflection::value; +template +constexpr inline bool refletable_v = is_reflection_v>; + +template +constexpr inline bool non_refletable_v = !refletable_v; + template inline constexpr bool is_custom_reflection_v = is_custom_reflection::value; diff --git a/iguana/util.hpp b/iguana/util.hpp index bbb27c2e..2122626c 100644 --- a/iguana/util.hpp +++ b/iguana/util.hpp @@ -13,10 +13,10 @@ #include "define.h" #include "detail/charconv.h" +#include "detail/traits.hpp" #include "detail/utf.hpp" #include "error_code.h" #include "field_reflection.hpp" -#include "reflection.hpp" #include "ylt/reflection/member_value.hpp" #include "ylt/reflection/user_reflect_macro.hpp" @@ -138,11 +138,16 @@ template using variant_element_t = std::remove_reference_t( std::declval>()))>; -template -constexpr inline bool refletable_v = is_reflection_v>; +template +constexpr void foreach_tuple(F&& f, Tuple& tp, std::index_sequence) { + (void(f(std::get(tp), std::integral_constant{})), ...); +} -template -constexpr inline bool non_refletable_v = !refletable_v; +template +constexpr void foreach_tuple(F&& f, Tuple& tp) { + foreach_tuple(std::forward(f), tp, + std::make_index_sequence>{}); +} template constexpr inline bool ylt_refletable_v = diff --git a/iguana/xml_util.hpp b/iguana/xml_util.hpp index 8259e176..b80be60d 100644 --- a/iguana/xml_util.hpp +++ b/iguana/xml_util.hpp @@ -1,5 +1,6 @@ #pragma once #include "detail/pb_type.hpp" +#include "reflection.hpp" #include "util.hpp" namespace iguana { diff --git a/iguana/yaml_util.hpp b/iguana/yaml_util.hpp index 920a9918..89edb857 100644 --- a/iguana/yaml_util.hpp +++ b/iguana/yaml_util.hpp @@ -1,6 +1,7 @@ #pragma once #include "detail/pb_type.hpp" +#include "reflection.hpp" #include "util.hpp" namespace iguana { diff --git a/test/test_some.cpp b/test/test_some.cpp index f634b102..97c4f0a8 100644 --- a/test/test_some.cpp +++ b/test/test_some.cpp @@ -137,7 +137,7 @@ struct test_double_t { YLT_REFL(test_double_t, val); struct test_empty_t {}; -REFLECTION_EMPTY(test_empty_t); +YLT_REFL(test_empty_t); struct test { std::string username; @@ -164,11 +164,11 @@ struct inner_struct { int z; }; -inline auto get_members_impl(inner_struct *) { - return std::make_tuple(iguana::field_t{&inner_struct::x, 7, "a"}, - iguana::field_t{&inner_struct::y, 9, "b"}, - iguana::field_t{&inner_struct::z, 12, "c"}); -} +// inline auto get_members_impl(inner_struct *) { +// return std::make_tuple(iguana::field_t{&inner_struct::x, 7, "a"}, +// iguana::field_t{&inner_struct::y, 9, "b"}, +// iguana::field_t{&inner_struct::z, 12, "c"}); +// } inline constexpr size_t iguana_member_count(inner_struct *) { return 3; } @@ -450,7 +450,7 @@ TEST_CASE("test dom parse") { TEST_CASE("test simple object") { { // test_double_t d{.val = 1.4806532964699196e-22}; - // iguana::string_stream ss; + // std::string ss; // iguana::to_json(d, ss); // // test_double_t p{}; @@ -479,7 +479,7 @@ TEST_CASE("test simple object") { TEST_CASE("test two_fields object") { two_fields_t obj{{1, 2}, {"aa", "bb"}}; - iguana::string_stream ss; + std::string ss; iguana::to_json(obj, ss); two_fields_t p{}; @@ -490,7 +490,7 @@ TEST_CASE("test two_fields object") { TEST_CASE("test simple nested object") { person o{"tom", false}; simple_nested_t t{1, o}; - iguana::string_stream ss; + std::string ss; iguana::to_json(t, ss); simple_nested_t p{}; @@ -503,7 +503,7 @@ TEST_CASE("test simple nested object") { TEST_CASE("test c array and std::array") { arr_t arr{{1, 2}}; - iguana::string_stream ss; + std::string ss; iguana::to_json(arr, ss); arr_t arr1{}; @@ -569,7 +569,7 @@ TEST_CASE("test bool, null, char, int, float") { TEST_CASE("test vector") { vector_t arr{{1, 2}}; - iguana::string_stream ss; + std::string ss; iguana::to_json(arr, ss); vector_t p{}; @@ -581,7 +581,7 @@ TEST_CASE("test map") { map_t map{}; map.map1 = {{1, "hello"}, {2, "iguana"}}; map.map2 = {{3, "this"}, {4, "hashmap"}}; - iguana::string_stream ss; + std::string ss; iguana::to_json(map, ss); map_t p{}; @@ -606,7 +606,7 @@ TEST_CASE("test nested object") { TEST_CASE("test tuple") { tuple_t t; t.tp = std::make_tuple(2, 3.14, "hello iguana"); - iguana::string_stream ss; + std::string ss; iguana::to_json(t, ss); tuple_t p{}; @@ -619,7 +619,7 @@ TEST_CASE("test tuple") { TEST_CASE("test list") { list_t list{{1, 2, 3}}; - iguana::string_stream ss; + std::string ss; iguana::to_json(list, ss); list_t p{}; @@ -629,7 +629,7 @@ TEST_CASE("test list") { TEST_CASE("test deque_t") { deque_t list{{1, 2, 3}}; - iguana::string_stream ss; + std::string ss; iguana::to_json(list, ss); deque_t p{}; @@ -697,7 +697,7 @@ TEST_CASE("test unique_ptr object") { TEST_CASE("test empty object") { test_empty_t empty_obj; - iguana::string_stream ss; + std::string ss; iguana::to_json(empty_obj, ss); CHECK(ss == "{}"); } @@ -706,7 +706,7 @@ TEST_CASE("test non-reflectable object") { { std::tuple t{1, 3.14, std::string("iguana")}; - iguana::string_stream ss; + std::string ss; iguana::to_json(t, ss); std::tuple p{}; From 332d63a36b4142f8154d195a52bb3b9b5bf5ad15 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 26 Aug 2024 17:43:33 +0800 Subject: [PATCH 09/44] fix compile --- example/json_example.cpp | 1 - iguana/ylt/reflection/member_value.hpp | 4 ++-- test/test_pb.cpp | 4 +++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/example/json_example.cpp b/example/json_example.cpp index 184817aa..a98fa058 100644 --- a/example/json_example.cpp +++ b/example/json_example.cpp @@ -14,7 +14,6 @@ inline char* to_chars_float(T value, char* buffer) { #include #include - namespace client { struct person { std::string name; diff --git a/iguana/ylt/reflection/member_value.hpp b/iguana/ylt/reflection/member_value.hpp index f5781e1a..06d677e1 100644 --- a/iguana/ylt/reflection/member_value.hpp +++ b/iguana/ylt/reflection/member_value.hpp @@ -235,7 +235,7 @@ inline constexpr void for_each(T&& t, Visit&& func) { } (std::make_index_sequence{}); #else - visit_members_impl0(std::forward(func), std::make_index_sequence{}, args...); + visit_members_impl0(std::forward(func), std::make_index_sequence{}, args...); #endif }); } @@ -249,7 +249,7 @@ inline constexpr void for_each(T&& t, Visit&& func) { } (std::make_index_sequence{}); #else - visit_members_impl(std::forward(func), std::make_index_sequence{}, args...); + visit_members_impl(std::forward(func), std::make_index_sequence{}, args...); #endif }); } diff --git a/test/test_pb.cpp b/test/test_pb.cpp index d09ee6ed..5a323c61 100644 --- a/test/test_pb.cpp +++ b/test/test_pb.cpp @@ -109,7 +109,9 @@ struct test_pb_st6 { }; REFLECTION(test_pb_st6, x, y); -struct pair_t : public iguana::base_impl { +struct pair_t + : public iguana::base_impl { pair_t() = default; pair_t(int a, int b) : x(a), y(b) {} int x; From 451b2fe9d0a5a36146597b06b6510279b26a6b4c Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 26 Aug 2024 17:58:03 +0800 Subject: [PATCH 10/44] format --- iguana/define.h | 3 ++- iguana/ylt/reflection/member_value.hpp | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/define.h b/iguana/define.h index 2887122c..0c0b4485 100644 --- a/iguana/define.h +++ b/iguana/define.h @@ -21,7 +21,8 @@ #define IGUANA__INLINE_LAMBDA constexpr __attribute__((always_inline)) #endif -#if __has_cpp_attribute(likely) && __has_cpp_attribute(unlikely) +#if __has_cpp_attribute(likely) && __has_cpp_attribute(unlikely) && \ + __cplusplus >= 202002L #define IGUANA_LIKELY [[likely]] #define IGUANA_UNLIKELY [[unlikely]] #else diff --git a/iguana/ylt/reflection/member_value.hpp b/iguana/ylt/reflection/member_value.hpp index 06d677e1..b62f30c8 100644 --- a/iguana/ylt/reflection/member_value.hpp +++ b/iguana/ylt/reflection/member_value.hpp @@ -235,7 +235,9 @@ inline constexpr void for_each(T&& t, Visit&& func) { } (std::make_index_sequence{}); #else - visit_members_impl0(std::forward(func), std::make_index_sequence{}, args...); + visit_members_impl0(std::forward(func), + std::make_index_sequence{}, + args...); #endif }); } @@ -249,7 +251,9 @@ inline constexpr void for_each(T&& t, Visit&& func) { } (std::make_index_sequence{}); #else - visit_members_impl(std::forward(func), std::make_index_sequence{}, args...); + visit_members_impl(std::forward(func), + std::make_index_sequence{}, + args...); #endif }); } From f492ed69e587a282559152856c34543d21b17d63 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 26 Aug 2024 18:18:17 +0800 Subject: [PATCH 11/44] fix macro --- .../ylt/reflection/internal/arg_list_macro.hpp | 6 +++--- iguana/ylt/reflection/user_reflect_macro.hpp | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/iguana/ylt/reflection/internal/arg_list_macro.hpp b/iguana/ylt/reflection/internal/arg_list_macro.hpp index b60ff393..d819ba57 100644 --- a/iguana/ylt/reflection/internal/arg_list_macro.hpp +++ b/iguana/ylt/reflection/internal/arg_list_macro.hpp @@ -1,11 +1,11 @@ #pragma once #include "common_macro.hpp" -#define WRAP_ARGS0(w, o, _0) +#define WRAP_ARGS0(w, o) #define WRAP_ARGS1(w, o, _1) w(o, _1) #include "generate/arg_list_macro_gen.hpp" #define WRAP_ARGS_(w, object, ...) \ YLT_CONCAT(WRAP_ARGS, YLT_ARG_COUNT(__VA_ARGS__)) \ - (w, object, __VA_ARGS__) -#define WRAP_ARGS(w, object, ...) WRAP_ARGS_(w, object, __VA_ARGS__) \ No newline at end of file + (w, object, ##__VA_ARGS__) +#define WRAP_ARGS(w, object, ...) WRAP_ARGS_(w, object, ##__VA_ARGS__) \ No newline at end of file diff --git a/iguana/ylt/reflection/user_reflect_macro.hpp b/iguana/ylt/reflection/user_reflect_macro.hpp index a4f93b89..7c7b96e3 100644 --- a/iguana/ylt/reflection/user_reflect_macro.hpp +++ b/iguana/ylt/reflection/user_reflect_macro.hpp @@ -27,23 +27,23 @@ using member_value_type_t = typename member_traits::value_type; template \ inline static constexpr decltype(auto) refl_visit_members( \ STRUCT &t, Visitor &&visitor) { \ - return visitor(WRAP_ARGS(CONCAT_MEMBER, t, __VA_ARGS__)); \ + return visitor(WRAP_ARGS(CONCAT_MEMBER, t, ##__VA_ARGS__)); \ } \ template \ inline static constexpr decltype(auto) refl_visit_members( \ const STRUCT &t, Visitor &&visitor) { \ - return visitor(WRAP_ARGS(CONCAT_MEMBER, t, __VA_ARGS__)); \ + return visitor(WRAP_ARGS(CONCAT_MEMBER, t, ##__VA_ARGS__)); \ } \ inline static decltype(auto) refl_object_to_tuple(STRUCT &t) { \ - return std::tie(WRAP_ARGS(CONCAT_MEMBER, t, __VA_ARGS__)); \ + return std::tie(WRAP_ARGS(CONCAT_MEMBER, t, ##__VA_ARGS__)); \ } \ inline static decltype(auto) refl_object_to_tuple(const STRUCT &t) { \ - return std::tie(WRAP_ARGS(CONCAT_MEMBER, t, __VA_ARGS__)); \ + return std::tie(WRAP_ARGS(CONCAT_MEMBER, t, ##__VA_ARGS__)); \ } \ inline static constexpr decltype(auto) refl_member_names( \ const ylt::reflection::identity &t) { \ constexpr std::array arr{ \ - WRAP_ARGS(CONCAT_NAME, t, __VA_ARGS__)}; \ + WRAP_ARGS(CONCAT_NAME, t, ##__VA_ARGS__)}; \ return arr; \ } \ inline static constexpr std::size_t refl_member_count( \ @@ -81,7 +81,7 @@ inline static decltype(auto) refl_object_to_tuple_impl(T &&t) { #define YLT_REFL_PRIVATE_(STRUCT, ...) \ namespace ylt::reflection { \ inline constexpr auto get_private_ptrs(const identity &t); \ - template struct private_visitor; \ + template struct private_visitor; \ template \ inline static constexpr decltype(auto) refl_visit_members( \ STRUCT &t, Visitor &&visitor) { \ @@ -108,10 +108,10 @@ inline static decltype(auto) refl_object_to_tuple_impl(T &&t) { inline static constexpr decltype(auto) refl_member_names( \ const ylt::reflection::identity &t) { \ constexpr std::array arr{ \ - WRAP_ARGS(CONCAT_NAME, t, __VA_ARGS__)}; \ + WRAP_ARGS(CONCAT_NAME, t, ##__VA_ARGS__)}; \ return arr; \ } \ - YLT_REFL_PRIVATE_(STRUCT, WRAP_ARGS(CONCAT_ADDR, STRUCT, __VA_ARGS__)) + YLT_REFL_PRIVATE_(STRUCT, WRAP_ARGS(CONCAT_ADDR, STRUCT, ##__VA_ARGS__)) template struct is_out_ylt_refl : std::false_type {}; From 44576ddb4fd130e24122bd30c42f58c6774d879e Mon Sep 17 00:00:00 2001 From: qicosmos Date: Tue, 27 Aug 2024 11:03:01 +0800 Subject: [PATCH 12/44] for msvc;remove gcc8 --- .github/workflows/linux-gcc.yml | 44 +++++++++---------- iguana/define.h | 3 +- iguana/ylt/reflection/internal/args_count.hpp | 23 +++++----- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/.github/workflows/linux-gcc.yml b/.github/workflows/linux-gcc.yml index b29756ec..ea35b539 100644 --- a/.github/workflows/linux-gcc.yml +++ b/.github/workflows/linux-gcc.yml @@ -58,31 +58,31 @@ jobs: working-directory: ${{ github.workspace }}/build run: ctest -C ${{ matrix.mode }} -j 1 -V - ubuntu_gcc8: - strategy: - matrix: - mode: [ Debug, Release ] - cpp_version: [17] - runs-on: ubuntu-20.04 + # ubuntu_gcc8: + # strategy: + # matrix: + # mode: [ Debug, Release ] + # cpp_version: [17] + # runs-on: ubuntu-20.04 - steps: - - name: check out - uses: actions/checkout@v3 + # steps: + # - name: check out + # uses: actions/checkout@v3 - - name: Install GCC8 - run: | - sudo apt update - sudo apt install gcc-8 g++-8 + # - name: Install GCC8 + # run: | + # sudo apt update + # sudo apt install gcc-8 g++-8 - - name: checkout gcc version - run: gcc-8 --version + # - name: checkout gcc version + # run: gcc-8 --version - - name: configure cmake - run: CXX=g++-8 CC=gcc-8 cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DCMAKE_CXX_STANDARD=${{ matrix.cpp_version }} + # - name: configure cmake + # run: CXX=g++-8 CC=gcc-8 cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DCMAKE_CXX_STANDARD=${{ matrix.cpp_version }} - - name: build project - run: cmake --build ${{ github.workspace }}/build --config ${{ matrix.mode }} + # - name: build project + # run: cmake --build ${{ github.workspace }}/build --config ${{ matrix.mode }} - - name: test - working-directory: ${{ github.workspace }}/build - run: ctest -C ${{ matrix.mode }} -j 1 -V \ No newline at end of file + # - name: test + # working-directory: ${{ github.workspace }}/build + # run: ctest -C ${{ matrix.mode }} -j 1 -V \ No newline at end of file diff --git a/iguana/define.h b/iguana/define.h index 2887122c..0c0b4485 100644 --- a/iguana/define.h +++ b/iguana/define.h @@ -21,7 +21,8 @@ #define IGUANA__INLINE_LAMBDA constexpr __attribute__((always_inline)) #endif -#if __has_cpp_attribute(likely) && __has_cpp_attribute(unlikely) +#if __has_cpp_attribute(likely) && __has_cpp_attribute(unlikely) && \ + __cplusplus >= 202002L #define IGUANA_LIKELY [[likely]] #define IGUANA_UNLIKELY [[unlikely]] #else diff --git a/iguana/ylt/reflection/internal/args_count.hpp b/iguana/ylt/reflection/internal/args_count.hpp index ec93dd61..1bb0ab44 100644 --- a/iguana/ylt/reflection/internal/args_count.hpp +++ b/iguana/ylt/reflection/internal/args_count.hpp @@ -3,17 +3,18 @@ #define YLT_MACRO_EXPAND(...) __VA_ARGS__ #define YLT_ARG_COUNT(...) \ - YLT_MACRO_EXPAND(YLT_ARG_COUNT_IMPL( \ - 0, ##__VA_ARGS__, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, \ - 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, \ - 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, \ - 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, \ - 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \ - 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, \ - 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ - 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) - -#define YLT_ARG_COUNT_IMPL( \ + _COUNTOF_CAT( \ + _COUNTOF_A, \ + (0, ##__VA_ARGS__, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, \ + 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, \ + 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, \ + 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, \ + 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \ + 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \ + 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) +#define _COUNTOF_CAT(a, b) a b +#define _COUNTOF_A( \ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \ _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, \ _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, \ From 087540241f28f31d1dd2ff3f565a0ceb9232be19 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Tue, 27 Aug 2024 11:07:51 +0800 Subject: [PATCH 13/44] msvc --- iguana/ylt/reflection/internal/args_count.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/ylt/reflection/internal/args_count.hpp b/iguana/ylt/reflection/internal/args_count.hpp index 1bb0ab44..0da72cf8 100644 --- a/iguana/ylt/reflection/internal/args_count.hpp +++ b/iguana/ylt/reflection/internal/args_count.hpp @@ -3,7 +3,7 @@ #define YLT_MACRO_EXPAND(...) __VA_ARGS__ #define YLT_ARG_COUNT(...) \ - _COUNTOF_CAT( \ + YLT_MACRO_EXPAND(_COUNTOF_CAT( \ _COUNTOF_A, \ (0, ##__VA_ARGS__, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, \ 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, \ @@ -12,7 +12,7 @@ 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \ 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \ 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))) #define _COUNTOF_CAT(a, b) a b #define _COUNTOF_A( \ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \ From db436c186157aab5b02961bf9058d591adbb379e Mon Sep 17 00:00:00 2001 From: qicosmos Date: Tue, 27 Aug 2024 11:12:55 +0800 Subject: [PATCH 14/44] test msvc --- iguana/ylt/reflection/internal/args_count.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/ylt/reflection/internal/args_count.hpp b/iguana/ylt/reflection/internal/args_count.hpp index 0da72cf8..4534090b 100644 --- a/iguana/ylt/reflection/internal/args_count.hpp +++ b/iguana/ylt/reflection/internal/args_count.hpp @@ -3,7 +3,7 @@ #define YLT_MACRO_EXPAND(...) __VA_ARGS__ #define YLT_ARG_COUNT(...) \ - YLT_MACRO_EXPAND(_COUNTOF_CAT( \ + _COUNTOF_CAT0( \ _COUNTOF_A, \ (0, ##__VA_ARGS__, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, \ 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, \ @@ -12,8 +12,9 @@ 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \ 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \ 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))) + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) #define _COUNTOF_CAT(a, b) a b +#define _COUNTOF_CAT0(a, b) YLT_MACRO_EXPAND(_COUNTOF_CAT(a, b)) #define _COUNTOF_A( \ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \ _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, \ From ab2f8374cc439504673d0744428daececd913df3 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Tue, 27 Aug 2024 11:20:42 +0800 Subject: [PATCH 15/44] fix for msvc arg count --- iguana/ylt/reflection/internal/args_count.hpp | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/iguana/ylt/reflection/internal/args_count.hpp b/iguana/ylt/reflection/internal/args_count.hpp index 4534090b..69d7a090 100644 --- a/iguana/ylt/reflection/internal/args_count.hpp +++ b/iguana/ylt/reflection/internal/args_count.hpp @@ -2,20 +2,45 @@ #define YLT_MACRO_EXPAND(...) __VA_ARGS__ -#define YLT_ARG_COUNT(...) \ - _COUNTOF_CAT0( \ - _COUNTOF_A, \ - (0, ##__VA_ARGS__, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, \ - 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, \ - 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, \ - 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, \ - 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \ - 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \ - 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) -#define _COUNTOF_CAT(a, b) a b -#define _COUNTOF_CAT0(a, b) YLT_MACRO_EXPAND(_COUNTOF_CAT(a, b)) -#define _COUNTOF_A( \ +#ifdef _MSC_VER // Microsoft compilers + +#define __NARGS( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \ + _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, \ + _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, \ + _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ + _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, \ + _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, \ + _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, _103, _104, \ + _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, \ + _117, _118, _119, _120, _121, _122, _123, _124, _125, N, ...) \ + N +#define NARGS_1(...) \ + YLT_MACRO_EXPAND(__NARGS( \ + __VA_ARGS__, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, \ + 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, \ + 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \ + 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, \ + 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, \ + 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, \ + 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, \ + 6, 5, 4, 3, 2, 1, 0)) + +#define AUGMENTER(...) unused, __VA_ARGS__ +#define YLT_ARG_COUNT(...) NARGS_1(AUGMENTER(__VA_ARGS__)) + +#else // Others + +#define YLT_ARG_COUNT(...) \ + __NARGS(0, ##__VA_ARGS__, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, \ + 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, \ + 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, \ + 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, \ + 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, \ + 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, \ + 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, \ + 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define __NARGS( \ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \ _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, \ _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, \ @@ -26,3 +51,5 @@ _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, \ _117, _118, _119, _120, _121, _122, _123, _124, N, ...) \ N + +#endif From 5ef8bd0477e9911bb906c1d133373f8b09add1d0 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Tue, 27 Aug 2024 18:17:51 +0800 Subject: [PATCH 16/44] test --- iguana/pb_util.hpp | 306 ++++++++++++++++++++++++++++++------------- iguana/pb_writer.hpp | 7 +- test/test_cpp20.cpp | 32 +++++ 3 files changed, 248 insertions(+), 97 deletions(-) diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 27bc9a89..8dee9075 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -434,107 +434,225 @@ IGUANA_INLINE size_t pb_oneof_size(Type&& t, Arr& size_arr) { return len; } +template +struct is_custom_reflection : std::false_type {}; + +template +struct is_custom_reflection< + T, std::void_t()))>> + : std::true_type {}; + +template +inline constexpr bool is_custom_reflection_v = + is_custom_reflection>::value; + +// T: parant type, value_type: member value pointer type, SubType: subtype from +// variant +template > +struct pb_field_t { + using owner_type = T; + using value_type = ValuePtr; + using sub_type = SubType; + constexpr pb_field_t() = default; + explicit constexpr pb_field_t(ValuePtr member, uint32_t number, + frozen::string name = "") + : member_ptr(member), field_name(name), field_no(number) {} + + ValuePtr member_ptr; + frozen::string field_name; + uint32_t field_no; + + auto& value() const { return *member_ptr; } +}; + +// using value_type = typename member_traits::value_type; +// return std::tuple(field_t>{ +// t, (base_idx + uint32_t(I)), s}...); + +template +constexpr inline auto build_pb_variant_fields(Field t, std::string_view name, + uint32_t base_idx, + std::index_sequence) { + using value_type = std::remove_pointer_t; + return std::tuple( + pb_field_t>{ + t, (base_idx + uint32_t(I)), name}...); +} + +template +struct make_reverse_index_sequence_helper; + +template +struct make_reverse_index_sequence_helper> + : std::index_sequence<(N - NN)...> {}; + +template +struct make_reverse_index_sequence + : make_reverse_index_sequence_helper< + N - 1, decltype(std::make_index_sequence{})> {}; + +template +constexpr inline auto build_fields_impl(ValueType field, std::string_view name, + uint32_t& index) { + using MemberPtr = decltype(field); + using value_type = std::remove_pointer_t; + if constexpr (is_variant::value) { + constexpr uint32_t variant_size = std::variant_size_v; + size_t base_index = index; + index += (variant_size - 1); + return build_pb_variant_fields(field, name, base_index, + std::make_index_sequence{}); + } + else { + uint32_t field_no = (I == index) ? (I + 1) : (2 + index); + index++; + return std::tuple(pb_field_t(field, field_no, name)); + } +} + +// template +// inline auto cat_pb_fields(Args&&... args) { +// ((std::cout<(args).field_name.data()<<" "),...); +// std::cout << "\n"; +// return std::tuple_cat(args...); +// } + +template +inline auto build_pb_fields(Tuple&& tp, std::index_sequence) { + constexpr auto arr = ylt::reflection::member_names; + uint32_t index = 0; + return (build_fields_impl(&std::get(tp), arr[I], index), ...); +} + +template +inline auto get_pb_members_tuple(T&& t) { + using U = ylt::reflection::remove_cvref_t; + if constexpr (ylt_refletable_v) { + auto tp = ylt::reflection::object_to_tuple(std::forward(t)); + constexpr size_t Size = std::tuple_size_v; + return build_pb_fields(tp, std::make_index_sequence{}); + // return ylt::reflection::visit_members(std::forward(t), [&](auto&... + // args) { + // return build_pb_fields(std::tuple(&args...), + // std::make_index_sequence{}); + // }); + } + else if constexpr (is_custom_reflection_v) { + return get_members_impl((U*)nullptr); + } + else { + static_assert(!sizeof(T), "not a reflectable type"); + } +} + // returns size = key_size + optional(len_size) + len // when key_size == 0, return len template IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { using T = std::remove_const_t>; - if constexpr (is_reflection_v || is_custom_reflection_v) { - size_t len = 0; - static constexpr auto tuple = get_members_tuple(); - constexpr size_t SIZE = std::tuple_size_v>; - size_t pre_index = -1; - if constexpr (!inherits_from_base_v && key_size != 0) { - pre_index = size_arr.size(); - size_arr.push_back(0); // placeholder - } - for_each_n( - [&len, &t, &size_arr](auto i) IGUANA__INLINE_LAMBDA { - using field_type = - std::tuple_element_t>; - constexpr auto value = std::get(tuple); - using U = typename field_type::value_type; - auto const& val = value.value(t); - if constexpr (variant_v) { - constexpr auto offset = - get_variant_index - 1>(); - if constexpr (offset == 0) { - len += pb_oneof_size(val, size_arr); - } - } - else { - constexpr uint32_t sub_key = - (value.field_no << 3) | - static_cast(get_wire_type()); - constexpr auto sub_keysize = variant_uint32_size_constexpr(sub_key); - len += pb_key_value_size(val, size_arr); - } - }, - std::make_index_sequence{}); - if constexpr (inherits_from_base_v) { - t.cache_size = len; - } - else if constexpr (key_size != 0) { - size_arr[pre_index] = len; - } - if constexpr (key_size == 0) { - // for top level - return len; - } - else { - if (len == 0) { - // equals key_size + variant_uint32_size(len) - return key_size + 1; - } - else { - return key_size + variant_uint32_size(static_cast(len)) + len; - } - } - } - else if constexpr (is_sequence_container::value) { - using item_type = typename T::value_type; + if constexpr (ylt_refletable_v) { size_t len = 0; - if constexpr (is_lenprefix_v) { - for (auto& item : t) { - len += pb_key_value_size(item, size_arr); - } - return len; - } - else { - for (auto& item : t) { - // here 0 to get pakced size, and item must be numeric - len += str_numeric_size<0, false>(item); - } - if (len == 0) { - return 0; - } - else { - return key_size + variant_uint32_size(static_cast(len)) + len; - } - } - } - else if constexpr (is_map_container::value) { - size_t len = 0; - for (auto& [k, v] : t) { - // the key_size of k and v is constant 1 - auto kv_len = pb_key_value_size<1, false>(k, size_arr) + - pb_key_value_size<1, false>(v, size_arr); - len += key_size + variant_uint32_size(static_cast(kv_len)) + - kv_len; - } - return len; - } - else if constexpr (optional_v) { - if (!t.has_value()) { - return 0; - } - return pb_key_value_size(*t, size_arr); - } - else { - return str_numeric_size(t); + auto tp = get_pb_members_tuple(std::forward(t)); + std::cout << "\n"; + + // size_t pre_index = -1; + // if constexpr (!inherits_from_base_v && key_size != 0) { + // pre_index = size_arr.size(); + // size_arr.push_back(0); // placeholder + // } + // for_each_n( + // [&len, &t, &size_arr](auto i) IGUANA__INLINE_LAMBDA { + // using field_type = + // std::tuple_element_t>; + // constexpr auto value = std::get(tuple); + // using U = typename field_type::value_type; + // auto const& val = value.value(t); + // if constexpr (variant_v) { + // constexpr auto offset = + // get_variant_index - 1>(); + // if constexpr (offset == 0) { + // len += pb_oneof_size(val, size_arr); + // } + // } + // else { + // constexpr uint32_t sub_key = + // (value.field_no << 3) | + // static_cast(get_wire_type()); + // constexpr auto sub_keysize = + // variant_uint32_size_constexpr(sub_key); len += + // pb_key_value_size(val, size_arr); + // } + // }, + // std::make_index_sequence{}); + // if constexpr (inherits_from_base_v) { + // t.cache_size = len; + // } + // else if constexpr (key_size != 0) { + // size_arr[pre_index] = len; + // } + // if constexpr (key_size == 0) { + // // for top level + // return len; + // } + // else { + // if (len == 0) { + // // equals key_size + variant_uint32_size(len) + // return key_size + 1; + // } + // else { + // return key_size + variant_uint32_size(static_cast(len)) + + // len; + // } + // } + return 0; } + // else if constexpr (is_sequence_container::value) { + // using item_type = typename T::value_type; + // size_t len = 0; + // if constexpr (is_lenprefix_v) { + // for (auto& item : t) { + // len += pb_key_value_size(item, size_arr); + // } + // return len; + // } + // else { + // for (auto& item : t) { + // // here 0 to get pakced size, and item must be numeric + // len += str_numeric_size<0, false>(item); + // } + // if (len == 0) { + // return 0; + // } + // else { + // return key_size + variant_uint32_size(static_cast(len)) + + // len; + // } + // } + // } + // else if constexpr (is_map_container::value) { + // size_t len = 0; + // for (auto& [k, v] : t) { + // // the key_size of k and v is constant 1 + // auto kv_len = pb_key_value_size<1, false>(k, size_arr) + + // pb_key_value_size<1, false>(v, size_arr); + // len += key_size + variant_uint32_size(static_cast(kv_len)) + + // kv_len; + // } + // return len; + // } + // else if constexpr (optional_v) { + // if (!t.has_value()) { + // return 0; + // } + // return pb_key_value_size(*t, size_arr); + // } + // else { + // return str_numeric_size(t); + // } + return 0; } // return the payload size diff --git a/iguana/pb_writer.hpp b/iguana/pb_writer.hpp index 219650fb..c6774da5 100644 --- a/iguana/pb_writer.hpp +++ b/iguana/pb_writer.hpp @@ -449,13 +449,14 @@ IGUANA_INLINE void build_sub_proto(Map& map, std::string_view str_type, #endif } // namespace detail -template +template , int> = 0> IGUANA_INLINE void to_pb(T const& t, Stream& out) { std::vector size_arr; auto byte_len = detail::pb_key_value_size<0>(t, size_arr); detail::resize(out, byte_len); - auto sz_ptr = size_arr.empty() ? nullptr : &size_arr[0]; - detail::to_pb_impl<0>(t, &out[0], sz_ptr); + // auto sz_ptr = size_arr.empty() ? nullptr : &size_arr[0]; + // detail::to_pb_impl<0>(t, &out[0], sz_ptr); } #if defined(__clang__) || defined(_MSC_VER) || \ diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index 4460218b..d722de96 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -10,10 +10,42 @@ struct point_t { int y; }; +struct test_variant { + test_variant() = default; + test_variant(int a, std::variant b, double c) + : x(a), y(std::move(b)), z(c) {} + int x; + std::variant y; + double z; +}; +#if __cplusplus < 202002L +YLT_REFL(test_variant, x, y, z); +#endif + #if __cplusplus < 202002L YLT_REFL(point_t, x, y); #endif +TEST_CASE("test pb") { + { + test_variant t(1, "test", 3); + auto tp = iguana::detail::get_pb_members_tuple(t); + std::cout << "\n"; + // auto tp = iguana::detail::get_pb_members_tuple(t); + assert(std::get<0>(tp).field_no == 1); + // assert(std::get<1>(tp).field_no == 2); + // assert(std::get<2>(tp).field_no == 3); + // assert(std::get<3>(tp).field_no == 4); + // assert(std::get<4>(tp).field_no == 5); + } + + point_t pt{1, 2}; + std::string str; + + iguana::to_pb(pt, str); + std::cout << str.size() << "\n"; +} + TEST_CASE("test simple") { point_t pt{1, 2}; std::string str; From 486ceaad993fa1a4f38bb7f6d9a6012c2ffc3461 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 29 Aug 2024 11:02:21 +0800 Subject: [PATCH 17/44] members_tuple --- iguana/pb_util.hpp | 82 +++++++++++++++++++++++---------------------- test/test_cpp20.cpp | 75 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 110 insertions(+), 47 deletions(-) diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 8dee9075..214a4cf9 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -466,63 +466,61 @@ struct pb_field_t { auto& value() const { return *member_ptr; } }; -// using value_type = typename member_traits::value_type; -// return std::tuple(field_t>{ -// t, (base_idx + uint32_t(I)), s}...); +template +constexpr inline auto get_field_no_impl(Array& arr, size_t& index) { + arr[I] = index; + using value_type = std::remove_pointer_t; + if constexpr (is_variant::value) { + constexpr size_t variant_size = std::variant_size_v; + index += (variant_size); + } + else { + index++; + return; + } +} + +template +inline constexpr auto get_field_no(std::index_sequence) { + std::array arr{}; + size_t index = 0; + (get_field_no_impl(std::declval()))>(arr, + index), + ...); + return arr; +} template constexpr inline auto build_pb_variant_fields(Field t, std::string_view name, - uint32_t base_idx, + size_t field_no, std::index_sequence) { using value_type = std::remove_pointer_t; return std::tuple( pb_field_t>{ - t, (base_idx + uint32_t(I)), name}...); + t, (uint32_t)(field_no + I), name}...); } -template -struct make_reverse_index_sequence_helper; - -template -struct make_reverse_index_sequence_helper> - : std::index_sequence<(N - NN)...> {}; - -template -struct make_reverse_index_sequence - : make_reverse_index_sequence_helper< - N - 1, decltype(std::make_index_sequence{})> {}; - -template -constexpr inline auto build_fields_impl(ValueType field, std::string_view name, - uint32_t& index) { - using MemberPtr = decltype(field); +template +constexpr inline auto build_pb_fields_impl(ValueType field, + std::string_view name, + size_t field_no) { using value_type = std::remove_pointer_t; if constexpr (is_variant::value) { constexpr uint32_t variant_size = std::variant_size_v; - size_t base_index = index; - index += (variant_size - 1); - return build_pb_variant_fields(field, name, base_index, + return build_pb_variant_fields(field, name, field_no, std::make_index_sequence{}); } else { - uint32_t field_no = (I == index) ? (I + 1) : (2 + index); - index++; - return std::tuple(pb_field_t(field, field_no, name)); + return std::tuple(pb_field_t(field, field_no, name)); } } -// template -// inline auto cat_pb_fields(Args&&... args) { -// ((std::cout<(args).field_name.data()<<" "),...); -// std::cout << "\n"; -// return std::tuple_cat(args...); -// } - -template -inline auto build_pb_fields(Tuple&& tp, std::index_sequence) { +template +inline auto build_pb_fields(Tuple&& tp, const Array& indexs, + std::index_sequence) { constexpr auto arr = ylt::reflection::member_names; - uint32_t index = 0; - return (build_fields_impl(&std::get(tp), arr[I], index), ...); + return std::tuple_cat( + build_pb_fields_impl(&std::get(tp), arr[I], indexs[I] + 1)...); } template @@ -531,7 +529,11 @@ inline auto get_pb_members_tuple(T&& t) { if constexpr (ylt_refletable_v) { auto tp = ylt::reflection::object_to_tuple(std::forward(t)); constexpr size_t Size = std::tuple_size_v; - return build_pb_fields(tp, std::make_index_sequence{}); + + constexpr std::array arr = + get_field_no(std::make_index_sequence{}); + + return build_pb_fields(tp, arr, std::make_index_sequence{}); // return ylt::reflection::visit_members(std::forward(t), [&](auto&... // args) { // return build_pb_fields(std::tuple(&args...), @@ -552,7 +554,7 @@ template IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { using T = std::remove_const_t>; if constexpr (ylt_refletable_v) { - size_t len = 0; + // size_t len = 0; auto tp = get_pb_members_tuple(std::forward(t)); std::cout << "\n"; diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index d722de96..0cc7702f 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -22,6 +22,30 @@ struct test_variant { YLT_REFL(test_variant, x, y, z); #endif +struct test_variant1 { + std::variant x; + int y; + double z; +}; +YLT_REFL(test_variant1, x, y, z); + +struct test_variant2 { + int x; + double y; + std::variant z; +}; +YLT_REFL(test_variant2, x, y, z); + +struct test_variant3 { + int x; + std::variant y; + int z; + std::variant a; + double b; + double c; +}; +YLT_REFL(test_variant3, x, y, z, a, b, c); + #if __cplusplus < 202002L YLT_REFL(point_t, x, y); #endif @@ -30,13 +54,50 @@ TEST_CASE("test pb") { { test_variant t(1, "test", 3); auto tp = iguana::detail::get_pb_members_tuple(t); - std::cout << "\n"; - // auto tp = iguana::detail::get_pb_members_tuple(t); - assert(std::get<0>(tp).field_no == 1); - // assert(std::get<1>(tp).field_no == 2); - // assert(std::get<2>(tp).field_no == 3); - // assert(std::get<3>(tp).field_no == 4); - // assert(std::get<4>(tp).field_no == 5); + + CHECK(std::get<0>(tp).field_no == 1); + CHECK(std::get<1>(tp).field_no == 2); + CHECK(std::get<2>(tp).field_no == 3); + CHECK(std::get<3>(tp).field_no == 4); + CHECK(std::get<4>(tp).field_no == 5); + } + + { + test_variant1 t{"test", 2, 3}; + auto tp = iguana::detail::get_pb_members_tuple(t); + + CHECK(std::get<0>(tp).field_no == 1); + CHECK(std::get<1>(tp).field_no == 2); + CHECK(std::get<2>(tp).field_no == 3); + CHECK(std::get<3>(tp).field_no == 4); + CHECK(std::get<4>(tp).field_no == 5); + } + + { + test_variant2 t{2, 3, "test"}; + auto tp = iguana::detail::get_pb_members_tuple(t); + + CHECK(std::get<0>(tp).field_no == 1); + CHECK(std::get<1>(tp).field_no == 2); + CHECK(std::get<2>(tp).field_no == 3); + CHECK(std::get<3>(tp).field_no == 4); + CHECK(std::get<4>(tp).field_no == 5); + } + + { + test_variant3 t{2, "test", 3, "ok", 5, 6}; + auto tp = iguana::detail::get_pb_members_tuple(t); + + CHECK(std::get<0>(tp).field_no == 1); + CHECK(std::get<1>(tp).field_no == 2); + CHECK(std::get<2>(tp).field_no == 3); + CHECK(std::get<3>(tp).field_no == 4); + CHECK(std::get<4>(tp).field_no == 5); + CHECK(std::get<5>(tp).field_no == 6); + CHECK(std::get<6>(tp).field_no == 7); + CHECK(std::get<7>(tp).field_no == 8); + CHECK(std::get<8>(tp).field_no == 9); + CHECK(std::get<9>(tp).field_no == 10); } point_t pt{1, 2}; From ada7f74325b657d725ea58f9e3fdeaee50207fa5 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 29 Aug 2024 16:03:37 +0800 Subject: [PATCH 18/44] use offset --- iguana/pb_util.hpp | 88 ++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 214a4cf9..1af7706c 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -446,32 +446,31 @@ template inline constexpr bool is_custom_reflection_v = is_custom_reflection>::value; -// T: parant type, value_type: member value pointer type, SubType: subtype from +// owner_type: parant type, value_type: member value type, SubType: subtype from // variant -template > +template ::value_type> struct pb_field_t { - using owner_type = T; - using value_type = ValuePtr; - using sub_type = SubType; + using member_type = MemberPtr; + using owner_type = typename member_traits::owner_type; + using value_type = typename member_traits::value_type; + using sub_type = ElementType; + constexpr pb_field_t() = default; - explicit constexpr pb_field_t(ValuePtr member, uint32_t number, - frozen::string name = "") - : member_ptr(member), field_name(name), field_no(number) {} + auto& value(owner_type& value) const { return value.*member_ptr; } + auto const& value(owner_type const& value) const { return value.*member_ptr; } - ValuePtr member_ptr; - frozen::string field_name; - uint32_t field_no; + MemberPtr member_ptr; + std::string_view field_name; - auto& value() const { return *member_ptr; } + inline static constexpr uint32_t field_no = FieldNo; }; template constexpr inline auto get_field_no_impl(Array& arr, size_t& index) { arr[I] = index; - using value_type = std::remove_pointer_t; - if constexpr (is_variant::value) { - constexpr size_t variant_size = std::variant_size_v; + if constexpr (is_variant::value) { + constexpr size_t variant_size = std::variant_size_v; index += (variant_size); } else { @@ -484,56 +483,59 @@ template inline constexpr auto get_field_no(std::index_sequence) { std::array arr{}; size_t index = 0; - (get_field_no_impl(std::declval()))>(arr, - index), + (get_field_no_impl>>( + arr, index), ...); return arr; } -template -constexpr inline auto build_pb_variant_fields(Field t, std::string_view name, - size_t field_no, +template +constexpr inline auto build_pb_variant_fields(MemberPtr field, + std::string_view name, std::index_sequence) { - using value_type = std::remove_pointer_t; + using value_type = typename member_traits::value_type; return std::tuple( - pb_field_t>{ - t, (uint32_t)(field_no + I), name}...); + pb_field_t>{field, name}...); } -template -constexpr inline auto build_pb_fields_impl(ValueType field, - std::string_view name, - size_t field_no) { - using value_type = std::remove_pointer_t; +template +constexpr inline auto build_pb_fields_impl(size_t offset, + std::string_view name) { + using value_type = std::remove_pointer_t>; + using U = std::remove_reference_t; + using P = value_type U::*; + P member_ptr = *reinterpret_cast(&offset); + if constexpr (is_variant::value) { constexpr uint32_t variant_size = std::variant_size_v; - return build_pb_variant_fields(field, name, field_no, - std::make_index_sequence{}); + return build_pb_variant_fields( + std::move(member_ptr), name, std::make_index_sequence{}); } else { - return std::tuple(pb_field_t(field, field_no, name)); + return std::tuple(pb_field_t{member_ptr, name}); } } -template -inline auto build_pb_fields(Tuple&& tp, const Array& indexs, +template +inline auto build_pb_fields(T&& t, const Array& offset_arr, std::index_sequence) { constexpr auto arr = ylt::reflection::member_names; + constexpr std::array indexs = + get_field_no(std::make_index_sequence{}); return std::tuple_cat( - build_pb_fields_impl(&std::get(tp), arr[I], indexs[I] + 1)...); + build_pb_fields_impl>( + offset_arr[I], arr[I])...); } template inline auto get_pb_members_tuple(T&& t) { using U = ylt::reflection::remove_cvref_t; if constexpr (ylt_refletable_v) { - auto tp = ylt::reflection::object_to_tuple(std::forward(t)); - constexpr size_t Size = std::tuple_size_v; - - constexpr std::array arr = - get_field_no(std::make_index_sequence{}); - - return build_pb_fields(tp, arr, std::make_index_sequence{}); + static auto& offset_arr = ylt::reflection::member_offsets; + using Tuple = decltype(ylt::reflection::struct_to_tuple()); + return build_pb_fields( + t, offset_arr, std::make_index_sequence>{}); // return ylt::reflection::visit_members(std::forward(t), [&](auto&... // args) { // return build_pb_fields(std::tuple(&args...), @@ -555,7 +557,7 @@ IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { using T = std::remove_const_t>; if constexpr (ylt_refletable_v) { // size_t len = 0; - auto tp = get_pb_members_tuple(std::forward(t)); + static auto tp = get_pb_members_tuple(std::forward(t)); std::cout << "\n"; // size_t pre_index = -1; From f3cf85b4f05cf1baa9a59717ac4282a4c9f2eb92 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 29 Aug 2024 16:13:34 +0800 Subject: [PATCH 19/44] clean --- iguana/pb_util.hpp | 10 +++++----- test/test_cpp20.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 1af7706c..c943b187 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -518,7 +518,7 @@ constexpr inline auto build_pb_fields_impl(size_t offset, } template -inline auto build_pb_fields(T&& t, const Array& offset_arr, +inline auto build_pb_fields(const Array& offset_arr, std::index_sequence) { constexpr auto arr = ylt::reflection::member_names; constexpr std::array indexs = @@ -529,13 +529,13 @@ inline auto build_pb_fields(T&& t, const Array& offset_arr, } template -inline auto get_pb_members_tuple(T&& t) { +inline auto get_pb_members_tuple() { using U = ylt::reflection::remove_cvref_t; if constexpr (ylt_refletable_v) { static auto& offset_arr = ylt::reflection::member_offsets; using Tuple = decltype(ylt::reflection::struct_to_tuple()); - return build_pb_fields( - t, offset_arr, std::make_index_sequence>{}); + return build_pb_fields( + offset_arr, std::make_index_sequence>{}); // return ylt::reflection::visit_members(std::forward(t), [&](auto&... // args) { // return build_pb_fields(std::tuple(&args...), @@ -557,7 +557,7 @@ IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { using T = std::remove_const_t>; if constexpr (ylt_refletable_v) { // size_t len = 0; - static auto tp = get_pb_members_tuple(std::forward(t)); + static auto tp = get_pb_members_tuple(); std::cout << "\n"; // size_t pre_index = -1; diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index 0cc7702f..fc2cb0a0 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -53,7 +53,7 @@ YLT_REFL(point_t, x, y); TEST_CASE("test pb") { { test_variant t(1, "test", 3); - auto tp = iguana::detail::get_pb_members_tuple(t); + auto tp = iguana::detail::get_pb_members_tuple(); CHECK(std::get<0>(tp).field_no == 1); CHECK(std::get<1>(tp).field_no == 2); @@ -64,7 +64,7 @@ TEST_CASE("test pb") { { test_variant1 t{"test", 2, 3}; - auto tp = iguana::detail::get_pb_members_tuple(t); + auto tp = iguana::detail::get_pb_members_tuple(); CHECK(std::get<0>(tp).field_no == 1); CHECK(std::get<1>(tp).field_no == 2); @@ -75,7 +75,7 @@ TEST_CASE("test pb") { { test_variant2 t{2, 3, "test"}; - auto tp = iguana::detail::get_pb_members_tuple(t); + auto tp = iguana::detail::get_pb_members_tuple(); CHECK(std::get<0>(tp).field_no == 1); CHECK(std::get<1>(tp).field_no == 2); @@ -86,7 +86,7 @@ TEST_CASE("test pb") { { test_variant3 t{2, "test", 3, "ok", 5, 6}; - auto tp = iguana::detail::get_pb_members_tuple(t); + auto tp = iguana::detail::get_pb_members_tuple(); CHECK(std::get<0>(tp).field_no == 1); CHECK(std::get<1>(tp).field_no == 2); From ff32e93ae9ca1c1fe25423f0fc6baa9620f63d61 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 29 Aug 2024 16:32:57 +0800 Subject: [PATCH 20/44] pb writer --- iguana/pb_util.hpp | 196 +++++++++++++++++++++---------------------- iguana/pb_writer.hpp | 26 +++--- test/test_cpp20.cpp | 4 + 3 files changed, 112 insertions(+), 114 deletions(-) diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index c943b187..dac306d2 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -14,7 +14,7 @@ #include #include "detail/pb_type.hpp" -#include "reflection.hpp" +// #include "reflection.hpp" #include "util.hpp" namespace iguana { @@ -556,107 +556,101 @@ template IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { using T = std::remove_const_t>; if constexpr (ylt_refletable_v) { - // size_t len = 0; - static auto tp = get_pb_members_tuple(); - std::cout << "\n"; - - // size_t pre_index = -1; - // if constexpr (!inherits_from_base_v && key_size != 0) { - // pre_index = size_arr.size(); - // size_arr.push_back(0); // placeholder - // } - // for_each_n( - // [&len, &t, &size_arr](auto i) IGUANA__INLINE_LAMBDA { - // using field_type = - // std::tuple_element_t>; - // constexpr auto value = std::get(tuple); - // using U = typename field_type::value_type; - // auto const& val = value.value(t); - // if constexpr (variant_v) { - // constexpr auto offset = - // get_variant_index - 1>(); - // if constexpr (offset == 0) { - // len += pb_oneof_size(val, size_arr); - // } - // } - // else { - // constexpr uint32_t sub_key = - // (value.field_no << 3) | - // static_cast(get_wire_type()); - // constexpr auto sub_keysize = - // variant_uint32_size_constexpr(sub_key); len += - // pb_key_value_size(val, size_arr); - // } - // }, - // std::make_index_sequence{}); - // if constexpr (inherits_from_base_v) { - // t.cache_size = len; - // } - // else if constexpr (key_size != 0) { - // size_arr[pre_index] = len; - // } - // if constexpr (key_size == 0) { - // // for top level - // return len; - // } - // else { - // if (len == 0) { - // // equals key_size + variant_uint32_size(len) - // return key_size + 1; - // } - // else { - // return key_size + variant_uint32_size(static_cast(len)) + - // len; - // } - // } - return 0; + size_t len = 0; + static auto tuple = get_pb_members_tuple(); + constexpr size_t SIZE = std::tuple_size_v>; + size_t pre_index = -1; + if constexpr (!inherits_from_base_v && key_size != 0) { + pre_index = size_arr.size(); + size_arr.push_back(0); // placeholder + } + for_each_n( + [&len, &t, &size_arr](auto i) IGUANA__INLINE_LAMBDA { + using field_type = + std::tuple_element_t>; + auto value = std::get(tuple); + using U = typename field_type::value_type; + auto& val = value.value(t); + if constexpr (variant_v) { + constexpr auto offset = + get_variant_index - 1>(); + if constexpr (offset == 0) { + len += pb_oneof_size(val, size_arr); + } + } + else { + constexpr uint32_t sub_key = + (value.field_no << 3) | + static_cast(get_wire_type()); + constexpr auto sub_keysize = variant_uint32_size_constexpr(sub_key); + len += pb_key_value_size(val, size_arr); + } + }, + std::make_index_sequence{}); + if constexpr (inherits_from_base_v) { + t.cache_size = len; + } + else if constexpr (key_size != 0) { + size_arr[pre_index] = len; + } + if constexpr (key_size == 0) { + // for top level + return len; + } + else { + if (len == 0) { + // equals key_size + variant_uint32_size(len) + return key_size + 1; + } + else { + return key_size + variant_uint32_size(static_cast(len)) + len; + } + } + } + else if constexpr (is_sequence_container::value) { + using item_type = typename T::value_type; + size_t len = 0; + if constexpr (is_lenprefix_v) { + for (auto& item : t) { + len += pb_key_value_size(item, size_arr); + } + return len; + } + else { + for (auto& item : t) { + // here 0 to get pakced size, and item must be numeric + len += str_numeric_size<0, false>(item); + } + if (len == 0) { + return 0; + } + else { + return key_size + variant_uint32_size(static_cast(len)) + len; + } + } + } + else if constexpr (is_map_container::value) { + size_t len = 0; + for (auto& [k, v] : t) { + // the key_size of k and v is constant 1 + auto kv_len = pb_key_value_size<1, false>(k, size_arr) + + pb_key_value_size<1, false>(v, size_arr); + len += key_size + variant_uint32_size(static_cast(kv_len)) + + kv_len; + } + return len; + } + else if constexpr (optional_v) { + if (!t.has_value()) { + return 0; + } + return pb_key_value_size(*t, size_arr); + } + else { + return str_numeric_size(t); } - // else if constexpr (is_sequence_container::value) { - // using item_type = typename T::value_type; - // size_t len = 0; - // if constexpr (is_lenprefix_v) { - // for (auto& item : t) { - // len += pb_key_value_size(item, size_arr); - // } - // return len; - // } - // else { - // for (auto& item : t) { - // // here 0 to get pakced size, and item must be numeric - // len += str_numeric_size<0, false>(item); - // } - // if (len == 0) { - // return 0; - // } - // else { - // return key_size + variant_uint32_size(static_cast(len)) + - // len; - // } - // } - // } - // else if constexpr (is_map_container::value) { - // size_t len = 0; - // for (auto& [k, v] : t) { - // // the key_size of k and v is constant 1 - // auto kv_len = pb_key_value_size<1, false>(k, size_arr) + - // pb_key_value_size<1, false>(v, size_arr); - // len += key_size + variant_uint32_size(static_cast(kv_len)) + - // kv_len; - // } - // return len; - // } - // else if constexpr (optional_v) { - // if (!t.has_value()) { - // return 0; - // } - // return pb_key_value_size(*t, size_arr); - // } - // else { - // return str_numeric_size(t); - // } - return 0; } // return the payload size diff --git a/iguana/pb_writer.hpp b/iguana/pb_writer.hpp index c6774da5..247ca35a 100644 --- a/iguana/pb_writer.hpp +++ b/iguana/pb_writer.hpp @@ -100,7 +100,7 @@ IGUANA_INLINE void to_pb_oneof(Type&& t, It&& it, uint32_t*& sz_ptr) { template IGUANA_INLINE void to_pb_impl(Type&& t, It&& it, uint32_t*& sz_ptr) { using T = std::remove_const_t>; - if constexpr (is_reflection_v || is_custom_reflection_v) { + if constexpr (ylt_refletable_v || is_custom_reflection_v) { // can't be omitted even if values are empty if constexpr (key != 0) { auto len = pb_value_size(t, sz_ptr); @@ -109,14 +109,14 @@ IGUANA_INLINE void to_pb_impl(Type&& t, It&& it, uint32_t*& sz_ptr) { if (len == 0) IGUANA_UNLIKELY { return; } } - static constexpr auto tuple = get_members_tuple(); + static auto tuple = get_pb_members_tuple(); constexpr size_t SIZE = std::tuple_size_v>; for_each_n( [&t, &it, &sz_ptr](auto i) IGUANA__INLINE_LAMBDA { using field_type = std::tuple_element_t>; - constexpr auto value = std::get(tuple); + auto value = std::get(tuple); auto& val = value.value(t); using U = typename field_type::value_type; @@ -297,10 +297,10 @@ IGUANA_INLINE void to_proto_impl( std::string_view field_name = "", uint32_t field_no = 0) { std::string sub_str; using T = std::remove_const_t>; - if constexpr (is_reflection_v || is_custom_reflection_v) { - constexpr auto name = get_name(); + if constexpr (ylt_refletable_v || is_custom_reflection_v) { + constexpr auto name = type_string(); out.append("message ").append(name).append(" {\n"); - static constexpr auto tuple = get_members_tuple(); + static auto tuple = get_pb_members_tuple(); constexpr size_t SIZE = std::tuple_size_v>; for_each_n( @@ -308,10 +308,10 @@ IGUANA_INLINE void to_proto_impl( using field_type = std::tuple_element_t>; - constexpr auto value = std::get(tuple); + auto value = std::get(tuple); using U = typename field_type::value_type; - if constexpr (is_reflection_v) { + if constexpr (ylt_refletable_v) { constexpr auto str_type = get_type_string(); build_proto_field( out, str_type, @@ -340,7 +340,7 @@ IGUANA_INLINE void to_proto_impl( out.append(" "); build_proto_field(out, str_type, field_name, value.field_no); - if constexpr (is_reflection_v) { + if constexpr (ylt_refletable_v) { build_sub_proto(map, str_type, sub_str); } @@ -363,7 +363,7 @@ IGUANA_INLINE void to_proto_impl( if constexpr (is_lenprefix_v) { // non-packed - if constexpr (is_reflection_v) { + if constexpr (ylt_refletable_v) { constexpr auto str_type = get_type_string(); build_proto_field(out, str_type, field_name, field_no); @@ -389,7 +389,7 @@ IGUANA_INLINE void to_proto_impl( build_proto_field<1>(out, "", field_name, field_no); - if constexpr (is_reflection_v) { + if constexpr (ylt_refletable_v) { constexpr auto str_type = get_type_string(); build_sub_proto(map, str_type, sub_str); } @@ -455,8 +455,8 @@ IGUANA_INLINE void to_pb(T const& t, Stream& out) { std::vector size_arr; auto byte_len = detail::pb_key_value_size<0>(t, size_arr); detail::resize(out, byte_len); - // auto sz_ptr = size_arr.empty() ? nullptr : &size_arr[0]; - // detail::to_pb_impl<0>(t, &out[0], sz_ptr); + auto sz_ptr = size_arr.empty() ? nullptr : &size_arr[0]; + detail::to_pb_impl<0>(t, &out[0], sz_ptr); } #if defined(__clang__) || defined(_MSC_VER) || \ diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index fc2cb0a0..0205d06b 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -105,6 +105,10 @@ TEST_CASE("test pb") { iguana::to_pb(pt, str); std::cout << str.size() << "\n"; + + std::string proto; + iguana::to_proto(proto); + std::cout << proto; } TEST_CASE("test simple") { From 3c31e582bd76129ce0bdacb7eb93370ab02a80ff Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 29 Aug 2024 16:52:10 +0800 Subject: [PATCH 21/44] pb writer --- iguana/pb_reader.hpp | 11 ++++----- iguana/pb_util.hpp | 53 ++++++++++++++++++++++++++++++++++++++++++++ test/test_cpp20.cpp | 11 +++++++++ 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/iguana/pb_reader.hpp b/iguana/pb_reader.hpp index 83d2425d..aa9d85e3 100644 --- a/iguana/pb_reader.hpp +++ b/iguana/pb_reader.hpp @@ -227,7 +227,7 @@ IGUANA_INLINE void from_pb(T& t, std::string_view pb_str) { #endif while (true) { pb_str = pb_str.substr(pos); - constexpr static auto map = get_members(); + static auto map = detail::get_members(); auto& member = map.at(field_number); std::visit( [&t, &pb_str, wire_type](auto& val) { @@ -256,8 +256,9 @@ IGUANA_INLINE void from_pb(T& t, std::string_view pb_str) { } } -template -IGUANA_INLINE void from_pb_adl(iguana_adl_t* p, T& t, std::string_view pb_str) { - iguana::from_pb(t, pb_str); -} +// template +// IGUANA_INLINE void from_pb_adl(iguana_adl_t* p, T& t, std::string_view +// pb_str) { +// iguana::from_pb(t, pb_str); +// } } // namespace iguana diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index dac306d2..89b8fe71 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -698,5 +698,58 @@ IGUANA_INLINE size_t pb_value_size(Type&& t, uint32_t*& sz_ptr) { } } +template +struct field_type_t; + +template +struct field_type_t> { + using value_type = std::variant; +}; + +template +constexpr size_t count_variant_size() { + if constexpr (is_variant::value) { + return std::variant_size_v; + } + else { + return 1; + } +} + +template +constexpr size_t tuple_type_count_impl(std::index_sequence) { + return ( + (count_variant_size>>() + + ...)); +} + +template +constexpr size_t tuple_type_count() { + return tuple_type_count_impl( + std::make_index_sequence>{}); +} + +template +constexpr auto inline get_members_impl(Tuple&& tp, std::index_sequence) { + return frozen::unordered_map{ + {std::get(tp).field_no, + T{std::in_place_index, std::move(std::get(tp))}}...}; +} + +template +inline auto get_members() { + if constexpr (ylt_refletable_v || is_custom_reflection_v) { + static auto tp = get_pb_members_tuple(); + using Tuple = std::decay_t; + using value_type = typename field_type_t::value_type; + constexpr auto Size = tuple_type_count(); + return get_members_impl(tp, + std::make_index_sequence{}); + } + else { + static_assert(!sizeof(T), "expected reflection or custom reflection"); + } +} + } // namespace detail } // namespace iguana \ No newline at end of file diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index 0205d06b..f70b6437 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -98,6 +98,14 @@ TEST_CASE("test pb") { CHECK(std::get<7>(tp).field_no == 8); CHECK(std::get<8>(tp).field_no == 9); CHECK(std::get<9>(tp).field_no == 10); + + std::string str; + iguana::to_pb(t, str); + std::cout << str.size() << "\n"; + + test_variant3 pt1; + iguana::from_pb(pt1, str); + std::cout << "\n"; } point_t pt{1, 2}; @@ -106,6 +114,9 @@ TEST_CASE("test pb") { iguana::to_pb(pt, str); std::cout << str.size() << "\n"; + point_t pt1; + iguana::from_pb(pt1, str); + std::string proto; iguana::to_proto(proto); std::cout << proto; From 7525f64158a2a0761105fc59cf89bd137358885e Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 29 Aug 2024 16:56:10 +0800 Subject: [PATCH 22/44] fix compile --- iguana/pb_reader.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/pb_reader.hpp b/iguana/pb_reader.hpp index aa9d85e3..039175a1 100644 --- a/iguana/pb_reader.hpp +++ b/iguana/pb_reader.hpp @@ -191,12 +191,12 @@ IGUANA_INLINE void from_pb(T& t, std::string_view pb_str) { WireType wire_type = static_cast(key & 0b0111); uint32_t field_number = key >> 3; #ifdef SEQUENTIAL_PARSE - constexpr static auto tp = get_members_tuple(); + static auto tp = detail::get_pb_members_tuple(); constexpr size_t SIZE = std::tuple_size_v>; bool parse_done = false; detail::for_each_n( [&](auto i) IGUANA__INLINE_LAMBDA { - constexpr auto val = std::get(tp); + auto val = std::get(tp); using sub_type = typename std::decay_t::sub_type; using value_type = typename std::decay_t::value_type; // sub_type is the element type when value_type is the variant type; From a620135975fd9659d50dc225bc36e16e0c2a6e0c Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 29 Aug 2024 17:49:09 +0800 Subject: [PATCH 23/44] compile --- iguana/pb_util.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 89b8fe71..3d5b45a6 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -60,7 +60,7 @@ constexpr inline WireType get_wire_type() { } else if constexpr (std::is_same_v || std::is_same_v || - is_reflection_v || is_sequence_container::value || + ylt_refletable_v || is_sequence_container::value || is_map_container::value) { return WireType::LengthDelimeted; } @@ -657,7 +657,7 @@ IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { template IGUANA_INLINE size_t pb_value_size(Type&& t, uint32_t*& sz_ptr) { using T = std::remove_const_t>; - if constexpr (is_reflection_v || is_custom_reflection_v) { + if constexpr (ylt_refletable_v || is_custom_reflection_v) { if constexpr (inherits_from_base_v) { return t.cache_size; } From 0f49f2c96f3f17918c529e669428d75852791d70 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 29 Aug 2024 17:51:46 +0800 Subject: [PATCH 24/44] compile --- iguana/pb_reader.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/pb_reader.hpp b/iguana/pb_reader.hpp index 039175a1..09cfa0fd 100644 --- a/iguana/pb_reader.hpp +++ b/iguana/pb_reader.hpp @@ -27,7 +27,7 @@ template IGUANA_INLINE void from_pb_impl(T& val, std::string_view& pb_str, uint32_t field_no) { size_t pos = 0; - if constexpr (is_reflection_v) { + if constexpr (ylt_refletable_v) { size_t pos; uint32_t size = detail::decode_varint(pb_str, pos); pb_str = pb_str.substr(pos); From e7683e7d13a3c1d458e57554553bf829a4b681e4 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Fri, 30 Aug 2024 16:35:11 +0800 Subject: [PATCH 25/44] pb reader --- iguana/pb_reader.hpp | 4 +- iguana/pb_util.hpp | 18 +++++---- iguana/pb_writer.hpp | 5 ++- iguana/ylt/reflection/member_names.hpp | 22 ++++++----- test/test_cpp20.cpp | 52 +++++++++++++++++++++++--- 5 files changed, 74 insertions(+), 27 deletions(-) diff --git a/iguana/pb_reader.hpp b/iguana/pb_reader.hpp index 09cfa0fd..978a616c 100644 --- a/iguana/pb_reader.hpp +++ b/iguana/pb_reader.hpp @@ -191,7 +191,7 @@ IGUANA_INLINE void from_pb(T& t, std::string_view pb_str) { WireType wire_type = static_cast(key & 0b0111); uint32_t field_number = key >> 3; #ifdef SEQUENTIAL_PARSE - static auto tp = detail::get_pb_members_tuple(); + static auto tp = detail::get_pb_members_tuple(t); constexpr size_t SIZE = std::tuple_size_v>; bool parse_done = false; detail::for_each_n( @@ -227,7 +227,7 @@ IGUANA_INLINE void from_pb(T& t, std::string_view pb_str) { #endif while (true) { pb_str = pb_str.substr(pos); - static auto map = detail::get_members(); + static auto map = detail::get_members(std::forward(t)); auto& member = map.at(field_number); std::visit( [&t, &pb_str, wire_type](auto& val) { diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 3d5b45a6..393f672a 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -483,7 +483,8 @@ template inline constexpr auto get_field_no(std::index_sequence) { std::array arr{}; size_t index = 0; - (get_field_no_impl>>( + (get_field_no_impl< + I, ylt::reflection::remove_cvref_t>>( arr, index), ...); return arr; @@ -502,7 +503,7 @@ constexpr inline auto build_pb_variant_fields(MemberPtr field, template constexpr inline auto build_pb_fields_impl(size_t offset, std::string_view name) { - using value_type = std::remove_pointer_t>; + using value_type = ylt::reflection::remove_cvref_t; using U = std::remove_reference_t; using P = value_type U::*; P member_ptr = *reinterpret_cast(&offset); @@ -529,11 +530,12 @@ inline auto build_pb_fields(const Array& offset_arr, } template -inline auto get_pb_members_tuple() { +inline auto get_pb_members_tuple(T&& t) { using U = ylt::reflection::remove_cvref_t; if constexpr (ylt_refletable_v) { - static auto& offset_arr = ylt::reflection::member_offsets; - using Tuple = decltype(ylt::reflection::struct_to_tuple()); + static auto& offset_arr = + ylt::reflection::internal::get_member_offset_arr(std::forward(t)); + using Tuple = decltype(ylt::reflection::object_to_tuple(std::declval())); return build_pb_fields( offset_arr, std::make_index_sequence>{}); // return ylt::reflection::visit_members(std::forward(t), [&](auto&... @@ -557,7 +559,7 @@ IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { using T = std::remove_const_t>; if constexpr (ylt_refletable_v) { size_t len = 0; - static auto tuple = get_pb_members_tuple(); + static auto tuple = get_pb_members_tuple(std::forward(t)); constexpr size_t SIZE = std::tuple_size_v>; size_t pre_index = -1; if constexpr (!inherits_from_base_v && key_size != 0) { @@ -737,9 +739,9 @@ constexpr auto inline get_members_impl(Tuple&& tp, std::index_sequence) { } template -inline auto get_members() { +inline auto get_members(T&& t) { if constexpr (ylt_refletable_v || is_custom_reflection_v) { - static auto tp = get_pb_members_tuple(); + static auto tp = get_pb_members_tuple(std::forward(t)); using Tuple = std::decay_t; using value_type = typename field_type_t::value_type; constexpr auto Size = tuple_type_count(); diff --git a/iguana/pb_writer.hpp b/iguana/pb_writer.hpp index 247ca35a..d3073fa9 100644 --- a/iguana/pb_writer.hpp +++ b/iguana/pb_writer.hpp @@ -109,7 +109,7 @@ IGUANA_INLINE void to_pb_impl(Type&& t, It&& it, uint32_t*& sz_ptr) { if (len == 0) IGUANA_UNLIKELY { return; } } - static auto tuple = get_pb_members_tuple(); + static auto tuple = get_pb_members_tuple(std::forward(t)); constexpr size_t SIZE = std::tuple_size_v>; for_each_n( [&t, &it, &sz_ptr](auto i) IGUANA__INLINE_LAMBDA { @@ -300,7 +300,8 @@ IGUANA_INLINE void to_proto_impl( if constexpr (ylt_refletable_v || is_custom_reflection_v) { constexpr auto name = type_string(); out.append("message ").append(name).append(" {\n"); - static auto tuple = get_pb_members_tuple(); + static T t; + static auto tuple = get_pb_members_tuple(t); constexpr size_t SIZE = std::tuple_size_v>; for_each_n( diff --git a/iguana/ylt/reflection/member_names.hpp b/iguana/ylt/reflection/member_names.hpp index fbaa5ad2..2e0efac8 100644 --- a/iguana/ylt/reflection/member_names.hpp +++ b/iguana/ylt/reflection/member_names.hpp @@ -107,25 +107,22 @@ inline constexpr auto get_member_names_map() { } template -inline auto get_member_offset_arr_impl(Tuple& tp, std::index_sequence) { +inline auto get_member_offset_arr_impl(T& t, Tuple& tp, + std::index_sequence) { std::array arr; - ((arr[Is] = size_t((const char*)std::get(tp) - - (char*)(&internal::wrapper::value))), - ...); + ((arr[Is] = size_t((const char*)&std::get(tp) - (char*)(&t))), ...); return arr; } template -inline const auto& get_member_offset_arr() { +inline const auto& get_member_offset_arr(T&& t) { constexpr size_t Count = members_count_v; - constexpr auto tp = struct_to_tuple(); + auto tp = ylt::reflection::object_to_tuple(std::forward(t)); #if __cplusplus >= 202002L [[maybe_unused]] static std::array arr = {[&]( std::index_sequence) mutable {std::array arr; - ((arr[Is] = size_t((const char*)std::get(tp) - - (char*)(&internal::wrapper::value))), - ...); + ((arr[Is] = size_t((const char*)&std::get(tp) - (char*)(&t))), ...); return arr; } (std::make_index_sequence{}) @@ -134,10 +131,15 @@ inline const auto& get_member_offset_arr() { return arr; #else [[maybe_unused]] static std::array arr = - get_member_offset_arr_impl(tp, std::make_index_sequence{}); + get_member_offset_arr_impl(t, tp, std::make_index_sequence{}); return arr; #endif } // namespace ylt::reflection + +template +inline const auto& get_member_offset_arr() { + return get_member_offset_arr(internal::wrapper::value); +} // namespace ylt::reflection } // namespace internal template diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index f70b6437..60618d92 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -1,5 +1,5 @@ #define DOCTEST_CONFIG_IMPLEMENT -// #define SEQUENTIAL_PARSE +#define SEQUENTIAL_PARSE #include "doctest.h" #include "iguana/iguana.hpp" @@ -50,10 +50,52 @@ YLT_REFL(test_variant3, x, y, z, a, b, c); YLT_REFL(point_t, x, y); #endif +struct test_variant4 { + test_variant4() = default; + test_variant4(int a, std::variant b, double c) + : x(a), y(std::move(b)), z(c) {} + +#if __cplusplus < 202002L + YLT_REFL(test_variant4, x, y, z); +#endif + + private: + int x; + std::variant y; + double z; +}; + TEST_CASE("test pb") { + { + using Tuple1 = decltype(ylt::reflection::object_to_tuple( + std::declval())); + std::cout << type_string() << "\n"; + + test_variant4 t(1, "test", 3); + auto tp = iguana::detail::get_pb_members_tuple(t); + + std::string proto; + iguana::to_proto(proto); + std::cout << proto; + + static_assert(std::get<0>(tp).field_no == 1, "err"); + + CHECK(std::get<0>(tp).field_no == 1); + CHECK(std::get<1>(tp).field_no == 2); + CHECK(std::get<2>(tp).field_no == 3); + CHECK(std::get<3>(tp).field_no == 4); + CHECK(std::get<4>(tp).field_no == 5); + + std::string str; + iguana::to_pb(t, str); + + test_variant4 t1; + iguana::from_pb(t1, str); + std::cout << "\n"; + } { test_variant t(1, "test", 3); - auto tp = iguana::detail::get_pb_members_tuple(); + auto tp = iguana::detail::get_pb_members_tuple(t); CHECK(std::get<0>(tp).field_no == 1); CHECK(std::get<1>(tp).field_no == 2); @@ -64,7 +106,7 @@ TEST_CASE("test pb") { { test_variant1 t{"test", 2, 3}; - auto tp = iguana::detail::get_pb_members_tuple(); + auto tp = iguana::detail::get_pb_members_tuple(t); CHECK(std::get<0>(tp).field_no == 1); CHECK(std::get<1>(tp).field_no == 2); @@ -75,7 +117,7 @@ TEST_CASE("test pb") { { test_variant2 t{2, 3, "test"}; - auto tp = iguana::detail::get_pb_members_tuple(); + auto tp = iguana::detail::get_pb_members_tuple(t); CHECK(std::get<0>(tp).field_no == 1); CHECK(std::get<1>(tp).field_no == 2); @@ -86,7 +128,7 @@ TEST_CASE("test pb") { { test_variant3 t{2, "test", 3, "ok", 5, 6}; - auto tp = iguana::detail::get_pb_members_tuple(); + auto tp = iguana::detail::get_pb_members_tuple(t); CHECK(std::get<0>(tp).field_no == 1); CHECK(std::get<1>(tp).field_no == 2); From 75dc2297db301c19f6f22294d046c3ce6ab2dbb8 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Fri, 30 Aug 2024 21:20:50 +0800 Subject: [PATCH 26/44] xml writer --- iguana/xml_writer.hpp | 64 +++++++++++++++++++------------------------ test/test_cpp20.cpp | 7 +++++ 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/iguana/xml_writer.hpp b/iguana/xml_writer.hpp index f9d5009d..9e204f80 100644 --- a/iguana/xml_writer.hpp +++ b/iguana/xml_writer.hpp @@ -69,7 +69,7 @@ IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, std::string_view name); template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void render_xml_value(Stream &ss, T &&t, std::string_view name); template @@ -249,41 +249,33 @@ IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, } template , int>> + std::enable_if_t, int>> IGUANA_INLINE void render_xml_value(Stream &ss, T &&t, std::string_view name) { if constexpr (pretty) { ss.push_back('\n'); } - for_each(std::forward(t), - [&](const auto &v, auto i) IGUANA__INLINE_LAMBDA { - using M = decltype(iguana_reflect_type(std::forward(t))); - using value_type = underline_type_t; - constexpr auto Idx = decltype(i)::value; - constexpr auto Count = M::value(); - [[maybe_unused]] constexpr std::string_view tag_name = - std::string_view(get_name, Idx>().data(), - get_name, Idx>().size()); - static_assert(Idx < Count); - if constexpr (sequence_container_v) { - render_xml_value(ss, t.*v, tag_name); - } - else if constexpr (attr_v) { - render_xml_value(ss, t.*v, tag_name); - } - else if constexpr (cdata_v) { - if constexpr (pretty) { - ss.append(spaces + 1, '\t'); - ss.append("\n"); - } - else { - ss.append(""); - } - } - else { - render_head(ss, tag_name); - render_xml_value(ss, t.*v, tag_name); - } - }); + ylt::reflection::for_each(t, [&](auto &field, auto tag_name, auto index) { + using value_type = underline_type_t; + if constexpr (sequence_container_v) { + render_xml_value(ss, field, tag_name); + } + else if constexpr (attr_v) { + render_xml_value(ss, field, tag_name); + } + else if constexpr (cdata_v) { + if constexpr (pretty) { + ss.append(spaces + 1, '\t'); + ss.append("\n"); + } + else { + ss.append(""); + } + } + else { + render_head(ss, tag_name); + render_xml_value(ss, field, tag_name); + } + }); render_tail(ss, name); } @@ -291,17 +283,17 @@ template , int> = 0> IGUANA_INLINE void to_xml(T &&t, Stream &s) { using value_type = typename std::decay_t::value_type; - static_assert(refletable_v, "value_type must be refletable"); + static_assert(ylt_refletable_v, "value_type must be refletable"); constexpr std::string_view root_name = std::string_view( get_name().data(), get_name().size()); render_xml_value(s, std::forward(t), root_name); } template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void to_xml(T &&t, Stream &s) { - constexpr std::string_view root_name = std::string_view( - get_name>().data(), get_name>().size()); + constexpr std::string_view root_name = + type_string>(); render_head(s, root_name); render_xml_value(s, std::forward(t), root_name); } diff --git a/test/test_cpp20.cpp b/test/test_cpp20.cpp index 60618d92..c45c1295 100644 --- a/test/test_cpp20.cpp +++ b/test/test_cpp20.cpp @@ -185,6 +185,13 @@ TEST_CASE("test simple") { std::cout << pt1.x << "\n"; } +TEST_CASE("test xml") { + point_t t{1, 3}; + std::string xml; + iguana::to_xml(t, xml); + std::cout << xml << "\n"; +} + DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); } DOCTEST_MSVC_SUPPRESS_WARNING_POP \ No newline at end of file From e1348abbcfd71cf81853b4607eebd410dc2c5575 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Sat, 31 Aug 2024 15:01:45 +0800 Subject: [PATCH 27/44] pb reader part1 --- iguana/reflection.hpp | 54 ----------------------------------- iguana/xml_reader.hpp | 34 +++++++++++----------- iguana/xml_util.hpp | 53 ++++++++++++++++++++++++++++++++++ iguana/xml_writer.hpp | 4 +-- test/test_cpp20.cpp | 66 ++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 133 insertions(+), 78 deletions(-) diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index e22995a3..5d53f4bb 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -943,31 +943,6 @@ constexpr inline auto get_members() { std::tuple_size_v, __VA_ARGS__) #define IGUANA_UNIQUE_VARIABLE(str) MACRO_CONCAT(str, __COUNTER__) -template -struct iguana_required_struct; -#define REQUIRED_IMPL(STRUCT_NAME, N, ...) \ - template <> \ - struct iguana::iguana_required_struct { \ - inline static constexpr auto requied_arr() { \ - std::array arr_required = { \ - MARCO_EXPAND(MACRO_CONCAT(CON_STR, N)(__VA_ARGS__))}; \ - return arr_required; \ - } \ - }; - -#define REQUIRED(STRUCT_NAME, ...) \ - REQUIRED_IMPL(STRUCT_NAME, GET_ARG_COUNT(__VA_ARGS__), __VA_ARGS__) - -template -struct has_iguana_required_arr : std::false_type {}; - -template -struct has_iguana_required_arr< - T, std::void_t::requied_arr())>> - : std::true_type {}; - -template -constexpr bool has_iguana_required_arr_v = has_iguana_required_arr::value; inline std::string_view trim_sv(std::string_view str) { std::string_view whitespaces(" \t\f\v\n\r"); @@ -1049,30 +1024,6 @@ inline auto iguana_reflect_type(const T &t) { } } -template typename Condition, - typename Tuple, typename Owner> -constexpr int element_index_helper() { - if constexpr (index == std::tuple_size_v) { - return index; - } - else { - using type_v = decltype(std::declval().* - std::declval>()); - using item_type = std::decay_t; - - return Condition::value - ? index - : element_index_helper(); - } -} - -template