Clean up, move code around
This commit is contained in:
parent
6127552b8a
commit
e03a06b332
@ -15,8 +15,8 @@ public:
|
||||
ExampleClass() = default;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_ANNOTATED(ExampleClass, property1, "comment1",
|
||||
property2, "comment2",
|
||||
property3, "comment3");
|
||||
property2, "multiline\ncomment2",
|
||||
property5, "comment5");
|
||||
};
|
||||
|
||||
class AnotherExampleClass {
|
||||
@ -30,8 +30,8 @@ public:
|
||||
AnotherExampleClass() = default;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_ANNOTATED(AnotherExampleClass, property1, "comment11",
|
||||
property2, "comment22",
|
||||
property3, "comment33");
|
||||
property2, "multiline\ncomment22",
|
||||
property3, "comment33");
|
||||
};
|
||||
|
||||
int main() {
|
||||
@ -40,9 +40,9 @@ int main() {
|
||||
AnotherExampleClass aec;
|
||||
|
||||
nlohmann::json j = ec;
|
||||
std::cout << j.dump_annotated<ExampleClass>() << std::endl;
|
||||
std::cout << j.dump_annotated<ExampleClass>(4) << std::endl;
|
||||
|
||||
nlohmann::json j2 = aec;
|
||||
std::cout << j2.dump_annotated<AnotherExampleClass>() << std::endl;
|
||||
// nlohmann::json j2 = aec;
|
||||
// std::cout << j2.dump_annotated<AnotherExampleClass>() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
@ -382,24 +382,6 @@
|
||||
#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, _6, _7, NAME,...) NAME
|
||||
#define NLOHMANN_JSON_ANNOTATED_PASTE(...) NLOHMANN_JSON_ANNOTATED_EXPAND(NLOHMANN_JSON_ANNOTATED_GET_MACRO(__VA_ARGS__, \
|
||||
NLOHMANN_JSON_ANNOTATED_PASTE7, \
|
||||
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_PASTE7(func, v1, w1, v2, w2, v3, w3) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE5(func, v2, w2, v3, w3)
|
||||
|
||||
#define NLOHMANN_JSON_ANNOTATED_TO(v1, w1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
|
||||
// #define NLOHMANN_EXPAND_ANNOTATION(v1, w1) static constexpr char annotation_##v1[] = 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);
|
||||
|
||||
@ -412,18 +394,6 @@
|
||||
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 TERNARY_EXPAND1(v1, w1) (property == #v1 ? w1 : "")
|
||||
#define TERNARY_EXPAND2(v1, w1, v2, w2) (property == #v2 ? w2 : TERNARY_EXPAND1(v1, w1))
|
||||
#define TERNARY_EXPAND3(v1, w1, v2, w2, v3, w3) (property == #v3 ? w3 : TERNARY_EXPAND2(v1, w1, v2, w2))
|
||||
#define TERNARY_NOT_ALLOWED
|
||||
|
||||
#define GET_TERNARY_EXPAND_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
|
||||
#define TERNARY_EXPAND(...) GET_TERNARY_EXPAND_MACRO(__VA_ARGS__, TERNARY_EXPAND3, TERNARY_NOT_ALLOWED, TERNARY_EXPAND2, TERNARY_NOT_ALLOWED, TERNARY_EXPAND1)(__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__)) } \
|
||||
static std::string get_annotation(const std::string& property) { return TERNARY_EXPAND(__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__)) }
|
||||
|
||||
27
include/nlohmann/detail/macro_scope_annotated.hpp
Normal file
27
include/nlohmann/detail/macro_scope_annotated.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
|
||||
#define NLOHMANN_JSON_ANNOTATED_TO(v1, w1) 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, _6, _7, NAME,...) NAME
|
||||
#define NLOHMANN_JSON_ANNOTATED_PASTE(...) NLOHMANN_JSON_ANNOTATED_EXPAND(NLOHMANN_JSON_ANNOTATED_GET_MACRO(__VA_ARGS__, \
|
||||
NLOHMANN_JSON_ANNOTATED_PASTE7, \
|
||||
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_PASTE5(func, v1, w1, v2, w2) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v2, w2)
|
||||
#define NLOHMANN_JSON_ANNOTATED_PASTE7(func, v1, w1, v2, w2, v3, w3) NLOHMANN_JSON_ANNOTATED_PASTE2(func, v1, w1) NLOHMANN_JSON_ANNOTATED_PASTE5(func, v2, w2, v3, w3)
|
||||
|
||||
|
||||
#define TERNARY_EXPAND1(v1, w1) (property == #v1 ? w1 : "")
|
||||
#define TERNARY_EXPAND2(v1, w1, v2, w2) (property == #v2 ? w2 : TERNARY_EXPAND1(v1, w1))
|
||||
#define TERNARY_EXPAND3(v1, w1, v2, w2, v3, w3) (property == #v3 ? w3 : TERNARY_EXPAND2(v1, w1, v2, w2))
|
||||
#define TERNARY_NOT_ALLOWED static_assert(false, "Annotated macro requires even number of arguments where each property is accompanied by a string comment.")
|
||||
|
||||
#define GET_TERNARY_EXPAND_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
|
||||
#define TERNARY_EXPAND(...) GET_TERNARY_EXPAND_MACRO(__VA_ARGS__, TERNARY_EXPAND3, TERNARY_NOT_ALLOWED, TERNARY_EXPAND2, TERNARY_NOT_ALLOWED, TERNARY_EXPAND1)(__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__)) } \
|
||||
static std::string get_annotation(const std::string& property) { return TERNARY_EXPAND(__VA_ARGS__); }
|
||||
@ -21,6 +21,7 @@
|
||||
#include <iomanip> // setfill, setw
|
||||
#include <type_traits> // is_same
|
||||
#include <utility> // move
|
||||
#include <sstream>
|
||||
|
||||
#include <nlohmann/detail/conversions/to_chars.hpp>
|
||||
#include <nlohmann/detail/exceptions.hpp>
|
||||
@ -31,6 +32,7 @@
|
||||
#include <nlohmann/detail/string_concat.hpp>
|
||||
#include <nlohmann/detail/value_t.hpp>
|
||||
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
namespace detail
|
||||
{
|
||||
@ -375,11 +377,195 @@ class serializer
|
||||
|
||||
template<typename UnderlyingType>
|
||||
void dump_annotated(const BasicJsonType& val,
|
||||
const bool pretty_print,
|
||||
const bool ensure_ascii,
|
||||
const unsigned int indent_step,
|
||||
const unsigned int current_indent = 0) {
|
||||
o->write_characters(UnderlyingType::get_annotation("property3").c_str(), UnderlyingType::get_annotation("property1").size());
|
||||
// o->write_characters(UnderlyingType::get_annotation("property3").c_str(), UnderlyingType::get_annotation("property1").size());
|
||||
switch (val.m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
{
|
||||
if (val.m_data.m_value.object->empty())
|
||||
{
|
||||
o->write_characters("{}", 2);
|
||||
return;
|
||||
}
|
||||
|
||||
o->write_characters("{\n", 2);
|
||||
|
||||
// variable to hold indentation for recursive calls
|
||||
const auto new_indent = current_indent + indent_step;
|
||||
if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
|
||||
{
|
||||
indent_string.resize(indent_string.size() * 2, ' ');
|
||||
}
|
||||
|
||||
// first n-1 elements
|
||||
auto i = val.m_data.m_value.object->cbegin();
|
||||
for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
|
||||
{
|
||||
write_annotation_if_available<UnderlyingType>(i->first, indent_string, new_indent);
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
o->write_characters("\": ", 3);
|
||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||
o->write_characters(",\n", 2);
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(i != val.m_data.m_value.object->cend());
|
||||
JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
|
||||
write_annotation_if_available<UnderlyingType>(i->first, indent_string, new_indent);
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
o->write_characters("\": ", 3);
|
||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||
|
||||
o->write_character('\n');
|
||||
o->write_characters(indent_string.c_str(), current_indent);
|
||||
o->write_character('}');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::array:
|
||||
{
|
||||
if (val.m_data.m_value.array->empty())
|
||||
{
|
||||
o->write_characters("[]", 2);
|
||||
return;
|
||||
}
|
||||
|
||||
o->write_characters("[\n", 2);
|
||||
|
||||
// variable to hold indentation for recursive calls
|
||||
const auto new_indent = current_indent + indent_step;
|
||||
if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
|
||||
{
|
||||
indent_string.resize(indent_string.size() * 2, ' ');
|
||||
}
|
||||
|
||||
// first n-1 elements
|
||||
for (auto i = val.m_data.m_value.array->cbegin();
|
||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||
{
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
||||
o->write_characters(",\n", 2);
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(!val.m_data.m_value.array->empty());
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
||||
|
||||
o->write_character('\n');
|
||||
o->write_characters(indent_string.c_str(), current_indent);
|
||||
o->write_character(']');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::string:
|
||||
{
|
||||
o->write_character('\"');
|
||||
dump_escaped(*val.m_data.m_value.string, ensure_ascii);
|
||||
o->write_character('\"');
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::binary:
|
||||
{
|
||||
o->write_characters("{\n", 2);
|
||||
|
||||
// variable to hold indentation for recursive calls
|
||||
const auto new_indent = current_indent + indent_step;
|
||||
if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
|
||||
{
|
||||
indent_string.resize(indent_string.size() * 2, ' ');
|
||||
}
|
||||
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
|
||||
o->write_characters("\"bytes\": [", 10);
|
||||
|
||||
if (!val.m_data.m_value.binary->empty())
|
||||
{
|
||||
for (auto i = val.m_data.m_value.binary->cbegin();
|
||||
i != val.m_data.m_value.binary->cend() - 1; ++i)
|
||||
{
|
||||
dump_integer(*i);
|
||||
o->write_characters(", ", 2);
|
||||
}
|
||||
dump_integer(val.m_data.m_value.binary->back());
|
||||
}
|
||||
|
||||
o->write_characters("],\n", 3);
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
|
||||
o->write_characters("\"subtype\": ", 11);
|
||||
if (val.m_data.m_value.binary->has_subtype())
|
||||
{
|
||||
dump_integer(val.m_data.m_value.binary->subtype());
|
||||
}
|
||||
else
|
||||
{
|
||||
o->write_characters("null", 4);
|
||||
}
|
||||
o->write_character('\n');
|
||||
o->write_characters(indent_string.c_str(), current_indent);
|
||||
o->write_character('}');
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::boolean:
|
||||
{
|
||||
if (val.m_data.m_value.boolean)
|
||||
{
|
||||
o->write_characters("true", 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
o->write_characters("false", 5);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::number_integer:
|
||||
{
|
||||
dump_integer(val.m_data.m_value.number_integer);
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::number_unsigned:
|
||||
{
|
||||
dump_integer(val.m_data.m_value.number_unsigned);
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::number_float:
|
||||
{
|
||||
dump_float(val.m_data.m_value.number_float);
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::discarded:
|
||||
{
|
||||
o->write_characters("<discarded>", 11);
|
||||
return;
|
||||
}
|
||||
|
||||
case value_t::null:
|
||||
{
|
||||
o->write_characters("null", 4);
|
||||
return;
|
||||
}
|
||||
|
||||
default: // LCOV_EXCL_LINE
|
||||
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
JSON_PRIVATE_UNLESS_TESTED:
|
||||
/*!
|
||||
@ -966,6 +1152,24 @@ class serializer
|
||||
return static_cast<number_unsigned_t>(-(x + 1)) + 1;
|
||||
}
|
||||
|
||||
template<typename UnderlyingType>
|
||||
void write_annotation_if_available(const std::string& property, const std::string& indent_string, unsigned int new_indent)
|
||||
{
|
||||
// TODO potentially add escaping option
|
||||
const auto annotation = UnderlyingType::get_annotation(property);
|
||||
if(annotation != "") {
|
||||
std::stringstream ss{annotation};
|
||||
for (std::string line; std::getline(ss, line, '\n');)
|
||||
{
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
o->write_characters("/* ", 3);
|
||||
o->write_characters(line.c_str(), line.size());
|
||||
o->write_characters(" */", 3);
|
||||
o->write_characters("\n", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/// the output of the serializer
|
||||
output_adapter_t<char> o = nullptr;
|
||||
|
||||
@ -60,6 +60,7 @@
|
||||
#include <nlohmann/detail/value_t.hpp>
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <nlohmann/ordered_map.hpp>
|
||||
#include <nlohmann/detail/macro_scope_annotated.hpp>
|
||||
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
#include <any>
|
||||
@ -1290,7 +1291,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
|
||||
template<typename UnderlyingType>
|
||||
string_t dump_annotated(const int indent = -1,
|
||||
string_t dump_annotated(const int indent = 4,
|
||||
const char indent_char = ' ',
|
||||
const bool ensure_ascii = false,
|
||||
const error_handler_t error_handler = error_handler_t::strict) const
|
||||
@ -1298,14 +1299,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
string_t result;
|
||||
serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
|
||||
|
||||
if (indent >= 0)
|
||||
{
|
||||
s.template dump_annotated<UnderlyingType>(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
|
||||
}
|
||||
else
|
||||
{
|
||||
s.template dump_annotated<UnderlyingType>(*this, false, ensure_ascii, 0);
|
||||
}
|
||||
JSON_ASSERT(indent >= 0);
|
||||
s.template dump_annotated<UnderlyingType>(*this, ensure_ascii, static_cast<unsigned int>(indent));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user