SkillAgentSearch skills...

Minjsoncpp

Minimalistic JSON C++ library

Install / Use

/learn @toughengineer/Minjsoncpp
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Minimalistic JSON C++ library

minjsoncpp is a minimalistic C++17 header-only library that implements facilities to programmatically manipulate, serialize/stringify and parse JSON data as defined by RFC 8259 The JavaScript Object Notation (JSON) Data Interchange Format.

The goals of this project (from the highest priority to the lowest):

  1. strictly conform to JSON specification,
  2. minimal footprint (source size, binary size, etc.),
  3. reasonable performance.

As such the code is only 1500 lines, no dependencies except for the C++ standard library, yet it follows the spec very closely and has reasonably good performance compared to popular JSON C++ libraries.

It is primarily intended for situations when you want to read a small JSON file, a config file for example, or to write a small JSON file, but don't want to deal with huge and/or complicated dependencies because of that small part where you need such functionality.

Supported compilers and standard libraries

Compilers:

  • GCC: 11.1 and later*
  • Clang: 8 (with libstdc++ 11.1..12.3) and later (with respectively supported versions of standard library)
  • MSVC: 19.16 (comes with Visual Studio 2017 version 15.9.11) and later

Standard libraries:

  • libstdc++: 11.1 and later*
    (goes with GCC, can be used with Clang)
  • libc++: 14 and later**
    (goes with Clang)
  • MSVC: the one that comes with Visual Studio 2017 version 15.9.11 and later
    (can be used with Clang on Windows)

*Since the earliest supported version of libstdc++ is 11.1 that's the corresponding earliest supported version of GCC because they (typically) come together.
**libc++ until version 20.1 does not implement std::from_chars() for double; strtod() is used instead when building with libc++.

In general you should be able to use it with any fully C++17 conformant compiler and standard library.

How to acquire the library

The easiest way is to put the header file minjsoncpp.h or copy-paste its contents into your project.

Cloning repo/using submodule

You can clone the repo https://github.com/toughengineer/minjsoncpp.git, or add it as a submodule.

<details><summary>Click/tap to expand details.</summary>
git submodule add https://github.com/toughengineer/minjsoncpp.git

or

git submodule add https://github.com/toughengineer/minjsoncpp.git thirdparty/minjsoncpp

to specify destination directory, in this case thirdparty/minjsoncpp,
and then initialize it with

git submodule update --init

In your CMakeLists.txt you can just add include directory with something like this:

include_directories("thirdparty/minjsoncpp/include")

Or you can add include directory for a particular CMake target (${TARGET_NAME} in this case):

target_include_directories(${TARGET_NAME} PRIVATE "thirdparty/minjsoncpp/include")

In this case you don't need to explicitly add dependencies to the targets.

Instead of explicitly adding include directory you can add a dependency to your CMake target:

target_link_libraries(${TARGET_NAME} minjsoncpp)

add_subdirectory("thirdparty/minjsoncpp")

target_link_libraries adds dependency to a target and makes include file available.

add_subdirectory processes minjsoncpp's CMakeLists.txt and adds minjsoncpp target for consumption.

</details>

Using CMake FetchContent

You can use FetchContent to get the library via CMakeLists.txt:

include(FetchContent)

FetchContent_Declare(
  minjsoncpp
  GIT_REPOSITORY https://github.com/toughengineer/minjsoncpp.git
  GIT_TAG main
  GIT_SHALLOW TRUE
)

FetchContent_MakeAvailable(minjsoncpp)

For your CMake target add:

target_link_libraries(${TARGET_NAME} minjsoncpp)

where ${TARGET_NAME} is the name of a CMake target like an executable or a library.

API

It is relatively straightforward.

You can jump straight to examples if you want to see how it can be used.

This library assumes UTF-8 encoding of strings inside JSON values, of inputs that are parsed, and of serialized/stringified JSON representation prescribed by RFC 8259 section 8.1.

Entities in the namespace minjson are all public and can be used freely.

Entities in the namespace minjson::impl are also public, but should be seen as "advanced" API intended to expose the full functionality without conveniently defined defaults.

Entities in the namespace minjson::detail are implementation details, you should not use them explicitly.

JSON values

JSON value is represented as template minjson::BasicValue<Allocator> with allocator parameter.

minjson::Value is defined for covenience as an alias to minjson::BasicValue<std::allocator<char>>. See section about allocator support below for details.

By convention minjson::BasicValue is parameterized with an allocator type for char elements.

Assuming minjson::Value, mapping of JSON value types to C++ types is as follows:

| JSON | C++ | |-------|-----| |null |minjson::Null (alias for std::monostate)| |boolean|minjson::Boolean (alias for bool)| |number |int64_t for integers,<br>double for decimal numbers| |string |minjson::String (alias for std::string, assumed to contain UTF-8 text)| |array |minjson::Array (alias for std::vector<minjson::Value>)| |object |minjson::Object (alias for std::unordered_map<minjson::String, minjson::Value>)|

Concrete value is stored in a variant defined as:

using Variant = std::variant<Null, Boolean, int64_t, double, String, Array, Object>;

minjson::Value provides access to it via variant() method and can be implicitly converted to a reference to minjson::Variant.

visit() functionality

You can std::visit() the underlying variant as usual, e.g.:

minjson::Value value = foo();
std::visit([](auto &x) { bar(x); }, value.variant());

or use minjson::visit() function directly on a minjson::Value instance:

minjson::Value value = foo();
minjson::visit([](auto &x) { bar(x); }, value);

or you can omit the namespace and rely on ADL:

minjson::Value value = foo();
visit([](auto &x) { bar(x); }, value);

See example in visit.cpp.

Value type inspection

You can explicitly check the type of a value and access the underlying object by using the following methods:

| check type | access value | |------------|--------------| |isNull() | |isBool() |asBool()| |isInt() |asInt()| |isDouble()|asDouble()| |isString()|asString()| |isArray() |asArray()| |isObject()|asObject()|

Initialization

You can construct minjson::Value in the usual way, e.g.:

minjson::Value null = minjson::Null{};
minjson::Value boolean = true;
minjson::Value integer = 42;
minjson::Value decimal = 3.14;
minjson::Value string = "hello";
minjson::Value array = minjson::Array{ 1, 2, 3 };
minjson::Value object = minjson::Object{ { "foo", 42 }, { "bar", "baz" } };

You can combine it any way you want, e.g.:

const minjson::Value value = minjson::Object{
  { "null", minjson::Null{} },
  { "boolean", true },
  { "integer", 42 },
  { "decimal", 3.14 },
  { "string", "hello there"sv },
  { "array", minjson::Array{ 1, 2, 3 } },
  { "object", minjson::Object{
      { "nested number", 23 },
      { "nested string", "General Kenobi"sv },
      { "nested array", minjson::Array{ 4, 5, 6 } },
      { "nested object", minjson::Object{ { "foo", "bar"sv } } }
    }
  }
};

Accessing values throughout JSON document

To access values within the JSON document throughout multiple levels you can use resolve() method which returns a pointer to a value (const minjson::Value*, can be nullptr if resolution fails).

Below are some examples of usage.

minjson::Value o = minjson::Object{ { "foo", 42 }, { "bar", "baz" } };

const auto *foo = o.resolve("foo");
if (foo) {
  // use '*foo'
}

In this case, string key argument "foo" implies that we expect o to contain an object and we are trying to get member value designated by the corresponding key.

minjson::Value a = minjson::Array{ 1, 2, 3 };

const auto *item = a.resolve(0);
if (item) {
  // use '*item'
}

Here numeric index argument 0 implies that we expect a to contain an array and we are trying to get member value with the corresponding index.

You can provide multiple arguments to resolve values throughout multiple levels, which would be similar to arguments being tokens of a JSON Pointer string, e.g.

const minjson::Value value = minjson::Object{
  { "object", minjson::Object{
      { "nested array", minjson::Array{ 4, 5, 6 } }
    }
  }
};

const auto *item = value.resolve("object", "nested array", 0);
if (item) {
  // use '*item'
}

In this case

  • string key argument "object" implies that we expect value to contain an object and we are trying to get member value designated by that key,
  • in turn, string key argument "nested array" implies that we expect the value that we get from the previous step to be an object and we are trying to get member value designated by this key,
  • finally, numeric index argument 0 implies that we expect the value that we get from the previous step (the "nested array" one) to contain an array and we are trying to get member value with that index.

This would be similar to trying to resolve JSON Pointer /object/nested array/1.

See more examples in resolve.cpp.

Sinks

Function templates in namespace minjson::impl receive "sinks": objects with implemented operator() or functions that can receive instances of std::string_view as subsequent parts of the result.

E.g. it c

View on GitHub
GitHub Stars10
CategoryDevelopment
Updated22d ago
Forks1

Languages

C++

Security Score

95/100

Audited on Mar 5, 2026

No findings