From 8e483b18a528ae95d143b95c7c8418f21b69aae7 Mon Sep 17 00:00:00 2001 From: "marek.piotrowski" Date: Wed, 19 Jul 2023 16:56:01 +0200 Subject: [PATCH] Adding minimal annotation support and a simple example --- CMakeLists.txt | 2 ++ example/CMakeLists.txt | 3 +++ example/main.cpp | 30 +++++++++++++++++++++++++ include/nlohmann/detail/macro_scope.hpp | 18 +++++++++++++++ include/nlohmann/json.hpp | 6 +++++ 5 files changed, 59 insertions(+) create mode 100644 example/CMakeLists.txt create mode 100644 example/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f942e04ab..e4ef0e2f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,3 +207,5 @@ if(JSON_Install) DESTINATION ${NLOHMANN_JSON_PKGCONFIG_INSTALL_DIR} ) endif() + +add_subdirectory(example) \ No newline at end of file diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 000000000..c5373b9ba --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable (AnnotatedNlohmannJson main.cpp) + +target_link_libraries (AnnotatedNlohmannJson PUBLIC nlohmann_json) \ No newline at end of file diff --git a/example/main.cpp b/example/main.cpp new file mode 100644 index 000000000..8c7ea08b3 --- /dev/null +++ b/example/main.cpp @@ -0,0 +1,30 @@ +#include +#include +#include + +#include + +class ExampleClass { +private: + int property1{1}; + double property2{2.5}; + std::string property3{"test"}; + std::map property4{{"x", 1}, {"y", 2}}; + std::vector property5{1.5, 5.4, 3.2}; +public: + ExampleClass() = default; + + // NLOHMANN_DEFINE_TYPE_INTRUSIVE(ExampleClass, property1, property2, property3, property4, property5); + + NLOHMANN_DEFINE_TYPE_INTRUSIVE_ANNOTATED(ExampleClass, property1, "comment1", + property2, "comment2"); +}; + +int main() { + std::cout << "Hello, world!" << std::endl; + ExampleClass ec; + + nlohmann::json j = ec; + std::cout << j.dump() << std::endl; + return 0; +} \ No newline at end of file diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index 2870a4f1d..53c23870a 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -382,6 +382,21 @@ #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; + + +#define NLOHMANN_JSON_ANNOTATED_EXPAND( x ) x +#define NLOHMANN_JSON_ANNOTATED_GET_MACRO(_1, _2, _3, _4, _5, NAME,...) NAME +#define NLOHMANN_JSON_ANNOTATED_PASTE(...) NLOHMANN_JSON_ANNOTATED_EXPAND(NLOHMANN_JSON_ANNOTATED_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_ANNOTATED_PASTE5, \ + NLOHMANN_JSON_ANNOTATED_PASTE2, \ + NLOHMANN_JSON_ANNOTATED_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) func(v1, w1) +// #define NLOHMANN_JSON_ANNOTATED_PASTE3(func, v1, w1, v2, w2) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v2, w2) +// #define NLOHMANN_JSON_ANNOTATED_PASTE4(func, v1, w1, v2, w2, v3, w3) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE3(func, v2, w2, v3, w3) +#define NLOHMANN_JSON_ANNOTATED_PASTE5(func, v1, w1, v2, w2) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v2, w2) + +#define NLOHMANN_JSON_ANNOTATED_TO(v1, w1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; nlohmann_json_j[#v1].annotate(w1); + #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); @@ -394,6 +409,9 @@ friend void to_json(nlohmann::json& nlohmann_json_j, const Type& 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_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ANNOTATED(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_ANNOTATED_EXPAND(NLOHMANN_JSON_ANNOTATED_PASTE(NLOHMANN_JSON_ANNOTATED_TO, __VA_ARGS__)) } + #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ friend void to_json(nlohmann::json& nlohmann_json_j, const Type& 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) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index a3c0af1e0..eedf27fbc 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -4201,6 +4201,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// the value of the current element json_value m_value = {}; + std::string m_annotation{""}; + data(const value_t v) : m_type(v), m_value(v) { @@ -4239,6 +4241,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @{ public: + void annotate(const std::string& annotation) { + m_data.m_annotation = annotation; + } + /// @brief create a CBOR serialization of a given JSON value /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/ static std::vector to_cbor(const basic_json& j)