From 07b364c555533572916985b1ec4ab212111e0825 Mon Sep 17 00:00:00 2001 From: MistEO Date: Tue, 23 Jan 2024 18:40:41 +0800 Subject: [PATCH] feat: MEO_JSONIZATION for basic type --- CMakeLists.txt | 2 +- README.md | 36 ++++++++++++++++ README_en.md | 36 ++++++++++++++++ include/json.hpp | 108 +++++++++++++++++++++++++++++++++++++++++++++- sample/sample.cpp | 32 ++++++++++++++ 5 files changed, 212 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ddac2d..bb73964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ option(BUILD_TESTING "Build testing" ON) set(CMAKE_CXX_STANDARD 17) if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") - add_compile_options("/utf-8" "/W4" "/WX") + add_compile_options("/utf-8" "/W4" "/WX" "/Zc:preprocessor") else() add_compile_options("-Wall;-Wextra;-Wpedantic;-Werror;-mtune=native") if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|EM64T|x86_64") diff --git a/README.md b/README.md index 0554bf8..366eae9 100644 --- a/README.md +++ b/README.md @@ -256,3 +256,39 @@ void serializing() ofs.close(); } ``` + +### 序列化 + +```c++ +void test_jsonization() +{ + struct MyStruct + { + std::vector vec; + std::map map; + + int i = 0; + double d = 0; + + // 如果你正在使用 MSVC, 请添加 "/Zc:preprocessor" 到项目设置中 + MEO_JSONIZATION(vec, map, i, d); + }; + + MyStruct a; + a.vec = { 1, 2, 3, 4, 5 }; + a.map = { { "key", 5 } }; + a.i = 100; + a.d = 0.5; + + json::object j = a.dump_to_json(); + + // output: { "d" : 0.500000, "i" : 100, "map" : { "key" : 5 }, "vec" : [ 1, 2, 3 ] } + std::cout << j << std::endl; + + MyStruct b; + b.load_from_json(j); + + // output: { "d" : 0.500000, "i" : 100, "map" : { "key" : 5 }, "vec" : [ 1, 2, 3 ] } + std::cout << b.dump_to_json() << std::endl; +} +``` diff --git a/README_en.md b/README_en.md index 9abab83..809f6ea 100644 --- a/README_en.md +++ b/README_en.md @@ -256,3 +256,39 @@ void serializing() ofs.close(); } ``` + +### JSONization + +```c++ +void test_jsonization() +{ + struct MyStruct + { + std::vector vec; + std::map map; + + int i = 0; + double d = 0; + + // if you are using MSVC, please add "/Zc:preprocessor" to your project + MEO_JSONIZATION(vec, map, i, d); + }; + + MyStruct a; + a.vec = { 1, 2, 3, 4, 5 }; + a.map = { { "key", 5 } }; + a.i = 100; + a.d = 0.5; + + json::object j = a.dump_to_json(); + + // output: { "d" : 0.500000, "i" : 100, "map" : { "key" : 5 }, "vec" : [ 1, 2, 3 ] } + std::cout << j << std::endl; + + MyStruct b; + b.load_from_json(j); + + // output: { "d" : 0.500000, "i" : 100, "map" : { "key" : 5 }, "vec" : [ 1, 2, 3 ] } + std::cout << b.dump_to_json() << std::endl; +} +``` diff --git a/include/json.hpp b/include/json.hpp index 2fd001f..8b79f18 100644 --- a/include/json.hpp +++ b/include/json.hpp @@ -1536,7 +1536,6 @@ template template typename collection_t> inline collection_t basic_array::as_collection() const { - collection_t result; if constexpr (_as_collection_helper::has_emplace_back>::value) { for (const auto& elem : _array_data) { @@ -2774,3 +2773,110 @@ static constexpr string_t unescape_string(const string_t& str) return result; } } // namespace json + +#define _MEOJSON_STRINGIZE(arg) _MEOJSON_STRINGIZE1(arg) +#define _MEOJSON_STRINGIZE1(arg) _MEOJSON_STRINGIZE2(arg) +#define _MEOJSON_STRINGIZE2(arg) #arg + +#define _MEOJSON_CONCATENATE(arg1, arg2) _MEOJSON_CONCATENATE1(arg1, arg2) +#define _MEOJSON_CONCATENATE1(arg1, arg2) _MEOJSON_CONCATENATE2(arg1, arg2) +#define _MEOJSON_CONCATENATE2(arg1, arg2) arg1##arg2 + +#define _MEOJSON_FOR_EACH_0(what, ...) +#define _MEOJSON_FOR_EACH_1(what, x, ...) what(x) +#define _MEOJSON_FOR_EACH_2(what, x, ...) what(x) _MEOJSON_FOR_EACH_1(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_3(what, x, ...) what(x) _MEOJSON_FOR_EACH_2(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_4(what, x, ...) what(x) _MEOJSON_FOR_EACH_3(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_5(what, x, ...) what(x) _MEOJSON_FOR_EACH_4(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_6(what, x, ...) what(x) _MEOJSON_FOR_EACH_5(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_7(what, x, ...) what(x) _MEOJSON_FOR_EACH_6(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_8(what, x, ...) what(x) _MEOJSON_FOR_EACH_7(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_9(what, x, ...) what(x) _MEOJSON_FOR_EACH_8(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_10(what, x, ...) what(x) _MEOJSON_FOR_EACH_9(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_11(what, x, ...) what(x) _MEOJSON_FOR_EACH_10(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_12(what, x, ...) what(x) _MEOJSON_FOR_EACH_11(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_13(what, x, ...) what(x) _MEOJSON_FOR_EACH_12(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_14(what, x, ...) what(x) _MEOJSON_FOR_EACH_13(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_15(what, x, ...) what(x) _MEOJSON_FOR_EACH_14(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_16(what, x, ...) what(x) _MEOJSON_FOR_EACH_15(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_17(what, x, ...) what(x) _MEOJSON_FOR_EACH_16(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_18(what, x, ...) what(x) _MEOJSON_FOR_EACH_17(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_19(what, x, ...) what(x) _MEOJSON_FOR_EACH_18(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_20(what, x, ...) what(x) _MEOJSON_FOR_EACH_19(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_21(what, x, ...) what(x) _MEOJSON_FOR_EACH_20(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_22(what, x, ...) what(x) _MEOJSON_FOR_EACH_21(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_23(what, x, ...) what(x) _MEOJSON_FOR_EACH_22(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_24(what, x, ...) what(x) _MEOJSON_FOR_EACH_23(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_25(what, x, ...) what(x) _MEOJSON_FOR_EACH_24(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_26(what, x, ...) what(x) _MEOJSON_FOR_EACH_25(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_27(what, x, ...) what(x) _MEOJSON_FOR_EACH_26(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_28(what, x, ...) what(x) _MEOJSON_FOR_EACH_27(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_29(what, x, ...) what(x) _MEOJSON_FOR_EACH_28(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_30(what, x, ...) what(x) _MEOJSON_FOR_EACH_29(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_31(what, x, ...) what(x) _MEOJSON_FOR_EACH_30(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_32(what, x, ...) what(x) _MEOJSON_FOR_EACH_31(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_33(what, x, ...) what(x) _MEOJSON_FOR_EACH_32(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_34(what, x, ...) what(x) _MEOJSON_FOR_EACH_33(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_35(what, x, ...) what(x) _MEOJSON_FOR_EACH_34(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_36(what, x, ...) what(x) _MEOJSON_FOR_EACH_35(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_37(what, x, ...) what(x) _MEOJSON_FOR_EACH_36(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_38(what, x, ...) what(x) _MEOJSON_FOR_EACH_37(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_39(what, x, ...) what(x) _MEOJSON_FOR_EACH_38(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_40(what, x, ...) what(x) _MEOJSON_FOR_EACH_39(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_41(what, x, ...) what(x) _MEOJSON_FOR_EACH_40(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_42(what, x, ...) what(x) _MEOJSON_FOR_EACH_41(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_43(what, x, ...) what(x) _MEOJSON_FOR_EACH_42(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_44(what, x, ...) what(x) _MEOJSON_FOR_EACH_43(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_45(what, x, ...) what(x) _MEOJSON_FOR_EACH_44(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_46(what, x, ...) what(x) _MEOJSON_FOR_EACH_45(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_47(what, x, ...) what(x) _MEOJSON_FOR_EACH_46(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_48(what, x, ...) what(x) _MEOJSON_FOR_EACH_47(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_49(what, x, ...) what(x) _MEOJSON_FOR_EACH_48(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_50(what, x, ...) what(x) _MEOJSON_FOR_EACH_49(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_51(what, x, ...) what(x) _MEOJSON_FOR_EACH_50(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_52(what, x, ...) what(x) _MEOJSON_FOR_EACH_51(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_53(what, x, ...) what(x) _MEOJSON_FOR_EACH_52(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_54(what, x, ...) what(x) _MEOJSON_FOR_EACH_53(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_55(what, x, ...) what(x) _MEOJSON_FOR_EACH_54(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_56(what, x, ...) what(x) _MEOJSON_FOR_EACH_55(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_57(what, x, ...) what(x) _MEOJSON_FOR_EACH_56(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_58(what, x, ...) what(x) _MEOJSON_FOR_EACH_57(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_59(what, x, ...) what(x) _MEOJSON_FOR_EACH_58(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_60(what, x, ...) what(x) _MEOJSON_FOR_EACH_59(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_61(what, x, ...) what(x) _MEOJSON_FOR_EACH_60(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_62(what, x, ...) what(x) _MEOJSON_FOR_EACH_61(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_63(what, x, ...) what(x) _MEOJSON_FOR_EACH_62(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH_64(what, x, ...) what(x) _MEOJSON_FOR_EACH_63(what, __VA_ARGS__) + +#define _MEOJSON_ARG_COUNT(...) \ + _MEOJSON_ARG_COUNT1(0, ##__VA_ARGS__, 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 _MEOJSON_ARG_COUNT1(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \ + _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ + _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, \ + _56, _57, _58, _59, _60, _61, _62, _63, _64, N, ...) \ + N + +#define _MEOJSON_FOR_EACH_(N, what, ...) _MEOJSON_CONCATENATE(_MEOJSON_FOR_EACH_, N)(what, __VA_ARGS__) +#define _MEOJSON_FOR_EACH(what, ...) _MEOJSON_FOR_EACH_(_MEOJSON_ARG_COUNT(__VA_ARGS__), what, __VA_ARGS__) + +#define _MEOJSON_ARG_TO_PAIR(x) { _MEOJSON_STRINGIZE(x), json::serialize(x) }, + +#define _MEOJSON_ARG_FROM_JSON(x) \ + if (auto x##opt = raw.find(#x)) \ + x = *std::move(x##opt); \ + else \ + return false; + +// if you are using MSVC, please add "/Zc:preprocessor" to your project +#define MEO_JSONIZATION(...) \ + json::object dump_to_json() const \ + { \ + return { _MEOJSON_FOR_EACH(_MEOJSON_ARG_TO_PAIR, __VA_ARGS__) }; \ + } \ + bool load_from_json(const json::object& raw) \ + { \ + _MEOJSON_FOR_EACH(_MEOJSON_ARG_FROM_JSON, __VA_ARGS__) \ + return true; \ + } diff --git a/sample/sample.cpp b/sample/sample.cpp index e00c3be..9082baa 100644 --- a/sample/sample.cpp +++ b/sample/sample.cpp @@ -11,6 +11,7 @@ bool parsing(); bool parsing_width(); bool serializing(); +void test_jsonization(); int main() { @@ -26,6 +27,8 @@ int main() return -1; } + test_jsonization(); + return 0; } @@ -293,3 +296,32 @@ bool serializing() return true; } + +void test_jsonization() +{ + struct MyStruct + { + std::vector vec; + std::map map; + + int i = 0; + double d = 0; + + // if you are using MSVC, please add "/Zc:preprocessor" to your project + MEO_JSONIZATION(vec, map, i, d); + }; + + MyStruct a; + a.vec = { 1, 2, 3 }; + a.map = { { "key", 5 } }; + a.i = 100; + a.d = 0.5; + + json::object j = a.dump_to_json(); + std::cout << j << std::endl; + + MyStruct b; + b.load_from_json(j); + + std::cout << b.dump_to_json() << std::endl; +}