Skip to content

nlohmann::basic_json::json_base_class_t

using json_base_class_t = detail::json_base_class<CustomBaseClass>;

The base class used to inject custom functionality into each instance of basic_json. Examples of 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.

Limitations

The type CustomBaseClass has to be a default-constructible class. basic_json only supports copy/move construction/assignment if CustomBaseClass does so as well.

Examples

Example

The following code shows how to inject custom data and methods for each node.

#include <iostream>
#include <nlohmann/json.hpp>

class visitor_adaptor_with_metadata
{
  public:
    template <class Fnc>
    void visit(const Fnc& fnc) const;

    int metadata = 42;
  private:
    template <class Ptr, class Fnc>
    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<std::uint8_t>,
             visitor_adaptor_with_metadata
             >;

template <class Fnc>
void visitor_adaptor_with_metadata::visit(const Fnc& fnc) const
{
    do_visit(json::json_pointer{}, fnc);
}

template <class Ptr, class Fnc>
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<const json*>(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::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:
            fnc(ptr, j);
            break;
        case value_t::discarded:
        default:
            break;
    }
}

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';
    });
}

Output:

/ - metadata = 42 -> {"null":null,"object":{"uint":1}}
/null - metadata = 42 -> null
/object - metadata = 21 -> {"uint":1}
/object/uint - metadata = 42 -> 1

Version history

  • Added in version 3.12.0.

Last update: December 19, 2022