From 79a70562d50423ba3ae2de0b4117ef0de861cba1 Mon Sep 17 00:00:00 2001 From: barcode Date: Tue, 28 Jun 2022 10:32:03 +0200 Subject: [PATCH] Update / add documentation for custom base class --- docs/examples/json_base_class_t.cpp | 87 +++++++++++++++++++ docs/examples/json_base_class_t.output | 4 + docs/mkdocs/docs/api/basic_json/index.md | 4 +- .../docs/api/basic_json/json_base_class_t.md | 44 ++++++++++ docs/mkdocs/mkdocs.yml | 1 + 5 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 docs/examples/json_base_class_t.cpp create mode 100644 docs/examples/json_base_class_t.output create mode 100644 docs/mkdocs/docs/api/basic_json/json_base_class_t.md diff --git a/docs/examples/json_base_class_t.cpp b/docs/examples/json_base_class_t.cpp new file mode 100644 index 000000000..6f4822ac4 --- /dev/null +++ b/docs/examples/json_base_class_t.cpp @@ -0,0 +1,87 @@ +#include +#include + +class visitor_adaptor_with_metadata +{ + public: + template + void visit(const Fnc& fnc) const; + + int metadata = 42; + private: + template + void do_visit(const Ptr& ptr, const Fnc& fnc) const; +}; + +using json = nlohmann::basic_json < + std::map, + std::vector, + std::string, + bool, + std::int64_t, + std::uint64_t, + double, + std::allocator, + nlohmann::adl_serializer, + std::vector, + visitor_adaptor_with_metadata + >; + +template +void visitor_adaptor_with_metadata::visit(const Fnc& fnc) const +{ + do_visit(json::json_pointer{}, fnc); +} + +template +void visitor_adaptor_with_metadata::do_visit(const Ptr& ptr, const Fnc& fnc) const +{ + using value_t = nlohmann::detail::value_t; + const json& j = *static_cast(this); + switch (j.type()) + { + case value_t::object: + fnc(ptr, j); + for (const auto& entry : j.items()) + { + entry.value().do_visit(ptr / entry.key(), fnc); + } + break; + case value_t::array: + fnc(ptr, j); + for (std::size_t i = 0; i < j.size(); ++i) + { + j.at(i).do_visit(ptr / std::to_string(i), fnc); + } + break; + case value_t::discarded: + break; + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + default: + fnc(ptr, j); + } +} + +int main() +{ + // create a json object + json j; + j["null"]; + j["object"]["uint"] = 1U; + j["object"].metadata = 21; + + // visit and output + j.visit( + [&](const json::json_pointer & p, + const json & j) + { + std::cout << (p.empty() ? std::string{"/"} : p.to_string()) + << " - metadata = " << j.metadata << " -> " << j.dump() << '\n'; + }); +} diff --git a/docs/examples/json_base_class_t.output b/docs/examples/json_base_class_t.output new file mode 100644 index 000000000..83ce1f693 --- /dev/null +++ b/docs/examples/json_base_class_t.output @@ -0,0 +1,4 @@ +/ - metadata = 42 -> {"null":null,"object":{"uint":1}} +/null - metadata = 42 -> null +/object - metadata = 21 -> {"uint":1} +/object/uint - metadata = 42 -> 1 diff --git a/docs/mkdocs/docs/api/basic_json/index.md b/docs/mkdocs/docs/api/basic_json/index.md index e474b662e..fb2be8fef 100644 --- a/docs/mkdocs/docs/api/basic_json/index.md +++ b/docs/mkdocs/docs/api/basic_json/index.md @@ -13,7 +13,8 @@ template< class NumberFloatType = double, template class AllocatorType = std::allocator, template class JSONSerializer = adl_serializer, - class BinaryType = std::vector + class BinaryType = std::vector > class basic_json; ``` @@ -32,6 +33,7 @@ class basic_json; | `AllocatorType` | type of the allocator to use | | | `JSONSerializer` | the serializer to resolve internal calls to `to_json()` and `from_json()` | [`json_serializer`](json_serializer.md) | | `BinaryType` | type for binary arrays | [`binary_t`](binary_t.md) | +| `CustomBaseClass` | extension point for user code | [`json_base_class_t`](json_base_class_t.md) | ## Specializations diff --git a/docs/mkdocs/docs/api/basic_json/json_base_class_t.md b/docs/mkdocs/docs/api/basic_json/json_base_class_t.md new file mode 100644 index 000000000..c8f3d25bf --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json/json_base_class_t.md @@ -0,0 +1,44 @@ +# nlohmann::basic_json::json_base_class_t + +```cpp +using json_base_class_t = detail::json_base_class; +``` + +The base class used to inject custom functionality into each instance of `basic_json`. +Examples for such functionality might be metadata, additional member functions (e.g. visitors) or other application specific code. + +## Template parameters + +`CustomBaseClass` +: the base class to be added to `basic_json` + +## Notes + +#### Default type + +The default value for `CustomBaseClass` is `void`. In this case an empty base class is used and no additional functionality is injected. + +#### Limits + +The type `CustomBaseClass` has to be a default constructible class. +`basic_json` only supports copy/move constructor/assignement if `CustomBaseClass` does so as well. + +## Examples + +??? example + + The following code shows how to inject custom data and methods for each node. + + ```cpp + --8<-- "examples/json_base_class_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_base_class_t.output" + ``` + +## Version history + +- Added in version ?.?.?. diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index 545584a92..823a59bea 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -141,6 +141,7 @@ nav: - 'is_string': api/basic_json/is_string.md - 'is_structured': api/basic_json/is_structured.md - 'items': api/basic_json/items.md + - 'json_base_class_t': api/basic_json/json_base_class_t.md - 'json_serializer': api/basic_json/json_serializer.md - 'max_size': api/basic_json/max_size.md - 'meta': api/basic_json/meta.md