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/CMakeLists.txt b/CMakeLists.txt index ed7ad81b..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) @@ -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/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/benchmark/xml_bench.hpp b/benchmark/xml_bench.hpp index ca5352b2..77cc6cc2 100644 --- a/benchmark/xml_bench.hpp +++ b/benchmark/xml_bench.hpp @@ -9,7 +9,6 @@ #include #include -#include "iguana/reflection.hpp" #include "iguana/xml_reader.hpp" #include "iguana/xml_writer.hpp" @@ -19,18 +18,18 @@ struct package_t { std::optional version; std::vector file; }; -REFLECTION(package_t, version, file); +YLT_REFL(package_t, version, file); struct filelists_t { std::vector package; }; -REFLECTION(filelists_t, package); +YLT_REFL(filelists_t, package); // ************ struct for sample_rss.xml **************** struct skip_t { std::string_view skip; }; -REFLECTION(skip_t, skip); +YLT_REFL(skip_t, skip); struct item_t { std::string_view title; std::string_view link; @@ -49,17 +48,17 @@ struct item_t { std::optional media_content; std::string_view itunes_keywords; }; -REFLECTION(item_t, title, link, description, pubDate, enclosure, guid, - itunes_author, itunes_subtitle, itunes_summary, itunes_explicit, - itunes_duration, dc_creator, media_thumbnail, author, media_content, - itunes_keywords); +YLT_REFL(item_t, title, link, description, pubDate, enclosure, guid, + itunes_author, itunes_subtitle, itunes_summary, itunes_explicit, + itunes_duration, dc_creator, media_thumbnail, author, media_content, + itunes_keywords); struct image_t { std::string_view link; std::string_view url; std::string_view title; }; -REFLECTION(image_t, link, url, title); +YLT_REFL(image_t, link, url, title); struct channel_t { std::string_view title; @@ -82,15 +81,15 @@ struct channel_t { std::string_view media_rating; std::string_view media_description; }; -REFLECTION(channel_t, title, link, description, generator, docs, language, - pubDate, lastBuildDate, image, itunes_author, itunes_subtitle, - itunes_keywords, itunes_image, itunes_explicit, itunes_block, item, - media_credit, media_rating, media_description); +YLT_REFL(channel_t, title, link, description, generator, docs, language, + pubDate, lastBuildDate, image, itunes_author, itunes_subtitle, + itunes_keywords, itunes_image, itunes_explicit, itunes_block, item, + media_credit, media_rating, media_description); struct rss_t { channel_t channel; }; -REFLECTION(rss_t, channel); +YLT_REFL(rss_t, channel); // ************ struct for bench_num.xml **************** @@ -103,16 +102,16 @@ struct goods_t { std::string_view rating; std::string_view discount; }; -REFLECTION(goods_t, id, sales, inventory, weight, price, rating, discount); +YLT_REFL(goods_t, id, sales, inventory, weight, price, rating, discount); struct storeowner_t { std::string_view name; std::string_view telephone; }; -REFLECTION(storeowner_t, name, telephone); +YLT_REFL(storeowner_t, name, telephone); struct store_t { std::string_view name; std::string_view address; storeowner_t owner; std::vector goods; }; -REFLECTION(store_t, name, address, owner, goods); +YLT_REFL(store_t, name, address, owner, goods); diff --git a/benchmark/yaml_benchmark.hpp b/benchmark/yaml_benchmark.hpp index c913128f..2f30d4f4 100644 --- a/benchmark/yaml_benchmark.hpp +++ b/benchmark/yaml_benchmark.hpp @@ -1,9 +1,10 @@ +#include + #include "iguana/yaml_reader.hpp" #include "iguana/yaml_writer.hpp" -#include 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) { @@ -20,7 +21,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; @@ -42,31 +43,31 @@ std::string yaml_file_content(const std::string &filename) { return content; } -/*--------- REFLECTION appveyor.yml-------------*/ +/*--------- YLT_REFL appveyor.yml-------------*/ struct matrix_t { std::string_view compiler; std::string_view generator; std::string_view configuration; }; -REFLECTION(matrix_t, compiler, generator, configuration); +YLT_REFL(matrix_t, compiler, generator, configuration); struct environment_t { std::vector matrix; }; -REFLECTION(environment_t, matrix); +YLT_REFL(environment_t, matrix); struct ex_matrix_t { std::string_view fast_finish; }; -REFLECTION(ex_matrix_t, fast_finish); +YLT_REFL(ex_matrix_t, fast_finish); struct artifact_t { std::string_view path; std::string_view name; }; -REFLECTION(artifact_t, path, name); +YLT_REFL(artifact_t, path, name); struct skip_commit_t { std::vector files; }; -REFLECTION(skip_commit_t, files); +YLT_REFL(skip_commit_t, files); struct appveyor_t { std::string_view version; std::string_view image; @@ -78,33 +79,33 @@ struct appveyor_t { std::vector artifacts; skip_commit_t skip_commits; }; -REFLECTION(appveyor_t, version, image, environment, matrix, install, - build_script, test_script, artifacts, skip_commits); +YLT_REFL(appveyor_t, version, image, environment, matrix, install, build_script, + test_script, artifacts, skip_commits); -/*--------- REFLECTION travis.yml-------------*/ +/*--------- YLT_REFL travis.yml-------------*/ struct apt_t { std::vector sources; }; -REFLECTION(apt_t, sources); +YLT_REFL(apt_t, sources); struct addon_t { apt_t apt; }; -REFLECTION(addon_t, apt); +YLT_REFL(addon_t, apt); struct env_t { std::vector global; }; -REFLECTION(env_t, global); +YLT_REFL(env_t, global); struct in_env_t { std::string_view env; }; -REFLECTION(in_env_t, env); +YLT_REFL(in_env_t, env); struct mat_t { std::vector include; }; -REFLECTION(mat_t, include); +YLT_REFL(mat_t, include); struct travis_t { std::string_view sudo; @@ -117,5 +118,5 @@ struct travis_t { std::vector script; std::vector after_success; }; -REFLECTION(travis_t, sudo, dist, language, addons, env, matrix, install, script, - after_success); +YLT_REFL(travis_t, sudo, dist, language, addons, env, matrix, install, script, + after_success); 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/example/json_example.cpp b/example/json_example.cpp index 4d18fa37..a98fa058 100644 --- a/example/json_example.cpp +++ b/example/json_example.cpp @@ -14,28 +14,26 @@ inline char* to_chars_float(T value, char* buffer) { #include #include -//#include - namespace client { struct person { std::string name; 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 +80,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() { { @@ -114,6 +112,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); @@ -134,11 +134,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 +159,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/example/xml_example.cpp b/example/xml_example.cpp index d75f151f..397f2d20 100644 --- a/example/xml_example.cpp +++ b/example/xml_example.cpp @@ -1,5 +1,6 @@ #include #include +#include enum class enum_status { start, @@ -9,7 +10,7 @@ struct child_t { int key1; int key2; }; -REFLECTION(child_t, key1, key2); +YLT_REFL(child_t, key1, key2); struct some_type_t { std::vector price; std::optional description; @@ -21,8 +22,8 @@ struct some_type_t { std::string_view addr; enum_status status; }; -REFLECTION(some_type_t, price, description, child, hasdescription, c, d_v, name, - addr, status); +YLT_REFL(some_type_t, price, description, child, hasdescription, c, d_v, name, + addr, status); void some_type_example() { std::string str = R"( @@ -71,11 +72,11 @@ struct book_t { std::string title; std::string author; }; -REFLECTION(book_t, title, author); +YLT_REFL(book_t, title, author); struct library { iguana::xml_attr_t book; }; -REFLECTION(library, book); +YLT_REFL(library, book); void lib_example() { std::string str = R"( @@ -121,7 +122,7 @@ struct package_t { iguana::xml_attr_t> version; iguana::xml_attr_t changelog; }; -REFLECTION(package_t, version, changelog); +YLT_REFL(package_t, version, changelog); void package_example() { auto validator = [](iguana::xml_attr_t package) { assert(package.attr()["name"] == "apr-util-ldap"); @@ -164,7 +165,7 @@ struct derived_t : public base_t { int version; std::string tag; }; -REFLECTION(derived_t, id, name, version, tag); +YLT_REFL(derived_t, id, name, version, tag); void derived_object() { derived_t d{}; @@ -191,13 +192,13 @@ void derived_object() { struct description_t { iguana::xml_cdata_t cdata; }; -REFLECTION(description_t, cdata); +YLT_REFL(description_t, cdata); struct node_t { std::string title; description_t description; iguana::xml_cdata_t<> cdata; }; -REFLECTION(node_t, title, description, cdata); +YLT_REFL(node_t, title, description, cdata); void cdata_example() { std::string str = R"( @@ -232,18 +233,18 @@ struct city_t { iguana::xml_cdata_t<> cd; std::string name; }; -REFLECTION(city_t, area, cd, name); +YLT_REFL(city_t, area, cd, name); struct cities_t { std::vector city; }; -REFLECTION(cities_t, city); +YLT_REFL(cities_t, city); struct province { iguana::xml_attr_t area; iguana::xml_cdata_t<> cd; std::unique_ptr cities; std::string capital; }; -REFLECTION(province, area, cd, cities, capital); +YLT_REFL(province, area, cd, cities, capital); void province_example() { std::string_view str = R"( @@ -286,7 +287,7 @@ struct text_t { escape_attr_t ID; std::string DisplayName; }; -REFLECTION(text_t, ID, DisplayName); +YLT_REFL(text_t, ID, DisplayName); void escape_example() { { std::string str = R"( diff --git a/example/yaml_example.cpp b/example/yaml_example.cpp index 15c93129..5f375a12 100644 --- a/example/yaml_example.cpp +++ b/example/yaml_example.cpp @@ -1,5 +1,3 @@ -#include "iguana/yaml_reader.hpp" -#include "iguana/yaml_writer.hpp" #include #include #include @@ -8,6 +6,9 @@ #include #include +#include "iguana/yaml_reader.hpp" +#include "iguana/yaml_writer.hpp" + enum class enum_status { start, stop, @@ -23,8 +24,8 @@ struct some_type_t { std::string_view addr; enum_status status; }; -REFLECTION(some_type_t, price, description, child, hasdescription, c, d_v, name, - addr, status); +YLT_REFL(some_type_t, price, description, child, hasdescription, c, d_v, name, + addr, status); void some_type_example() { std::string str = R"( @@ -65,19 +66,19 @@ struct address_t { std::string_view state; std::string_view country; }; -REFLECTION(address_t, street, city, state, country); +YLT_REFL(address_t, street, city, state, country); struct contact_t { std::string_view type; std::string_view value; }; -REFLECTION(contact_t, type, value); +YLT_REFL(contact_t, type, value); struct person_t { std::string_view name; int age; address_t address; std::vector contacts; }; -REFLECTION(person_t, name, age, address, contacts); +YLT_REFL(person_t, name, age, address, contacts); std::ostream &operator<<(std::ostream &os, person_t p) { os << "name: " << p.name << "\tage: " << p.age << std::endl; @@ -126,7 +127,7 @@ struct map_person_t { map_type address; std::vector contacts; }; -REFLECTION(map_person_t, name, age, address, contacts); +YLT_REFL(map_person_t, name, age, address, contacts); void map_person_example() { std::string str = R"( name: John Doe @@ -161,17 +162,17 @@ struct product_t { float price; std::optional description; }; -REFLECTION(product_t, name, price, description); +YLT_REFL(product_t, name, price, description); struct store_t { std::string name; std::string_view location; std::vector products; }; -REFLECTION(store_t, name, location, products); +YLT_REFL(store_t, name, location, products); struct store_example_t { store_t store; }; -REFLECTION(store_example_t, store); +YLT_REFL(store_example_t, store); void store_example() { std::string str = R"( store: @@ -212,17 +213,17 @@ struct book_t { std::optional title; std::vector categories; }; -REFLECTION(book_t, title, categories); +YLT_REFL(book_t, title, categories); struct library_t { std::unique_ptr name; std::string location; std::vector> books; }; -REFLECTION(library_t, name, location, books); +YLT_REFL(library_t, name, location, books); struct library_example_t { std::vector libraries; }; -REFLECTION(library_example_t, libraries); +YLT_REFL(library_example_t, libraries); void library_example() { std::string str = R"( @@ -284,7 +285,7 @@ struct movie_t { std::optional year; std::vector actors; }; -REFLECTION(movie_t, title, year, actors); +YLT_REFL(movie_t, title, year, actors); void test_tuple_example() { std::string str = R"( # this is a movie diff --git a/iguana/common.hpp b/iguana/common.hpp new file mode 100644 index 00000000..8fcf601a --- /dev/null +++ b/iguana/common.hpp @@ -0,0 +1,281 @@ +#pragma once +#include + +#include "util.hpp" + +namespace iguana { +struct iguana_adl_t {}; + +namespace detail { +template +struct identity {}; + +struct field_info { + size_t offset; + std::string_view type_name; +}; + +struct base { + virtual void to_pb(std::string& str) const {} + virtual void from_pb(std::string_view str) {} + virtual void to_xml(std::string& str) const {} + virtual void from_xml(std::string_view str) {} + virtual void to_json(std::string& str) const {} + virtual void from_json(std::string_view str) {} + virtual void to_yaml(std::string& str) const {} + virtual void from_yaml(std::string_view str) {} + virtual std::vector get_fields_name() const { return {}; } + virtual std::any get_field_any(std::string_view name) const { return {}; } + virtual iguana::detail::field_info get_field_info( + std::string_view name) const { + return {}; + } + + template + T& get_field_value(std::string_view name) { + auto info = get_field_info(name); + check_field(name, info); + auto ptr = (((char*)this) + info.offset); + return *((T*)ptr); + } + + template + void set_field_value(std::string_view name, T val) { + auto info = get_field_info(name); + check_field(name, info); + + auto ptr = (((char*)this) + info.offset); + + static_assert(std::is_constructible_v, "can not assign"); + + *((FiledType*)ptr) = std::move(val); + } + virtual ~base() {} + + private: + template + void check_field(std::string_view name, const field_info& info) { + if (info.offset == 0) { + throw std::invalid_argument(std::string(name) + " field not exist "); + } + +#if defined(__clang__) || defined(_MSC_VER) || \ + (defined(__GNUC__) && __GNUC__ > 8) + if (info.type_name != iguana::type_string()) { + std::string str = "type is not match: can not assign "; + str.append(iguana::type_string()); + str.append(" to ").append(info.type_name); + + throw std::invalid_argument(str); + } +#endif + } +}; + +inline std::unordered_map()>> + g_pb_map; + +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 +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; + +// owner_type: parant type, value_type: member value type, SubType: subtype from +// variant +template +struct pb_field_t { + using owner_type = Owner; + using value_type = Value; + using sub_type = ElementType; + + // constexpr pb_field_t() = default; + auto& value(owner_type& value) const { + auto member_ptr = (value_type*)((char*)(&value) + offset); + return *member_ptr; + } + // auto const& value(owner_type const& value) const { + // auto member_ptr = + // (value_type *)((char *)(&value) + offset); + // return *member_ptr; + // } + + size_t offset; + std::string_view field_name; + + inline static constexpr uint32_t field_no = FieldNo; +}; + +template +constexpr inline auto get_field_no_impl(Array& arr, size_t& index) { + arr[I] = index; + 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< + I, ylt::reflection::remove_cvref_t>>( + arr, index), + ...); + return arr; +} + +template +constexpr inline auto build_pb_variant_fields(size_t offset, + std::string_view name, + std::index_sequence) { + return std::tuple( + pb_field_t>{offset, name}...); +} + +template +constexpr inline auto build_pb_fields_impl(size_t offset, + std::string_view name) { + using value_type = ylt::reflection::remove_cvref_t; + using U = std::remove_reference_t; + + if constexpr (is_variant::value) { + constexpr uint32_t variant_size = std::variant_size_v; + return build_pb_variant_fields( + offset, name, std::make_index_sequence{}); + } + else { + return std::tuple(pb_field_t{offset, name}); + } +} + +template +inline auto build_pb_fields(const Array& offset_arr, + std::index_sequence) { + constexpr auto arr = ylt::reflection::get_member_names(); + constexpr std::array indexs = + get_field_no(std::make_index_sequence{}); + return std::tuple_cat( + 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) { + static auto& offset_arr = ylt::reflection::internal::get_member_offset_arr( + ylt::reflection::internal::wrapper::value); + using Tuple = decltype(ylt::reflection::object_to_tuple(std::declval())); + return build_pb_fields( + offset_arr, 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"); + } +} + +template +inline auto get_members(T&& t) { + if constexpr (ylt_refletable_v || is_custom_reflection_v) { + 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(); + return get_members_impl(tp, + std::make_index_sequence{}); + } + else { + static_assert(!sizeof(T), "expected reflection or custom reflection"); + } +} +} // namespace detail + +template +inline bool register_type() { +#if defined(__clang__) || defined(_MSC_VER) || \ + (defined(__GNUC__) && __GNUC__ > 8) + if constexpr (std::is_base_of_v) { + auto it = detail::g_pb_map.emplace(type_string(), [] { + return std::make_shared(); + }); + return it.second; + } + else { + return true; + } +#else + return true; +#endif +} + +template +IGUANA_INLINE constexpr size_t member_offset(T* t, U T::*member) { + return (char*)&(t->*member) - (char*)t; +} + +template +IGUANA_INLINE auto build_pb_field(std::string_view name) { + using owner = + typename ylt::reflection::member_traits::owner_type; + using value_type = + typename ylt::reflection::member_traits::value_type; + size_t offset = member_offset((owner*)nullptr, ptr); + return iguana::detail::pb_field_t{offset, name}; +} +} // namespace iguana \ 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/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/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/dynamic.hpp b/iguana/dynamic.hpp index 4b479b0c..47cf2015 100644 --- a/iguana/dynamic.hpp +++ b/iguana/dynamic.hpp @@ -1,14 +1,9 @@ #pragma once -#include "reflection.hpp" +#include "common.hpp" namespace iguana { using base = detail::base; -template -IGUANA_INLINE constexpr size_t member_offset(T* t, U T::*member) { - return (char*)&(t->*member) - (char*)t; -} - constexpr inline uint8_t ENABLE_JSON = 0x01; constexpr inline uint8_t ENABLE_YAML = 0x02; constexpr inline uint8_t ENABLE_XML = 0x04; @@ -17,6 +12,7 @@ constexpr inline uint8_t ENABLE_ALL = 0x0F; template struct base_impl : public base { + base_impl() { [[maybe_unused]] static bool r = register_type(); } void to_pb(std::string& str) const override { if constexpr ((ENABLE_FLAG & ENABLE_PB) != 0) { to_pb_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); @@ -91,7 +87,8 @@ struct base_impl : public base { iguana::detail::field_info get_field_info( std::string_view name) const override { - static constexpr auto map = iguana::get_members(); + static auto map = + detail::get_members(ylt::reflection::internal::wrapper::value); iguana::detail::field_info info{}; for (auto const& [no, field] : map) { if (info.offset > 0) { @@ -100,7 +97,7 @@ struct base_impl : public base { std::visit( [&](auto const& val) { if (val.field_name == name) { - info.offset = member_offset((T*)this, val.member_ptr); + info.offset = val.offset; using value_type = typename std::remove_reference_t::value_type; #if defined(__clang__) || defined(_MSC_VER) || \ @@ -116,7 +113,8 @@ struct base_impl : public base { } std::vector get_fields_name() const override { - static constexpr auto map = iguana::get_members(); + static auto map = + detail::get_members(ylt::reflection::internal::wrapper::value); std::vector vec; @@ -135,7 +133,8 @@ struct base_impl : public base { } std::any get_field_any(std::string_view name) const override { - static constexpr auto map = iguana::get_members(); + static auto map = + detail::get_members(ylt::reflection::internal::wrapper::value); std::any result; for (auto const& [no, field] : map) { @@ -147,8 +146,7 @@ struct base_impl : public base { if (val.field_name == name) { using value_type = typename std::remove_reference_t::value_type; - auto const offset = member_offset((T*)this, val.member_ptr); - auto ptr = (char*)this + offset; + auto ptr = (char*)this + val.offset; result = *((value_type*)ptr); } }, diff --git a/iguana/json_reader.hpp b/iguana/json_reader.hpp index d433f017..765815fe 100644 --- a/iguana/json_reader.hpp +++ b/iguana/json_reader.hpp @@ -4,9 +4,18 @@ #include "json_util.hpp" namespace iguana { -template , int> = 0> +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> = 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); } @@ -86,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) { @@ -404,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); } @@ -542,7 +554,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 +565,80 @@ IGUANA_INLINE void from_json(T &value, It &&it, It &&end) { ++it; return; } - std::string_view key = detail::get_key(it, end); + using U = ylt::reflection::remove_cvref_t; + 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); + bool parse_done = false; + ylt::reflection::for_each( + value, [&](auto &field, auto name, auto index) IGUANA__INLINE_LAMBDA { + if (parse_done || (key != name)) + IGUANA_UNLIKELY { return; } + skip_ws(it, end); + match<':'>(it, end); + { + using namespace detail; + from_json_impl(field, 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; } - - 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); - 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) { + while (it != end) { + static auto frozen_map = ylt::reflection::get_variant_map(); + 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 offset) IGUANA__INLINE_LAMBDA { using namespace detail; - from_json_impl(value.*member_ptr, it, end); - } - else { - static_assert(!sizeof(V), "type not supported"); - } - }, - member_it->second); - } - else - IGUANA_UNLIKELY { + using value_type = typename decltype(offset)::type; + auto member_ptr = + (value_type *)((char *)(&value) + offset.value); + from_json_impl(*member_ptr, it, end); + }, + 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); @@ -643,35 +655,15 @@ IGUANA_INLINE void from_json(T &value, It &&it, It &&end, } } -template , int> = 0> +template , int>> 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>> +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> = 0> IGUANA_INLINE void to_json(T &&t, Stream &s); namespace detail { template @@ -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> @@ -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('"'); }; @@ -244,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(']'); } @@ -267,28 +266,27 @@ 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(','); } - }); + using U = ylt::reflection::remove_cvref_t; + constexpr auto Count = ylt::reflection::members_count_v; + 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('}'); } 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/pb_reader.hpp b/iguana/pb_reader.hpp index 83d2425d..a91a6969 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); @@ -191,14 +191,16 @@ 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(t); constexpr size_t SIZE = std::tuple_size_v>; bool parse_done = false; + auto ptr = &t; detail::for_each_n( - [&](auto i) IGUANA__INLINE_LAMBDA { - constexpr auto val = std::get(tp); + [&, ptr](auto i) IGUANA__INLINE_LAMBDA { + auto val = std::get(tp); using sub_type = typename std::decay_t::sub_type; using value_type = typename std::decay_t::value_type; + constexpr bool is_variant_v = variant_v; // sub_type is the element type when value_type is the variant type; // otherwise, they are the same. if (parse_done || field_number != val.field_no) { @@ -207,11 +209,13 @@ IGUANA_INLINE void from_pb(T& t, std::string_view pb_str) { pb_str = pb_str.substr(pos); if (wire_type != detail::get_wire_type()) IGUANA_UNLIKELY { throw std::runtime_error("unmatched wire_type"); } - if constexpr (variant_v) { - detail::parse_oneof(val.value(t), val, pb_str); + + auto member_ptr = (value_type*)((char*)(ptr) + val.offset); + if constexpr (is_variant_v) { + detail::parse_oneof(*member_ptr, val, pb_str); } else { - detail::from_pb_impl(val.value(t), pb_str, val.field_no); + detail::from_pb_impl(*member_ptr, pb_str, val.field_no); } if (pb_str.empty()) { parse_done = true; @@ -227,7 +231,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(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 27bc9a89..bd8d5faa 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -13,8 +13,8 @@ #include #include +#include "common.hpp" #include "detail/pb_type.hpp" -#include "reflection.hpp" #include "util.hpp" namespace iguana { @@ -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; } @@ -439,9 +439,9 @@ IGUANA_INLINE size_t pb_oneof_size(Type&& t, Arr& size_arr) { 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) { + if constexpr (ylt_refletable_v) { size_t len = 0; - static constexpr auto tuple = get_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) { @@ -453,13 +453,13 @@ IGUANA_INLINE size_t pb_key_value_size(Type&& t, Arr& size_arr) { 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; - auto const& val = value.value(t); + using sub_type = typename field_type::sub_type; + auto& val = value.value(t); if constexpr (variant_v) { constexpr auto offset = - get_variant_index - 1>(); + get_variant_index - 1>(); if constexpr (offset == 0) { len += pb_oneof_size(val, size_arr); } @@ -541,7 +541,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; } diff --git a/iguana/pb_writer.hpp b/iguana/pb_writer.hpp index 219650fb..b40fbf72 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,21 +109,21 @@ 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(std::forward(t)); 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; + using sub_type = typename field_type::sub_type; if constexpr (variant_v) { constexpr auto offset = - get_variant_index - 1>(); + get_variant_index - 1>(); if constexpr (offset == 0) { to_pb_oneof(val, it, sz_ptr); } @@ -297,10 +297,11 @@ 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 T t; + static auto tuple = get_pb_members_tuple(t); constexpr size_t SIZE = std::tuple_size_v>; for_each_n( @@ -308,10 +309,11 @@ 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) { + using sub_type = typename field_type::sub_type; + if constexpr (ylt_refletable_v) { constexpr auto str_type = get_type_string(); build_proto_field( out, str_type, @@ -322,7 +324,6 @@ IGUANA_INLINE void to_proto_impl( } else if constexpr (variant_v) { constexpr size_t var_size = std::variant_size_v; - using sub_type = typename field_type::sub_type; constexpr auto offset = get_variant_index(); @@ -340,7 +341,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 +364,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 +390,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); } @@ -449,7 +450,8 @@ 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); diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp deleted file mode 100644 index 474e27fa..00000000 --- a/iguana/reflection.hpp +++ /dev/null @@ -1,1349 +0,0 @@ -// -// Created by Qiyu on 17-6-5. -// - -#ifndef IGUANA_REFLECTION_HPP -#define IGUANA_REFLECTION_HPP -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "detail/string_stream.hpp" -#include "detail/traits.hpp" -#include "field_reflection.hpp" -#include "frozen/string.h" -#include "frozen/unordered_map.h" - -namespace iguana::detail { -/******************************************/ -/* arg list expand macro, now support 120 args */ -#define MAKE_ARG_LIST_1(op, arg, ...) op(arg) -#define MAKE_ARG_LIST_2(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_1(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_3(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_2(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_4(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_3(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_5(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_4(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_6(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_5(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_7(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_6(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_8(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_7(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_9(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_8(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_10(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_9(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_11(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_10(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_12(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_11(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_13(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_12(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_14(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_13(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_15(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_14(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_16(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_15(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_17(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_16(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_18(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_17(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_19(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_18(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_20(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_19(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_21(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_20(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_22(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_21(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_23(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_22(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_24(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_23(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_25(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_24(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_26(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_25(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_27(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_26(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_28(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_27(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_29(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_28(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_30(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_29(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_31(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_30(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_32(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_31(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_33(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_32(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_34(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_33(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_35(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_34(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_36(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_35(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_37(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_36(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_38(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_37(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_39(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_38(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_40(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_39(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_41(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_40(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_42(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_41(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_43(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_42(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_44(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_43(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_45(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_44(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_46(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_45(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_47(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_46(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_48(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_47(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_49(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_48(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_50(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_49(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_51(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_50(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_52(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_51(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_53(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_52(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_54(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_53(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_55(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_54(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_56(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_55(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_57(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_56(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_58(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_57(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_59(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_58(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_60(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_59(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_61(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_60(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_62(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_61(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_63(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_62(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_64(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_63(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_65(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_64(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_66(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_65(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_67(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_66(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_68(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_67(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_69(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_68(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_70(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_69(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_71(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_70(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_72(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_71(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_73(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_72(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_74(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_73(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_75(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_74(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_76(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_75(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_77(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_76(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_78(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_77(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_79(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_78(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_80(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_79(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_81(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_80(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_82(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_81(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_83(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_82(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_84(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_83(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_85(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_84(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_86(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_85(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_87(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_86(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_88(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_87(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_89(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_88(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_90(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_89(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_91(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_90(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_92(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_91(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_93(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_92(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_94(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_93(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_95(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_94(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_96(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_95(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_97(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_96(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_98(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_97(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_99(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_98(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_100(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_99(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_101(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_100(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_102(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_101(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_103(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_102(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_104(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_103(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_105(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_104(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_106(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_105(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_107(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_106(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_108(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_107(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_109(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_108(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_110(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_109(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_111(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_110(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_112(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_111(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_113(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_112(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_114(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_113(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_115(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_114(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_116(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_115(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_117(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_116(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_118(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_117(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_119(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_118(op, __VA_ARGS__)) -#define MAKE_ARG_LIST_120(op, arg, ...) \ - op(arg), MARCO_EXPAND(MAKE_ARG_LIST_119(op, __VA_ARGS__)) - -#define ADD_VIEW(str) std::string_view(#str, sizeof(#str) - 1) - -#define SEPERATOR , -#define CON_STR_1(element, ...) ADD_VIEW(element) -#define CON_STR_2(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_1(__VA_ARGS__)) -#define CON_STR_3(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_2(__VA_ARGS__)) -#define CON_STR_4(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_3(__VA_ARGS__)) -#define CON_STR_5(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_4(__VA_ARGS__)) -#define CON_STR_6(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_5(__VA_ARGS__)) -#define CON_STR_7(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_6(__VA_ARGS__)) -#define CON_STR_8(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_7(__VA_ARGS__)) -#define CON_STR_9(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_8(__VA_ARGS__)) -#define CON_STR_10(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_9(__VA_ARGS__)) -#define CON_STR_11(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_10(__VA_ARGS__)) -#define CON_STR_12(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_11(__VA_ARGS__)) -#define CON_STR_13(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_12(__VA_ARGS__)) -#define CON_STR_14(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_13(__VA_ARGS__)) -#define CON_STR_15(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_14(__VA_ARGS__)) -#define CON_STR_16(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_15(__VA_ARGS__)) -#define CON_STR_17(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_16(__VA_ARGS__)) -#define CON_STR_18(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_17(__VA_ARGS__)) -#define CON_STR_19(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_18(__VA_ARGS__)) -#define CON_STR_20(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_19(__VA_ARGS__)) -#define CON_STR_21(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_20(__VA_ARGS__)) -#define CON_STR_22(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_21(__VA_ARGS__)) -#define CON_STR_23(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_22(__VA_ARGS__)) -#define CON_STR_24(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_23(__VA_ARGS__)) -#define CON_STR_25(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_24(__VA_ARGS__)) -#define CON_STR_26(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_25(__VA_ARGS__)) -#define CON_STR_27(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_26(__VA_ARGS__)) -#define CON_STR_28(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_27(__VA_ARGS__)) -#define CON_STR_29(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_28(__VA_ARGS__)) -#define CON_STR_30(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_29(__VA_ARGS__)) -#define CON_STR_31(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_30(__VA_ARGS__)) -#define CON_STR_32(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_31(__VA_ARGS__)) -#define CON_STR_33(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_32(__VA_ARGS__)) -#define CON_STR_34(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_33(__VA_ARGS__)) -#define CON_STR_35(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_34(__VA_ARGS__)) -#define CON_STR_36(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_35(__VA_ARGS__)) -#define CON_STR_37(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_36(__VA_ARGS__)) -#define CON_STR_38(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_37(__VA_ARGS__)) -#define CON_STR_39(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_38(__VA_ARGS__)) -#define CON_STR_40(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_39(__VA_ARGS__)) -#define CON_STR_41(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_40(__VA_ARGS__)) -#define CON_STR_42(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_41(__VA_ARGS__)) -#define CON_STR_43(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_42(__VA_ARGS__)) -#define CON_STR_44(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_43(__VA_ARGS__)) -#define CON_STR_45(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_44(__VA_ARGS__)) -#define CON_STR_46(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_45(__VA_ARGS__)) -#define CON_STR_47(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_46(__VA_ARGS__)) -#define CON_STR_48(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_47(__VA_ARGS__)) -#define CON_STR_49(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_48(__VA_ARGS__)) -#define CON_STR_50(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_49(__VA_ARGS__)) -#define CON_STR_51(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_50(__VA_ARGS__)) -#define CON_STR_52(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_51(__VA_ARGS__)) -#define CON_STR_53(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_52(__VA_ARGS__)) -#define CON_STR_54(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_53(__VA_ARGS__)) -#define CON_STR_55(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_54(__VA_ARGS__)) -#define CON_STR_56(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_55(__VA_ARGS__)) -#define CON_STR_57(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_56(__VA_ARGS__)) -#define CON_STR_58(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_57(__VA_ARGS__)) -#define CON_STR_59(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_58(__VA_ARGS__)) -#define CON_STR_60(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_59(__VA_ARGS__)) -#define CON_STR_61(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_60(__VA_ARGS__)) -#define CON_STR_62(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_61(__VA_ARGS__)) -#define CON_STR_63(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_62(__VA_ARGS__)) -#define CON_STR_64(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_63(__VA_ARGS__)) -#define CON_STR_65(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_64(__VA_ARGS__)) -#define CON_STR_66(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_65(__VA_ARGS__)) -#define CON_STR_67(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_66(__VA_ARGS__)) -#define CON_STR_68(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_67(__VA_ARGS__)) -#define CON_STR_69(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_68(__VA_ARGS__)) -#define CON_STR_70(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_69(__VA_ARGS__)) -#define CON_STR_71(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_70(__VA_ARGS__)) -#define CON_STR_72(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_71(__VA_ARGS__)) -#define CON_STR_73(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_72(__VA_ARGS__)) -#define CON_STR_74(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_73(__VA_ARGS__)) -#define CON_STR_75(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_74(__VA_ARGS__)) -#define CON_STR_76(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_75(__VA_ARGS__)) -#define CON_STR_77(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_76(__VA_ARGS__)) -#define CON_STR_78(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_77(__VA_ARGS__)) -#define CON_STR_79(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_78(__VA_ARGS__)) -#define CON_STR_80(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_79(__VA_ARGS__)) -#define CON_STR_81(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_80(__VA_ARGS__)) -#define CON_STR_82(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_81(__VA_ARGS__)) -#define CON_STR_83(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_82(__VA_ARGS__)) -#define CON_STR_84(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_83(__VA_ARGS__)) -#define CON_STR_85(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_84(__VA_ARGS__)) -#define CON_STR_86(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_85(__VA_ARGS__)) -#define CON_STR_87(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_86(__VA_ARGS__)) -#define CON_STR_88(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_87(__VA_ARGS__)) -#define CON_STR_89(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_88(__VA_ARGS__)) -#define CON_STR_90(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_89(__VA_ARGS__)) -#define CON_STR_91(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_90(__VA_ARGS__)) -#define CON_STR_92(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_91(__VA_ARGS__)) -#define CON_STR_93(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_92(__VA_ARGS__)) -#define CON_STR_94(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_93(__VA_ARGS__)) -#define CON_STR_95(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_94(__VA_ARGS__)) -#define CON_STR_96(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_95(__VA_ARGS__)) -#define CON_STR_97(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_96(__VA_ARGS__)) -#define CON_STR_98(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_97(__VA_ARGS__)) -#define CON_STR_99(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_98(__VA_ARGS__)) -#define CON_STR_100(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_99(__VA_ARGS__)) -#define CON_STR_101(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_100(__VA_ARGS__)) -#define CON_STR_102(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_101(__VA_ARGS__)) -#define CON_STR_103(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_102(__VA_ARGS__)) -#define CON_STR_104(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_103(__VA_ARGS__)) -#define CON_STR_105(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_104(__VA_ARGS__)) -#define CON_STR_106(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_105(__VA_ARGS__)) -#define CON_STR_107(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_106(__VA_ARGS__)) -#define CON_STR_108(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_107(__VA_ARGS__)) -#define CON_STR_109(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_108(__VA_ARGS__)) -#define CON_STR_110(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_109(__VA_ARGS__)) -#define CON_STR_111(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_110(__VA_ARGS__)) -#define CON_STR_112(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_111(__VA_ARGS__)) -#define CON_STR_113(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_112(__VA_ARGS__)) -#define CON_STR_114(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_113(__VA_ARGS__)) -#define CON_STR_115(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_114(__VA_ARGS__)) -#define CON_STR_116(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_115(__VA_ARGS__)) -#define CON_STR_117(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_116(__VA_ARGS__)) -#define CON_STR_118(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_117(__VA_ARGS__)) -#define CON_STR_119(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_118(__VA_ARGS__)) -#define CON_STR_120(element, ...) \ - ADD_VIEW(element) SEPERATOR MARCO_EXPAND(CON_STR_119(__VA_ARGS__)) -#define RSEQ_N() \ - 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 ARG_N(_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, N, ...) \ - N - -#define MARCO_EXPAND(...) __VA_ARGS__ -#define APPLY_VARIADIC_MACRO(macro, ...) MARCO_EXPAND(macro(__VA_ARGS__)) - -#define ADD_REFERENCE(t) std::reference_wrapper(t) -#define ADD_REFERENCE_CONST(t) \ - std::reference_wrapper>(t) -#define FIELD(t) t -#define MAKE_NAMES(...) #__VA_ARGS__, - -// note use MACRO_CONCAT like A##_##B direct may cause marco expand error -#define MACRO_CONCAT(A, B) MACRO_CONCAT1(A, B) -#define MACRO_CONCAT1(A, B) A##_##B - -#define MAKE_ARG_LIST(N, op, arg, ...) \ - MACRO_CONCAT(MAKE_ARG_LIST, N)(op, arg, __VA_ARGS__) - -#define GET_ARG_COUNT_INNER(...) MARCO_EXPAND(ARG_N(__VA_ARGS__)) -#define GET_ARG_COUNT(...) GET_ARG_COUNT_INNER(__VA_ARGS__, RSEQ_N()) - -#define MAKE_STR_LIST(...) \ - MACRO_CONCAT(CON_STR, GET_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__) - -template -struct identity {}; - -struct field_info { - size_t offset; - std::string_view type_name; -}; - -struct base { - virtual void to_pb(std::string &str) const {} - virtual void from_pb(std::string_view str) {} - virtual void to_xml(std::string &str) const {} - virtual void from_xml(std::string_view str) {} - virtual void to_json(std::string &str) const {} - virtual void from_json(std::string_view str) {} - virtual void to_yaml(std::string &str) const {} - virtual void from_yaml(std::string_view str) {} - virtual std::vector get_fields_name() const { return {}; } - virtual std::any get_field_any(std::string_view name) const { return {}; } - virtual iguana::detail::field_info get_field_info( - std::string_view name) const { - return {}; - } - - template - T &get_field_value(std::string_view name) { - auto info = get_field_info(name); - check_field(name, info); - auto ptr = (((char *)this) + info.offset); - return *((T *)ptr); - } - - template - void set_field_value(std::string_view name, T val) { - auto info = get_field_info(name); - check_field(name, info); - - auto ptr = (((char *)this) + info.offset); - - static_assert(std::is_constructible_v, "can not assign"); - - *((FiledType *)ptr) = std::move(val); - } - virtual ~base() {} - - private: - template - void check_field(std::string_view name, const field_info &info) { - if (info.offset == 0) { - throw std::invalid_argument(std::string(name) + " field not exist "); - } - -#if defined(__clang__) || defined(_MSC_VER) || \ - (defined(__GNUC__) && __GNUC__ > 8) - if (info.type_name != iguana::type_string()) { - std::string str = "type is not match: can not assign "; - str.append(iguana::type_string()); - str.append(" to ").append(info.type_name); - - throw std::invalid_argument(str); - } -#endif - } -}; - -inline std::unordered_map()>> - g_pb_map; - -template -inline bool register_type() { -#if defined(__clang__) || defined(_MSC_VER) || \ - (defined(__GNUC__) && __GNUC__ > 8) - if constexpr (std::is_base_of_v) { - auto it = g_pb_map.emplace(type_string(), [] { - return std::make_shared(); - }); - return it.second; - } - else { - return true; - } -#else - return true; -#endif -} - -#define MAKE_META_DATA_IMPL(STRUCT_NAME, ...) \ - static inline bool IGUANA_UNIQUE_VARIABLE(reg_var) = \ - iguana::detail::register_type(); \ - [[maybe_unused]] inline static auto iguana_reflect_members( \ - const iguana::detail::identity &) { \ - struct reflect_members { \ - constexpr decltype(auto) static apply_impl() { \ - return std::make_tuple(__VA_ARGS__); \ - } \ - using size_type = \ - std::integral_constant; \ - constexpr static std::string_view name() { return name_##STRUCT_NAME; } \ - constexpr static std::string_view struct_name() { \ - return std::string_view(#STRUCT_NAME, sizeof(#STRUCT_NAME) - 1); \ - } \ - constexpr static std::string_view fields() { \ - return fields_##STRUCT_NAME; \ - } \ - constexpr static size_t value() { return size_type::value; } \ - constexpr static std::array arr() { \ - return arr_##STRUCT_NAME; \ - } \ - }; \ - return reflect_members{}; \ - } - -#define MAKE_META_DATA(STRUCT_NAME, TABLE_NAME, N, ...) \ - static constexpr inline std::array arr_##STRUCT_NAME = { \ - MARCO_EXPAND(MACRO_CONCAT(CON_STR, N)(__VA_ARGS__))}; \ - static constexpr inline std::string_view fields_##STRUCT_NAME = { \ - MAKE_NAMES(__VA_ARGS__)}; \ - static constexpr inline std::string_view name_##STRUCT_NAME = TABLE_NAME; \ - MAKE_META_DATA_IMPL(STRUCT_NAME, \ - MAKE_ARG_LIST(N, &STRUCT_NAME::FIELD, __VA_ARGS__)) - -#define REFLECTION_ALIAS_IMPL(STRUCT_NAME, ALIAS, N, ...) \ - MAKE_META_DATA_IMPL_ALIAS(STRUCT_NAME, ALIAS, __VA_ARGS__) - -#define FLDALIAS(a, b) \ - std::pair { a, b } - -template -constexpr auto get_mem_ptr_tp(Args... pair) { - return std::make_tuple(std::get<0>(pair)...); -} - -template -constexpr std::array get_alias_arr(Args... pairs) { - return std::array{ - frozen::string(std::get<1>(pairs))...}; -} - -#define MAKE_META_DATA_IMPL_ALIAS(STRUCT_NAME, ALIAS, ...) \ - [[maybe_unused]] inline static auto iguana_reflect_members( \ - const iguana::detail::identity &) { \ - struct reflect_members { \ - constexpr decltype(auto) static apply_impl() { \ - return iguana::detail::get_mem_ptr_tp(__VA_ARGS__); \ - } \ - using size_type = std::integral_constant< \ - size_t, std::tuple_size_v>; \ - constexpr static std::string_view name() { return ALIAS; } \ - constexpr static std::string_view struct_name() { \ - return std::string_view(#STRUCT_NAME, sizeof(#STRUCT_NAME) - 1); \ - } \ - constexpr static size_t value() { return size_type::value; } \ - constexpr static std::array arr() { \ - return iguana::detail::get_alias_arr(__VA_ARGS__); \ - } \ - }; \ - return reflect_members{}; \ - } - -#define MAKE_META_DATA_IMPL_EMPTY(STRUCT_NAME) \ - inline auto iguana_reflect_members( \ - const iguana::detail::identity &) { \ - struct reflect_members { \ - constexpr decltype(auto) static apply_impl() { \ - return std::make_tuple(); \ - } \ - using size_type = std::integral_constant; \ - constexpr static std::string_view name() { \ - return std::string_view(#STRUCT_NAME, sizeof(#STRUCT_NAME) - 1); \ - } \ - constexpr static size_t value() { return size_type::value; } \ - constexpr static std::array arr() { \ - return arr_##STRUCT_NAME; \ - } \ - }; \ - return reflect_members{}; \ - } - -#define MAKE_META_DATA_EMPTY(STRUCT_NAME) \ - constexpr inline std::array arr_##STRUCT_NAME = {}; \ - MAKE_META_DATA_IMPL_EMPTY(STRUCT_NAME) - -template -inline auto get_value_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_iguana_struct_map_impl( - const std::array &arr, T &&t, - std::index_sequence) { - using ValueType = decltype(get_value_type(t)); - return frozen::unordered_map{ - {filter_str(arr[Is]), - ValueType{std::in_place_index, std::get(t)}}...}; -} -} // namespace iguana::detail - -namespace iguana { -#define REFLECTION_WITH_NAME(STRUCT_NAME, TABLE_NAME, ...) \ - MAKE_META_DATA(STRUCT_NAME, TABLE_NAME, GET_ARG_COUNT(__VA_ARGS__), \ - __VA_ARGS__) - -struct iguana_adl_t {}; - -template -inline auto iguana_reflect_type(const T &t); - -inline std::unordered_map< - std::string_view, - std::vector>> - g_iguana_custom_map; -template -inline constexpr auto get_iguana_struct_map() { - using reflect_members = decltype(iguana_reflect_type(std::declval())); - if constexpr (reflect_members::value() == 0) { - return std::array{}; - } - else { - return detail::get_iguana_struct_map_impl( - reflect_members::arr(), reflect_members::apply_impl(), - std::make_index_sequence{}); - } -} - -template ::value_type> -struct field_t { - using member_type = T; - using owner_type = typename member_traits::owner_type; - using value_type = typename member_traits::value_type; - using sub_type = ElementType; - constexpr field_t() = default; - constexpr field_t(T member, uint32_t number, frozen::string name = "") - : member_ptr(member), field_name(name), field_no(number) {} - - T member_ptr; - frozen::string field_name; - uint32_t field_no; - - auto &value(owner_type &value) const { return value.*member_ptr; } - auto const &value(owner_type const &value) const { return value.*member_ptr; } -}; - -template -struct field_type_t; - -template -struct field_type_t> { - using value_type = std::variant; -}; - -template -struct is_custom_reflection : std::false_type {}; - -template -struct is_custom_reflection< - T, std::void_t()))>> - : std::true_type {}; - -template -struct is_reflection : std::false_type {}; - -template -inline constexpr bool is_reflection_v = is_reflection::value; - -template -inline constexpr bool is_custom_reflection_v = is_custom_reflection::value; - -template -constexpr inline auto build_variant_fields(T t, S &s, uint32_t base_idx, - std::index_sequence) { - 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_fields(T t, S &s, uint32_t &index) { - using value_type = typename member_traits::value_type; - if constexpr (is_variant::value) { - constexpr uint32_t Size = std::variant_size_v; - index += (Size - 1); - return build_variant_fields(t, s, I + 1, std::make_index_sequence{}); - } - else { - uint32_t field_no = (I == index) ? (I + 1) : (2 + index); - index++; - return std::tuple(field_t{t, field_no, s}); - } -} - -template -constexpr inline auto get_members_tuple_impl(T &&tp, U &&arr, - std::index_sequence &&) { - uint32_t index = 0; - return std::tuple_cat(build_fields(std::get(tp), arr[I], index)...); -} - -template -constexpr inline auto get_members_tuple() { - if constexpr (is_reflection::value) { - using reflect_members = decltype(iguana_reflect_type(std::declval())); - using Tuple = decltype(reflect_members::apply_impl()); - constexpr size_t Size = std::tuple_size_v; - return get_members_tuple_impl(reflect_members::apply_impl(), - reflect_members::arr(), - std::make_index_sequence{}); - } - else if constexpr (is_custom_reflection_v) { - using U = std::remove_const_t>; - return get_members_impl((U *)nullptr); - } - else { - static_assert(!sizeof(T), "expected reflection or custom reflection"); - } -} - -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 -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 inline auto get_members() { - if constexpr (is_reflection_v || is_custom_reflection_v) { - constexpr auto tp = get_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"); - } -} - -#define REFLECTION(STRUCT_NAME, ...) \ - MAKE_META_DATA(STRUCT_NAME, #STRUCT_NAME, GET_ARG_COUNT(__VA_ARGS__), \ - __VA_ARGS__) - -#define REFLECTION_EMPTY(STRUCT_NAME) MAKE_META_DATA_EMPTY(STRUCT_NAME) - -#define REFLECTION_ALIAS(STRUCT_NAME, ALIAS, ...) \ - REFLECTION_ALIAS_IMPL( \ - STRUCT_NAME, ALIAS, \ - 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"); - auto first = str.find_first_not_of(whitespaces); - auto last = str.find_last_not_of(whitespaces); - if (first == std::string_view::npos || last == std::string_view::npos) - return std::string_view(); - return str.substr(first, last - first + 1); -} - -inline int add_custom_fields(std::string_view key, - std::vector v) { - std::vector> vec; - for (auto val : v) { - std::string_view str = {val.data() + 1, val.size() - 2}; - size_t pos = str.find(','); - if (pos == std::string_view::npos || pos == str.size() - 1) { - continue; - } - - std::string_view origin = str.substr(0, pos); - std::string_view alias = str.substr(pos + 1); - - vec.push_back(std::make_pair(trim_sv(origin), trim_sv(alias))); - } - g_iguana_custom_map.emplace(key, std::move(vec)); - return 0; -} - -#define CUSTOM_FIELDS_IMPL(STRUCT_NAME, N, ...) \ - inline auto IGUANA_UNIQUE_VARIABLE(STRUCT_NAME) = iguana::add_custom_fields( \ - #STRUCT_NAME, {MARCO_EXPAND(MACRO_CONCAT(CON_STR, N)(__VA_ARGS__))}); - -#define CUSTOM_FIELDS(STRUCT_NAME, ...) \ - CUSTOM_FIELDS_IMPL(STRUCT_NAME, GET_ARG_COUNT(__VA_ARGS__), __VA_ARGS__) - -template -using Reflect_members = decltype(iguana_reflect_members( - std::declval>())); - -template -struct is_public_reflection : std::false_type {}; - -template -struct is_public_reflection>()))>> - : std::true_type {}; - -template -constexpr bool is_public_reflection_v = is_public_reflection::value; - -template -struct is_private_reflection : std::false_type {}; - -template -struct is_private_reflection< - T, std::void_t().iguana_reflect_members( - std::declval>()))>> : std::true_type {}; - -template -constexpr bool is_private_reflection_v = is_private_reflection::value; - -template -struct is_reflection>> - : std::true_type {}; - -template -struct is_reflection>> - : std::true_type {}; - -template -inline auto iguana_reflect_type(const T &t) { - if constexpr (is_public_reflection_v>) { - return iguana_reflect_members(iguana::detail::identity{}); - } - else { - return t.iguana_reflect_members(iguana::detail::identity{}); - } -} - -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