From 199dea11b17c533721b26249e2dcaee6ca1d51d3 Mon Sep 17 00:00:00 2001 From: AniketDhemare <59532267+AniketDhemare@users.noreply.github.com> Date: Fri, 15 Mar 2024 17:42:21 +0530 Subject: [PATCH 01/13] #4307 Updated docx to 3.10.5 from 3.10.4 (#4310) --- docs/mkdocs/docs/api/basic_json/update.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mkdocs/docs/api/basic_json/update.md b/docs/mkdocs/docs/api/basic_json/update.md index a594cf9d0..f3546157a 100644 --- a/docs/mkdocs/docs/api/basic_json/update.md +++ b/docs/mkdocs/docs/api/basic_json/update.md @@ -139,4 +139,4 @@ function. ## Version history - Added in version 3.0.0. -- Added `merge_objects` parameter in 3.10.4. +- Added `merge_objects` parameter in 3.10.5. From 16b3d841d57f513d39b9903fea3815c83f969504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20M=C3=BCller?= <147368808+philip-paul-mueller@users.noreply.github.com> Date: Mon, 8 Apr 2024 21:11:25 +0200 Subject: [PATCH 02/13] Fixed an error in the `Custom data source` example. (#4335) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 789a716f5..9f8ff1782 100644 --- a/README.md +++ b/README.md @@ -385,7 +385,7 @@ struct MyIterator { using iterator_category = std::input_iterator_tag; MyIterator& operator++() { - MyContainer.advance(); + target->advance(); return *this; } @@ -394,7 +394,7 @@ struct MyIterator { } reference operator*() const { - return target.get_current(); + return target->get_current(); } MyContainer* target = nullptr; From 377c767aa19da7159cf537490bc33da96edf8803 Mon Sep 17 00:00:00 2001 From: Leila Shcheglova <119249992+LeilaShcheglova@users.noreply.github.com> Date: Tue, 9 Apr 2024 02:12:32 +0700 Subject: [PATCH 03/13] Updated exception handling to catch const reference in out_of_range (#4331) Co-authored-by: LeilaSh --- docs/examples/at__keytype_const.c++17.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/at__keytype_const.c++17.cpp b/docs/examples/at__keytype_const.c++17.cpp index b08cd17b5..712d456e6 100644 --- a/docs/examples/at__keytype_const.c++17.cpp +++ b/docs/examples/at__keytype_const.c++17.cpp @@ -36,7 +36,7 @@ int main() // try to read from a nonexisting key using string_view std::cout << object.at("the fast"sv) << '\n'; } - catch (const json::out_of_range) + catch (const json::out_of_range& e) { std::cout << "out of range" << '\n'; } From c883fb0f17cbdf75545bddcc551e21a924a31b05 Mon Sep 17 00:00:00 2001 From: Alex Prabhat Bara <50404684+alexprabhat99@users.noreply.github.com> Date: Wed, 10 Apr 2024 21:47:47 +0530 Subject: [PATCH 04/13] Fix for incorrect function name in documentation example (#4342) --- docs/mkdocs/docs/features/arbitrary_types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mkdocs/docs/features/arbitrary_types.md b/docs/mkdocs/docs/features/arbitrary_types.md index 9b54fcb3e..e2e789338 100644 --- a/docs/mkdocs/docs/features/arbitrary_types.md +++ b/docs/mkdocs/docs/features/arbitrary_types.md @@ -265,7 +265,7 @@ struct bad_serializer } template - static void to_json(const BasicJsonType& j, T& value) { + static void from_json(const BasicJsonType& j, T& value) { // this calls BasicJsonType::json_serializer::from_json(j, value); // if BasicJsonType::json_serializer == bad_serializer ... oops! value = j.template template get(); // oops! From 97f0bdaf9a7e143e475bb331431a423694c21d19 Mon Sep 17 00:00:00 2001 From: laterlaugh <166613655+laterlaugh@users.noreply.github.com> Date: Fri, 12 Apr 2024 21:20:18 +0800 Subject: [PATCH 05/13] chore: fix some typos in comments (#4345) chore: fix some typos in comments Signed-off-by: laterlaugh --- tests/src/unit-class_parser.cpp | 2 +- tests/src/unit-regression2.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/unit-class_parser.cpp b/tests/src/unit-class_parser.cpp index ee42fb098..e2a8bac0f 100644 --- a/tests/src/unit-class_parser.cpp +++ b/tests/src/unit-class_parser.cpp @@ -828,7 +828,7 @@ TEST_CASE("parser class") // for ranges in range of IEEE 754-2008 binary64 (double precision) // this does not accommodate 64 bit integers without loss of accuracy. // As 64 bit integers are now widely used in software, it is desirable - // to expand support to to the full 64 bit (signed and unsigned) range + // to expand support to the full 64 bit (signed and unsigned) range // i.e. -(2**63) -> (2**64)-1. // -(2**63) ** Note: compilers see negative literals as negated positive numbers (hence the -1)) diff --git a/tests/src/unit-regression2.cpp b/tests/src/unit-regression2.cpp index 17624d3c6..0172a45ea 100644 --- a/tests/src/unit-regression2.cpp +++ b/tests/src/unit-regression2.cpp @@ -866,7 +866,7 @@ TEST_CASE("regression tests 2") CHECK(j.dump() == "[1,4]"); } - SECTION("issue #3343 - json and ordered_json are not interchangable") + SECTION("issue #3343 - json and ordered_json are not interchangeable") { json::object_t jobj({ { "product", "one" } }); ordered_json::object_t ojobj({{"product", "one"}}); From 01da82eae2f9a25377966556287b09a157a9985e Mon Sep 17 00:00:00 2001 From: Yuanhao Jia Date: Sat, 13 Apr 2024 20:11:49 +0800 Subject: [PATCH 06/13] Fix gdb pretty printer (#4343) --- tools/gdb_pretty_printer/nlohmann-json.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/gdb_pretty_printer/nlohmann-json.py b/tools/gdb_pretty_printer/nlohmann-json.py index 299152aed..3984f592f 100644 --- a/tools/gdb_pretty_printer/nlohmann-json.py +++ b/tools/gdb_pretty_printer/nlohmann-json.py @@ -17,16 +17,16 @@ def json_lookup_function(val): if m := ns_pattern.fullmatch(str(val.type.strip_typedefs().name)): name = m.group('name') if name and name.startswith('basic_json<') and name.endswith('>'): - m = ns_pattern.fullmatch(str(val['m_type'])) + m = ns_pattern.fullmatch(str(val["m_data"]['m_type'])) t = m.group('name') if t and t.startswith('detail::value_t::'): try: - union_val = val['m_value'][t.removeprefix('detail::value_t::')] + union_val = val["m_data"]['m_value'][t.removeprefix('detail::value_t::')] if union_val.type.code == gdb.TYPE_CODE_PTR: return gdb.default_visualizer(union_val.dereference()) else: return JsonValuePrinter(union_val) except Exception: - return JsonValuePrinter(val['m_type']) + return JsonValuePrinter(val["m_data"]['m_type']) gdb.pretty_printers.append(json_lookup_function) From 8c391e04fe4195d8be862c97f38cfe10e2a3472e Mon Sep 17 00:00:00 2001 From: Fallen_Breath Date: Sat, 13 Apr 2024 20:15:00 +0800 Subject: [PATCH 07/13] Docs: Fix wrong code usage in the Value access section of `json_pointer.md` (#4255) --- docs/mkdocs/docs/features/json_pointer.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/mkdocs/docs/features/json_pointer.md b/docs/mkdocs/docs/features/json_pointer.md index 04aeca504..4fd58f20e 100644 --- a/docs/mkdocs/docs/features/json_pointer.md +++ b/docs/mkdocs/docs/features/json_pointer.md @@ -71,10 +71,10 @@ auto j = json::parse(R"({ })"); // access values -auto val = j["/"_json_pointer]; // {"array":["A","B","C"],...} +auto val = j[""_json_pointer]; // {"array":["A","B","C"],...} auto val1 = j["/nested/one"_json_pointer]; // 1 -auto val2 = j.at[json::json_pointer("/nested/three/1")]; // false -auto val3 = j.value[json::json_pointer("/nested/four", 0)]; // 0 +auto val2 = j.at(json::json_pointer("/nested/three/1")); // false +auto val3 = j.value(json::json_pointer("/nested/four"), 0); // 0 ``` ## Flatten / unflatten From 960b763ecd144f156d05ec61f577b04107290137 Mon Sep 17 00:00:00 2001 From: Nikhil Idiculla Date: Sun, 7 Jul 2024 01:22:17 -0700 Subject: [PATCH 08/13] Docs: fix typos of 'whether' in `operator_{gt,le,lt}.md` (#4412) --- docs/mkdocs/docs/api/basic_json/operator_gt.md | 2 +- docs/mkdocs/docs/api/basic_json/operator_le.md | 2 +- docs/mkdocs/docs/api/basic_json/operator_lt.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/mkdocs/docs/api/basic_json/operator_gt.md b/docs/mkdocs/docs/api/basic_json/operator_gt.md index 9516656e0..486da5fd0 100644 --- a/docs/mkdocs/docs/api/basic_json/operator_gt.md +++ b/docs/mkdocs/docs/api/basic_json/operator_gt.md @@ -17,7 +17,7 @@ bool operator>(ScalarType lhs, const const_reference rhs) noexcept; // (2) operand is `NaN` and the other operand is either `NaN` or any other number. - Otherwise, returns the result of `#!cpp !(lhs <= rhs)` (see [**operator<=**](operator_le.md)). -2. Compares wether a JSON value is greater than a scalar or a scalar is greater than a JSON value by +2. Compares whether a JSON value is greater than a scalar or a scalar is greater than a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1. ## Template parameters diff --git a/docs/mkdocs/docs/api/basic_json/operator_le.md b/docs/mkdocs/docs/api/basic_json/operator_le.md index 7b648e035..c6144bb45 100644 --- a/docs/mkdocs/docs/api/basic_json/operator_le.md +++ b/docs/mkdocs/docs/api/basic_json/operator_le.md @@ -17,7 +17,7 @@ bool operator<=(ScalarType lhs, const const_reference rhs) noexcept; // (2) operand is `NaN` and the other operand is either `NaN` or any other number. - Otherwise, returns the result of `#!cpp !(rhs < lhs)` (see [**operator<**](operator_lt.md)). -1. Compares wether a JSON value is less than or equal to a scalar or a scalar is less than or equal +1. Compares whether a JSON value is less than or equal to a scalar or a scalar is less than or equal to a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1. diff --git a/docs/mkdocs/docs/api/basic_json/operator_lt.md b/docs/mkdocs/docs/api/basic_json/operator_lt.md index b5d191ec4..118d817c8 100644 --- a/docs/mkdocs/docs/api/basic_json/operator_lt.md +++ b/docs/mkdocs/docs/api/basic_json/operator_lt.md @@ -27,7 +27,7 @@ bool operator<(ScalarType lhs, const const_reference rhs) noexcept; // (2) 7. binary For instance, any boolean value is considered less than any string. -2. Compares wether a JSON value is less than a scalar or a scalar is less than a JSON value by converting +2. Compares whether a JSON value is less than a scalar or a scalar is less than a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1. ## Template parameters From b36f4c477c40356a0ae1204b567cca3c2a57d201 Mon Sep 17 00:00:00 2001 From: Griffin Myers Date: Thu, 5 Sep 2024 14:28:24 -0400 Subject: [PATCH 09/13] Update natvis to reflect 3.11.3 and the current structure of basic_json (#4451) * Update natvis Jinja template to reflect the current structure of basic_json. In 5a1a57510a330a521d1b20170b8e45aad52d790a the underlying structure of basic_json was altered to move m_type and m_value under an m_data field. This updates the nativ template to be consistent with this change. * Generate nlohmann_json.natvis for 3.11.3 and latest basic_json structure. --- nlohmann_json.natvis | 258 +++++++++--------- tools/generate_natvis/nlohmann_json.natvis.j2 | 26 +- 2 files changed, 142 insertions(+), 142 deletions(-) diff --git a/nlohmann_json.natvis b/nlohmann_json.natvis index a831ea04b..fbe4221f2 100644 --- a/nlohmann_json.natvis +++ b/nlohmann_json.natvis @@ -7,21 +7,21 @@ - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) @@ -37,21 +37,21 @@ - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) @@ -65,30 +65,30 @@ - - - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + + + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) - + {second} second @@ -97,21 +97,21 @@ - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) @@ -125,30 +125,30 @@ - - - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + + + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) - + {second} second @@ -157,21 +157,21 @@ - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) @@ -185,30 +185,30 @@ - - - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + + + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) - + {second} second @@ -217,21 +217,21 @@ - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) @@ -245,30 +245,30 @@ - - - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + + + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) - + {second} second diff --git a/tools/generate_natvis/nlohmann_json.natvis.j2 b/tools/generate_natvis/nlohmann_json.natvis.j2 index d6b728935..c3eafa54b 100644 --- a/tools/generate_natvis/nlohmann_json.natvis.j2 +++ b/tools/generate_natvis/nlohmann_json.natvis.j2 @@ -8,21 +8,21 @@ {% for ns in namespaces %} - null - {*(m_value.object)} - {*(m_value.array)} - {*(m_value.string)} - {m_value.boolean} - {m_value.number_integer} - {m_value.number_unsigned} - {m_value.number_float} - discarded + null + {*(m_data.m_value.object)} + {*(m_data.m_value.array)} + {*(m_data.m_value.string)} + {m_data.m_value.boolean} + {m_data.m_value.number_integer} + {m_data.m_value.number_unsigned} + {m_data.m_value.number_float} + discarded - - *(m_value.object),view(simple) + + *(m_data.m_value.object),view(simple) - - *(m_value.array),view(simple) + + *(m_data.m_value.array),view(simple) From 63258397761b3dd96dd171e5a5ad5aa915834c35 Mon Sep 17 00:00:00 2001 From: thetimr Date: Mon, 7 Oct 2024 22:53:32 -0600 Subject: [PATCH 10/13] Update is_structured.md (#4472) --- docs/mkdocs/docs/api/basic_json/is_structured.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mkdocs/docs/api/basic_json/is_structured.md b/docs/mkdocs/docs/api/basic_json/is_structured.md index f8fe4dcba..ecca80d8d 100644 --- a/docs/mkdocs/docs/api/basic_json/is_structured.md +++ b/docs/mkdocs/docs/api/basic_json/is_structured.md @@ -21,7 +21,7 @@ Constant. ## Possible implementation ```cpp -constexpr bool is_primitive() const noexcept +constexpr bool is_structured() const noexcept { return is_array() || is_object(); } From ac8b22180db393d56f5f2954eb353967fad254e3 Mon Sep 17 00:00:00 2001 From: Balazs Erseki Date: Mon, 4 Nov 2024 17:45:58 +0100 Subject: [PATCH 11/13] Update CONTRIBUTING.md (#4486) Typo in the filename. --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index dc98fd878..87b13df30 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -20,7 +20,7 @@ Clearly describe the issue: - If you propose a change or addition, try to give an **example** how the improved code could look like or how to use it. - If you found a compilation error, please tell us which **compiler** (version and operating system) you used and paste the (relevant part of) the error messages to the ticket. -Please stick to the provided issue template ([bug report](https://github.com/nlohmann/json/blob/develop/.github/ISSUE_TEMPLATE/bug.yml) if possible. For questions, feature or support requests, please [open a discussion](https://github.com/nlohmann/json/discussions/new). +Please stick to the provided issue template ([bug report](https://github.com/nlohmann/json/blob/develop/.github/ISSUE_TEMPLATE/bug.yaml) if possible. For questions, feature or support requests, please [open a discussion](https://github.com/nlohmann/json/discussions/new). ## Files to change From aff5a31d352c6826649b8ec022337d9df20dcf4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= <49476401+rotolof@users.noreply.github.com> Date: Fri, 8 Nov 2024 21:41:19 +0100 Subject: [PATCH 12/13] Add NLOHMANN_DEFINE_DERIVED_TYPE_* macros (#4033) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add NLOHMANN_DEFINE_DERIVED_TYPE_* macros * Fix with amalgamate * Add documentation * Fix with amalgamate * Fix with amalgamate --------- Co-authored-by: Niccolò Iardella --- .../macros/nlohmann_define_derived_type.md | 118 +++++++++++ include/nlohmann/detail/macro_scope.hpp | 26 +++ single_include/nlohmann/json.hpp | 69 +++---- single_include/nlohmann/json_fwd.hpp | 1 - tests/src/unit-udt_macro.cpp | 185 ++++++++++++++++++ 5 files changed, 356 insertions(+), 43 deletions(-) create mode 100644 docs/mkdocs/docs/api/macros/nlohmann_define_derived_type.md diff --git a/docs/mkdocs/docs/api/macros/nlohmann_define_derived_type.md b/docs/mkdocs/docs/api/macros/nlohmann_define_derived_type.md new file mode 100644 index 000000000..e7c92ada2 --- /dev/null +++ b/docs/mkdocs/docs/api/macros/nlohmann_define_derived_type.md @@ -0,0 +1,118 @@ +# NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT + +# NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT + +```cpp +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(type, base_type, member...) // (1) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(type, base_type, member...) // (2) + +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(type, base_type, member...) // (3) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, base_type, member...) // (4) +``` + +These macros can be used to simplify the serialization/deserialization of derived types if you want to use a JSON +object as serialization and want to use the member variable names as object keys in that object. + +- Macros 1 and 2 are to be defined **inside** the class/struct to create code for. +Like [`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](nlohmann_define_type_intrusive.md), they can access private members. +- Macros 3 and 4 are to be defined **outside** the class/struct to create code for, but **inside** its namespace. +Like [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](nlohmann_define_type_non_intrusive.md), +they **cannot** access private members. + + +The first parameter is the name of the derived class/struct, +the second parameter is the name of the base class/struct and all remaining parameters name the members. +The base type **must** be already serializable/deserializable. + +- Macros 1 and 3 will use [`at`](../basic_json/at.md) during deserialization and will throw + [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a key is missing in the JSON object. +- Macros 2 and 4 will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the + respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function + default constructs an object and uses its values as the defaults when calling the `value` function. + +## Parameters + +`type` (in) +: name of the type (class, struct) to serialize/deserialize + +`base_type` (in) +: name of the base type (class, struct) `type` is derived from + +`member` (in) +: name of the member variable to serialize/deserialize; up to 64 members can be given as comma-separated list + +## Default definition + +Macros 1 and 2 add two friend functions to the class which take care of the serialization and deserialization: + +```cpp +friend void to_json(nlohmann::json&, const type&); +friend void from_json(const nlohmann::json&, type&); +``` + +Macros 3 and 4 add two functions to the namespace which take care of the serialization and deserialization: + +```cpp +void to_json(nlohmann::json&, const type&); +void from_json(const nlohmann::json&, type&); +``` + +In both cases they call the `to_json`/`from_json` functions of the base type +before serializing/deserializing the members of the derived type: + +```cpp +class A { /* ... */ }; +class B : public A { /* ... */ }; + +void to_json(nlohmann::json& j, const B& b) { + nlohmann::to_json(j, static_cast(b)); + // ... +} + +void from_json(const nlohmann::json& j, B& b) { + nlohmann::from_json(j, static_cast(b)); + // ... +} +``` + +## Notes + +!!! info "Prerequisites" + + - Macros 1 and 2 have the same prerequisites of NLOHMANN_DEFINE_TYPE_INTRUSIVE. + - Macros 3 and 3 have the same prerequisites of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE. + - Serialization/deserialization of base types must be defined. + +!!! warning "Implementation limits" + + - See Implementation limits for NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE. + +## Examples + +Example of `NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE` usage: + +```cpp +class A { + double Aa; + double Ab; + NLOHMANN_DEFINE_TYPE_INTRUSIVE(A, Aa, Ab) +}; + +class B : public A { + int Ba; + int Bb; + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(B, A, Ba, Bb) +}; +``` + +## See also + +- [NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT](nlohmann_define_type_intrusive.md) + for similar macros that can be defined _inside_ a non-derived type. +- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT](nlohmann_define_type_non_intrusive.md) + for a similar macros that can be defined _outside_ a non-derived type. +- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview. + +## Version history + +1. Added in version 3.11.x. diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index 97127a646..be31fd88c 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -425,6 +425,32 @@ inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE +@since version 3.11.x +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE +@since version 3.11.x +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + // inspired from https://stackoverflow.com/a/26745591 // allows to call any std function as if (e.g. with begin): // using std::begin; begin(x); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index a858728c4..18066f486 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -41,7 +41,6 @@ // SPDX-License-Identifier: MIT - #include // #include @@ -54,7 +53,6 @@ // SPDX-License-Identifier: MIT - // This file contains all macro definitions affecting or depending on the ABI #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK @@ -156,7 +154,6 @@ // SPDX-License-Identifier: MIT - #include // transform #include // array #include // forward_list @@ -179,7 +176,6 @@ // SPDX-License-Identifier: MIT - #include // nullptr_t #include // exception #if JSON_DIAGNOSTICS @@ -199,7 +195,6 @@ // SPDX-License-Identifier: MIT - #include // array #include // size_t #include // uint8_t @@ -215,7 +210,6 @@ // SPDX-License-Identifier: MIT - #include // declval, pair // #include // __ _____ _____ _____ @@ -227,7 +221,6 @@ // SPDX-License-Identifier: MIT - #include // #include @@ -240,7 +233,6 @@ // SPDX-License-Identifier: MIT - // #include @@ -2777,6 +2769,33 @@ JSON_HEDLEY_DIAGNOSTIC_POP inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE +@since version 3.11.x +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE +@since version 3.11.x +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + + // inspired from https://stackoverflow.com/a/26745591 // allows to call any std function as if (e.g. with begin): // using std::begin; begin(x); @@ -2946,7 +2965,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - // #include @@ -3021,7 +3039,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // size_t // #include @@ -3064,7 +3081,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // array #include // size_t #include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type @@ -3237,7 +3253,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // numeric_limits #include // false_type, is_constructible, is_integral, is_same, true_type #include // declval @@ -3254,7 +3269,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // random_access_iterator_tag // #include @@ -3322,7 +3336,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - // #include @@ -3342,7 +3355,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - // #include @@ -4217,7 +4229,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // strlen #include // string #include // forward @@ -4603,7 +4614,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - // #include @@ -4627,7 +4637,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - // #include @@ -5133,7 +5142,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // copy #include // begin, end #include // string @@ -5153,7 +5161,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // size_t #include // input_iterator_tag #include // string, to_string @@ -5875,7 +5882,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // uint8_t, uint64_t #include // tie #include // move @@ -5987,7 +5993,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // uint8_t #include // size_t #include // hash @@ -6120,7 +6125,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // generate_n #include // array #include // ldexp @@ -6146,7 +6150,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // array #include // size_t #include // strlen @@ -6643,7 +6646,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include #include // string #include // move @@ -7375,7 +7377,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // array #include // localeconv #include // size_t @@ -9016,7 +9017,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // size_t #include // declval #include // string @@ -12168,7 +12168,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // isfinite #include // uint8_t #include // function @@ -12697,7 +12696,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - // #include // #include @@ -12710,7 +12708,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // ptrdiff_t #include // numeric_limits @@ -12869,7 +12866,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next #include // conditional, is_const, remove_const @@ -13631,7 +13627,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // ptrdiff_t #include // reverse_iterator #include // declval @@ -13808,7 +13803,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // all_of #include // isdigit #include // errno, ERANGE @@ -14803,7 +14797,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include #include @@ -14895,7 +14888,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // reverse #include // array #include // map @@ -14921,7 +14913,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // copy #include // size_t #include // back_inserter @@ -16890,7 +16881,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // reverse, remove, fill, find, none_of #include // array #include // localeconv, lconv @@ -16915,7 +16905,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // array #include // signbit, isfinite #include // intN_t, uintN_t @@ -19010,7 +18999,6 @@ NLOHMANN_JSON_NAMESPACE_END // SPDX-License-Identifier: MIT - #include // equal_to, less #include // initializer_list #include // input_iterator_tag, iterator_traits @@ -24566,7 +24554,6 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC // SPDX-License-Identifier: MIT - // restore clang diagnostic settings #if defined(__clang__) #pragma clang diagnostic pop @@ -24611,7 +24598,6 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC // SPDX-License-Identifier: MIT - #undef JSON_HEDLEY_ALWAYS_INLINE #undef JSON_HEDLEY_ARM_VERSION #undef JSON_HEDLEY_ARM_VERSION_CHECK @@ -24762,5 +24748,4 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC #undef JSON_HEDLEY_FALL_THROUGH - #endif // INCLUDE_NLOHMANN_JSON_HPP_ diff --git a/single_include/nlohmann/json_fwd.hpp b/single_include/nlohmann/json_fwd.hpp index 29a6036d7..f219db3be 100644 --- a/single_include/nlohmann/json_fwd.hpp +++ b/single_include/nlohmann/json_fwd.hpp @@ -25,7 +25,6 @@ // SPDX-License-Identifier: MIT - // This file contains all macro definitions affecting or depending on the ABI #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK diff --git a/tests/src/unit-udt_macro.cpp b/tests/src/unit-udt_macro.cpp index 04631a4dc..668ad8b3a 100644 --- a/tests/src/unit-udt_macro.cpp +++ b/tests/src/unit-udt_macro.cpp @@ -38,6 +38,26 @@ class person_with_private_data NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata) }; +class derived_person_with_private_data : public person_with_private_data +{ + private: + std::string hair_color{"blue"}; + + public: + bool operator==(const derived_person_with_private_data& rhs) const + { + return person_with_private_data::operator==(rhs) && hair_color == rhs.hair_color; + } + + derived_person_with_private_data() = default; + derived_person_with_private_data(std::string name_, int age_, json metadata_, std::string hair_color_) + : person_with_private_data(std::move(name_), age_, std::move(metadata_)) + , hair_color(std::move(hair_color_)) + {} + + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived_person_with_private_data, person_with_private_data, hair_color) +}; + class person_with_private_data_2 { private: @@ -74,6 +94,31 @@ class person_with_private_data_2 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(person_with_private_data_2, age, name, metadata) }; +class derived_person_with_private_data_2 : public person_with_private_data_2 +{ + private: + std::string hair_color{"blue"}; + + public: + bool operator==(const derived_person_with_private_data_2& rhs) const + { + return person_with_private_data_2::operator==(rhs) && hair_color == rhs.hair_color; + } + + derived_person_with_private_data_2() = default; + derived_person_with_private_data_2(std::string name_, int age_, json metadata_, std::string hair_color_) + : person_with_private_data_2(std::move(name_), age_, std::move(metadata_)) + , hair_color(std::move(hair_color_)) + {} + + std::string getHairColor() const + { + return hair_color; + } + + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(derived_person_with_private_data_2, person_with_private_data_2, hair_color) +}; + class person_without_private_data_1 { public: @@ -96,6 +141,26 @@ class person_without_private_data_1 NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_without_private_data_1, age, name, metadata) }; +class derived_person_without_private_data_1 : public person_without_private_data_1 +{ + public: + std::string hair_color{"blue"}; + + public: + bool operator==(const derived_person_without_private_data_1& rhs) const + { + return person_without_private_data_1::operator==(rhs) && hair_color == rhs.hair_color; + } + + derived_person_without_private_data_1() = default; + derived_person_without_private_data_1(std::string name_, int age_, json metadata_, std::string hair_color_) + : person_without_private_data_1(std::move(name_), age_, std::move(metadata_)) + , hair_color(std::move(hair_color_)) + {} + + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived_person_without_private_data_1, person_without_private_data_1, hair_color) +}; + class person_without_private_data_2 { public: @@ -118,6 +183,26 @@ class person_without_private_data_2 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata) +class derived_person_without_private_data_2 : public person_without_private_data_2 +{ + public: + std::string hair_color{"blue"}; + + public: + bool operator==(const derived_person_without_private_data_2& rhs) const + { + return person_without_private_data_2::operator==(rhs) && hair_color == rhs.hair_color; + } + + derived_person_without_private_data_2() = default; + derived_person_without_private_data_2(std::string name_, int age_, json metadata_, std::string hair_color_) + : person_without_private_data_2(std::move(name_), age_, std::move(metadata_)) + , hair_color(std::move(hair_color_)) + {} +}; + +NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(derived_person_without_private_data_2, person_without_private_data_2, hair_color) + class person_without_private_data_3 { public: @@ -153,6 +238,31 @@ class person_without_private_data_3 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(person_without_private_data_3, age, name, metadata) +class derived_person_without_private_data_3 : public person_without_private_data_3 +{ + public: + std::string hair_color{"blue"}; + + public: + bool operator==(const derived_person_without_private_data_3& rhs) const + { + return person_without_private_data_3::operator==(rhs) && hair_color == rhs.hair_color; + } + + derived_person_without_private_data_3() = default; + derived_person_without_private_data_3(std::string name_, int age_, json metadata_, std::string hair_color_) + : person_without_private_data_3(std::move(name_), age_, std::move(metadata_)) + , hair_color(std::move(hair_color_)) + {} + + std::string getHairColor() const + { + return hair_color; + } +}; + +NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(derived_person_without_private_data_3, person_without_private_data_3, hair_color) + class person_with_private_alphabet { public: @@ -216,6 +326,19 @@ class person_with_private_alphabet NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) }; +class derived_person_with_private_alphabet : public person_with_private_alphabet +{ + public: + bool operator==(const derived_person_with_private_alphabet& other) const + { + return person_with_private_alphabet::operator==(other) && schwa == other.schwa; + } + + private: + int schwa = 0; + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived_person_with_private_alphabet, person_with_private_alphabet, schwa) +}; + class person_with_public_alphabet { public: @@ -345,6 +468,32 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRU } } +TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE", T, + persons::derived_person_with_private_data, + persons::derived_person_without_private_data_1, + persons::derived_person_without_private_data_2) +{ + SECTION("person") + { + // serialization + T p1("Erik", 1, {{"haircuts", 2}}, "red"); + CHECK(json(p1).dump() == "{\"age\":1,\"hair_color\":\"red\",\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}"); + + // deserialization + auto p2 = json(p1).get(); + CHECK(p2 == p1); + + // roundtrip + CHECK(T(json(p1)) == p1); + CHECK(json(T(json(p1))) == json(p1)); + + // check exception in case of missing field + json j = json(p1); + j.erase("age"); + CHECK_THROWS_WITH_AS(j.get(), "[json.exception.out_of_range.403] key 'age' not found", json::out_of_range); + } +} + TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT", T, persons::person_with_private_data_2, persons::person_without_private_data_3) @@ -379,6 +528,42 @@ TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRU } } +TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT and NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT", T, + persons::derived_person_with_private_data_2, + persons::derived_person_without_private_data_3) +{ + SECTION("derived person with default values") + { + // serialization of default constructed object + T p0; + CHECK(json(p0).dump() == "{\"age\":0,\"hair_color\":\"blue\",\"metadata\":null,\"name\":\"\"}"); + + // serialization + T p1("Erik", 1, {{"haircuts", 2}}, "red"); + CHECK(json(p1).dump() == "{\"age\":1,\"hair_color\":\"red\",\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}"); + + // deserialization + auto p2 = json(p1).get(); + CHECK(p2 == p1); + + // roundtrip + CHECK(T(json(p1)) == p1); + CHECK(json(T(json(p1))) == json(p1)); + + // check default value in case of missing field + json j = json(p1); + j.erase("name"); + j.erase("age"); + j.erase("metadata"); + j.erase("hair_color"); + T p3 = j.get(); + CHECK(p3.getName() == ""); + CHECK(p3.getAge() == 0); + CHECK(p3.getMetadata() == nullptr); + CHECK(p3.getHairColor() == "blue"); + } +} + TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T, persons::person_with_private_alphabet, persons::person_with_public_alphabet) From 18ff442e63984e60e54c22b100e29e682951b81f Mon Sep 17 00:00:00 2001 From: Borislav Stanimirov Date: Fri, 8 Nov 2024 22:42:36 +0200 Subject: [PATCH 13/13] Allow overriding the CMake target name (#4483) --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a49dc47e..c7bbc7da4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,11 @@ endif () ## include(GNUInstallDirs) -set(NLOHMANN_JSON_TARGET_NAME ${PROJECT_NAME}) +if (NOT DEFINED NLOHMANN_JSON_TARGET_NAME) + # Allow overriding the target name when using FetchContent / add_subdirectory. + set(NLOHMANN_JSON_TARGET_NAME ${PROJECT_NAME}) +endif() + set(NLOHMANN_JSON_CONFIG_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}" CACHE INTERNAL "") set(NLOHMANN_JSON_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") set(NLOHMANN_JSON_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")