• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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