1 #include <iostream>
2 #include <nlohmann/json.hpp>
3
4 class visitor_adaptor_with_metadata
5 {
6 public:
7 template <class Fnc>
8 void visit(const Fnc& fnc) const;
9
10 int metadata = 42;
11 private:
12 template <class Ptr, class Fnc>
13 void do_visit(const Ptr& ptr, const Fnc& fnc) const;
14 };
15
16 using json = nlohmann::basic_json <
17 std::map,
18 std::vector,
19 std::string,
20 bool,
21 std::int64_t,
22 std::uint64_t,
23 double,
24 std::allocator,
25 nlohmann::adl_serializer,
26 std::vector<std::uint8_t>,
27 visitor_adaptor_with_metadata
28 >;
29
30 template <class Fnc>
visit(const Fnc & fnc) const31 void visitor_adaptor_with_metadata::visit(const Fnc& fnc) const
32 {
33 do_visit(json::json_pointer{}, fnc);
34 }
35
36 template <class Ptr, class Fnc>
do_visit(const Ptr & ptr,const Fnc & fnc) const37 void visitor_adaptor_with_metadata::do_visit(const Ptr& ptr, const Fnc& fnc) const
38 {
39 using value_t = nlohmann::detail::value_t;
40 const json& j = *static_cast<const json*>(this);
41 switch (j.type())
42 {
43 case value_t::object:
44 fnc(ptr, j);
45 for (const auto& entry : j.items())
46 {
47 entry.value().do_visit(ptr / entry.key(), fnc);
48 }
49 break;
50 case value_t::array:
51 fnc(ptr, j);
52 for (std::size_t i = 0; i < j.size(); ++i)
53 {
54 j.at(i).do_visit(ptr / std::to_string(i), fnc);
55 }
56 break;
57 case value_t::null:
58 case value_t::string:
59 case value_t::boolean:
60 case value_t::number_integer:
61 case value_t::number_unsigned:
62 case value_t::number_float:
63 case value_t::binary:
64 fnc(ptr, j);
65 break;
66 case value_t::discarded:
67 default:
68 break;
69 }
70 }
71
main()72 int main()
73 {
74 // create a json object
75 json j;
76 j["null"];
77 j["object"]["uint"] = 1U;
78 j["object"].metadata = 21;
79
80 // visit and output
81 j.visit(
82 [&](const json::json_pointer & p,
83 const json & j)
84 {
85 std::cout << (p.empty() ? std::string{"/"} : p.to_string())
86 << " - metadata = " << j.metadata << " -> " << j.dump() << '\n';
87 });
88 }
89