Skip to content

basic_json templated on a "policy" class #456

Description

@jaredgrubb

I'm enjoying the library, however I have a couple comments:

  • the mangled name is really awful:
    nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long long, unsigned long long, double, std::__1::allocator, nlohmann::adl_serializer>
  • it's not possible to extend basic_json beyond the types

The mangled name is cosmetic, but it is annoying to have to try to read stackshots or prints in debuggers.

One idea I had was to refactor basic_json to be based on a policy type, aka nlohmann::basic_json<nlohmann::default_policy>, where default_policy would be defined something like:

template <
    template<typename U, typename V, typename... Args> class ObjectType = std::map,
    template<typename U, typename... Args> class ArrayType = std::vector,
    class StringType = std::string,
    class BooleanType = bool,
    class NumberIntegerType = std::int64_t,
    class NumberUnsignedType = std::uint64_t,
    class NumberFloatType = double,
    template<typename U> class AllocatorType = std::allocator,
    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer
    >
struct policy_base {
    using object_t = ...;
    using array_t = ...;
    // ...

    using json_value = ... /* union definition */;
    using parser = ...;

    // ... whatever accessors are needed to complete the abstraction
};

struct default_policy : policy_base<> {};

It would take a bit of work to get basic_json refactored in terms of the policy, and to figure out exactly what should go in each part. But I think this could make the design a bit cleaner in that it turns basic_json into the interface-glue that makes the type easy to use, and the policy object becomes the low-level details that provide a nice customization point.

The kinds of customizations that this could enable:

  • allow the union to be extended to support user types (for example, std::shared_ptr<json>, or std::unique_ptr<LazyJsonLoader> that only deserializes a sub-object if it gets used, or to allow EmployeeRecord to be placed directly in the union and serialized inline, but also provide conversion-operators like other types)
  • maybe the parser could be extended to support non-conforming extensions (like trailing comma); I support that this library doesnt support this out of the box, but it would be nice if it was doable without too much work. (I have not looked at the parser, so maybe this is not even remotely possible right now).

Anyway, I just wanted to throw the idea out there to get feedback.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind: enhancement/improvementstate: please discussplease discuss the issue or vote for your favorite optionstate: stalethe issue has not been updated in a while and will be closed automatically soon unless it is updated

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions