The JSON output from different Server APIs can range from simple to highly nested and complex. The examples on this page attempt to illustrate how the JSON Data Set treats specific formats, and gives examples of the different constructor options that allow the user to tweak its behavior. See our JSON Primer for more information.
Example 1 - JSON Array with simple data types as elements.
Example 2 - JSON Array with objects as elements
Example 3 - JSON Object
Example 4 - The "path" constructor option.
Example 5 - The "path" constructor option and JSON Array with objects as elements.
Example 6 - The "subPaths" constructor option with a single path.
Example 7 - The "subPaths" constructor option with multiple paths.
Example 8 - "path" constructor option example.
Example 9 - Multiple matches for a single sub path.
Example 10 - Multiple matches for multiple sub paths.
Example 11 - The JSON Nested Data Set.
Example 12 - Sorting with the JSON Nested Data Set
Be sure to check out the "What's Not Supported" section.
Example 1
If the JSON data describes an array, and each element of that array is of a basic type (number, string, boolean, or null):
[ 100, 500, 300, 200, 400 ]
the JSON DataSet will create a row for each element in the JSON array, and store its value in a column named "column0".
var dsExample1 = new Spry.Data.JSONDataSet("../../data/json/array-01.js");
...
<divclass="liveSample"spry:region="dsExample1">
Values from array: <spanspry:repeatchildren="dsExample1">{column0} </span>
</div>
Here is a live example:
Values from array: 100 500 300 200 400
Example 2
If the JSON data describes an array, and each element of that array is an object:
[
{
color: "red",
value: "#f00"
},
{
color: "green",
value: "#0f0"
},
{
color: "blue",
value: "#00f"
},
{
color: "cyan",
value: "#0ff"
},
{
color: "magenta",
value: "#f0f"
},
{
color: "yellow",
value: "#ff0"
},
{
color: "black",
value: "#000"
}
]
the JSON Data Set will create a row for each object in the array, and each property on the object will become a column.
var dsExample2 = new Spry.Data.JSONDataSet("../../data/json/array-02.js");
...
<divclass="liveSample"spry:region="dsExample2">
Values from array: <spanspry:repeatchildren="dsExample2">{color}({value}) </span>
</div>
Here's a live example:
Values from array: red(#f00) green(#0f0) blue(#00f) cyan(#0ff) magenta(#f0f) yellow(#ff0) black(#000)
Example 3
If the JSON data describes an object:
{
color: "red",
value: "#f00"
}
the JSON Data Set will create a single row for the object, and each property on the object will become a column. The data set will only contain one row of data.
var dsExample3 = new Spry.Data.JSONDataSet("../../data/json/array-03.js");
...
<divclass="liveSample"spry:region="dsExample3">
Values from object: {color}({value})
</div>
Here is a live example:
Values from object: red(#f00)
Example 4
The objects returned from most Server APIs are highly nested:
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
If the data you want to extract out is not at the top-level of the JSON object, you can tell the JSON data set where to find it by using the "path" constructor option. In this example, we want to extract out all of the "batter" data:
var dsExample4 = new Spry.Data.JSONDataSet("../../data/json/object-02.js", { path: "batters.batter" });
...
<divclass="liveSample"spry:region="dsExample4">
<p>Batters:</p>
<ul>
<lispry:repeat="dsExample4">{type} ({id})</li>
</ul>
</div>
The path is simply the set of properties used to traverse the object's structure, separated by dots. Here's a live example:
Batters:
Regular (1001)
Chocolate (1002)
Blueberry (1003)
Devil's Food (1004)
Example 5
In the case where you have an array of highly nested objects:
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
{
"id": "0002",
"type": "donut",
"name": "Raised",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
{
"id": "0003",
"type": "donut",
"name": "Old Fashioned",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
]
the JSON data set uses the "path" constructor option to extract the matching data out from each object in the array. Each match then becomes a row in the data set. In this example, we want the data set to select all of the "batter" objects and flatten them into rows:
var dsExample5 = new Spry.Data.JSONDataSet("../../data/json/array-03.js", { path: "batters.batter" });
...
<divclass="liveSample"spry:region="dsExample5">
<p>Batters:</p>
<ul>
<lispry:repeat="dsExample5">{type} ({id})</li>
</ul>
</div>
Here's a live example:
Batters:
Regular (1001)
Chocolate (1002)
Blueberry (1003)
Devil's Food (1004)
Regular (1001)
Regular (1001)
Chocolate (1002)
Example 6
Some JSON formats use nested structures to simply group data together. An example of this would be the "image" and "thumbnail" properties in the following example:
{
"id": "0001",
"type": "donut",
"name": "Cake",
"image":
{
"url": "images/0001.jpg",
"width": 200,
"height": 200
},
"thumbnail":
{
"url": "images/thumbnails/0001.jpg",
"width": 32,
"height": 32
}
}
It is sometimes desirable to flatten these structures so they are also available as columns in the data set. You can use the "subPaths" constructor option to tell the JSON Data Set to include these nested structures when it flattens the top-level JSON object, or the data selected by the "path" constructor option. In this particular example, because we have not specified a "path" constructor option, the JSON data set will attempt to flatten the top-level object. Since we want to also include the data from the "image" nested structure, we specify the path to the data which is simply "image".
var dsExample6 = new Spry.Data.JSONDataSet("../../data/json/object-03.js", { subPaths: "image" });
...
<divclass="liveSample"spry:region="dsExample6">
<tableclass="dataTable">
<tr>
<th>id</th>
<th>type</th>
<th>name</th>
<th>image.width</th>
<th>image.height</th>
<th>image.url</th>
</tr>
<tr>
<td>{id}</td>
<td>{type}</td>
<td>{name}</td>
<td>{image.width}</td>
<td>{image.height}</td>
<td>{image.url}</td>
</tr>
</table>
</div>
The properties within the nested "image" structure are now accessible from within the data set. Notice that the names of the columns are all prefixed by "image.". Here's a live example:
id type name image.width image.height image.url
0001 donut Cake 200 200 images/0001.jpg
Example 7
You can specify multiple paths in the "subPaths" constructor option. So if you wanted to include both "image" and "thumbnail" in the flattening process, you simply pass an array of strings:
var dsExample7 = new Spry.Data.JSONDataSet("../../data/json/object-03.js", { subPaths: [ "image", "thumbnail" ] });
...
<divclass="liveSample"spry:region="dsExample7">
<tableclass="dataTable">
<tr>
<th>id</th>
<th>type</th>
<th>name</th>
<th>image.width</th>
<th>image.height</th>
<th>image.url</th>
<th>thumbnail.width</th>
<th>thumbnail.height</th>
<th>thumbnail.url</th>
</tr>
<tr>
<td>{id}</td>
<td>{type}</td>
<td>{name}</td>
<td>{image.width}</td>
<td>{image.height}</td>
<td>{image.url}</td>
<td>{thumbnail.width}</td>
<td>{thumbnail.height}</td>
<td>{thumbnail.url}</td>
</tr>
</table>
</div>
Here is a live example:
id type name image.width image.height image.url thumbnail.width thumbnail.height thumbnail.url
This example shows the use of the "path" constructor option to extract out the data items. This is nothing different from some of the previous examples, but we will build on this in the next example. An abbreviated version of the JSON data is included here for reference. You can see the full JSON data used by this example here.
{
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
...
]
}
}
In this example, we are simply going to list the types of items in our JSON object. We are going to use the "path" constructor option to select out all of the "item" objects, and then display the info we get in a table:
var dsExample8 = new Spry.Data.JSONDataSet("../../data/json/donuts.js", { path: "items.item" });
...
<divclass="liveSample"spry:region="dsExample8">
<tableclass="dataTable">
<tr>
<thspry:sort="id">id</th>
<thspry:sort="type">type</th>
<thspry:sort="name">name</th>
</tr>
<trspry:repeat="dsExample8">
<td>{id}</td>
<td>{type}</td>
<td>{name}</td>
</tr>
</table>
</div>
Using the path "items.item" will result in a data set that has the following columns defined for each row:
ds_RowID id type name ppu
Here is a live example:
id type name
0001 donut Cake
0002 donut Raised
0003 donut Old Fashioned
0004 bar Bar
0005 twist Twist
0006 filled Filled
Example 9
This example builds on Example 8 to show what happens when you select a set of repeating structures with the "subPaths" constructor option.
{
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
...
]
}
}
In this example, we are going to also select the "batter" objects with our "subPaths" constructor option, then display all of our data set rows in a table.
var dsExample9 = new Spry.Data.JSONDataSet("../../data/json/donuts.js", { path: "items.item", subPaths: "batters.batter" });
...
<divclass="liveSample"spry:region="dsExample9">
<tableclass="dataTable">
<tr>
<thspry:sort="id">id</th>
<thspry:sort="type">type</th>
<thspry:sort="name">name</th>
<thspry:sort="batters.batter.type">batter</th>
</tr>
<trspry:repeat="dsExample9">
<td>{id}</td>
<td>{type}</td>
<td>{name}</td>
<td>{batters.batter.type}</td>
</tr>
</table>
</div>
Using the path "items.item" and subPath "batters.batter" will result in a data set that has the following columns defined for each row:
ds_RowID id type name ppu batters.batter.id batters.batter.type
Here is a live example:
id type name batter
0001 donut Cake Regular
0001 donut Cake Chocolate
0001 donut Cake Blueberry
0001 donut Cake Devil's Food
0002 donut Raised Regular
0003 donut Old Fashioned Regular
0003 donut Old Fashioned Chocolate
0004 bar Bar Regular
0005 twist Twist Regular
0006 filled Filled Regular
If you compare the results above against what you see in Example 8, the first thing you will notice is that we now have more rows then we used to. What is basically happening here is that each top-level object matched by the "path" constructor option is merged with any objects that were matched by the paths in the "subPaths" constructor option. If more than one object is matched below a given top-level object, a row is created for every object matched so that its data can be accommodated.
Example 10
This example builds on Example 9 to show what happens when you select another set of repeating structures with the "subPaths" constructor option.
9{
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
...
]
}
}
In this example, we are going to also select the "topping" objects with our "subPaths" constructor option, then display all of our data set rows in a table.
var dsExample10 = new Spry.Data.JSONDataSet("../../data/json/donuts.js", { path: "items.item", subPaths: [ "batters.batter", "topping" ] });
...
<divclass="liveSample"spry:region="dsExample10">
<tableclass="dataTable">
<tr>
<thspry:sort="id">id</th>
<thspry:sort="type">type</th>
<thspry:sort="name">name</th>
<thspry:sort="batters.batter.type">batter</th>
<thspry:sort="topping.type">topping</th>
</tr>
<trspry:repeat="dsExample10">
<td>{id}</td>
<td>{type}</td>
<td>{name}</td>
<td>{batters.batter.type}</td>
<td>{topping.type}</td>
</tr>
</table>
</div>
Using the path "items.item" and sub paths "batters.batter" and "topping", will result in a data set that has the following columns defined for each row:
ds_RowID id type name ppu batters.batter.id batters.batter.type topping.id topping.type
Here is a live example:
id type name batter topping
0001 donut Cake Regular None
0001 donut Cake Regular Glazed
0001 donut Cake Regular Sugar
0001 donut Cake Regular Powdered Sugar
0001 donut Cake Regular Chocolate with Sprinkles
0001 donut Cake Regular Chocolate
0001 donut Cake Regular Maple
0001 donut Cake Chocolate None
0001 donut Cake Chocolate Glazed
0001 donut Cake Chocolate Sugar
0001 donut Cake Chocolate Powdered Sugar
0001 donut Cake Chocolate Chocolate with Sprinkles
0001 donut Cake Chocolate Chocolate
0001 donut Cake Chocolate Maple
0001 donut Cake Blueberry None
0001 donut Cake Blueberry Glazed
0001 donut Cake Blueberry Sugar
0001 donut Cake Blueberry Powdered Sugar
0001 donut Cake Blueberry Chocolate with Sprinkles
0001 donut Cake Blueberry Chocolate
0001 donut Cake Blueberry Maple
0001 donut Cake Devil's Food None
0001 donut Cake Devil's Food Glazed
0001 donut Cake Devil's Food Sugar
0001 donut Cake Devil's Food Powdered Sugar
0001 donut Cake Devil's Food Chocolate with Sprinkles
0001 donut Cake Devil's Food Chocolate
0001 donut Cake Devil's Food Maple
0002 donut Raised Regular None
0002 donut Raised Regular Glazed
0002 donut Raised Regular Sugar
0002 donut Raised Regular Chocolate
0002 donut Raised Regular Maple
0003 donut Old Fashioned Regular None
0003 donut Old Fashioned Regular Glazed
0003 donut Old Fashioned Regular Chocolate
0003 donut Old Fashioned Regular Maple
0003 donut Old Fashioned Chocolate None
0003 donut Old Fashioned Chocolate Glazed
0003 donut Old Fashioned Chocolate Chocolate
0003 donut Old Fashioned Chocolate Maple
0004 bar Bar Regular Chocolate
0004 bar Bar Regular Maple
0005 twist Twist Regular Glazed
0005 twist Twist Regular Sugar
0006 filled Filled Regular Glazed
0006 filled Filled Regular Powdered Sugar
0006 filled Filled Regular Chocolate
0006 filled Filled Regular Maple
We get even more rows than we had in Example 9 because the "topping" path also selected multiple objects in some cases. So for every top-level object matched by the "paths" constructor option, we get 'm*n' rows, where 'm' is the number of matches by the "batters.batter" sub path, and 'n' is the number of matches by the "topping" sub path.
Example 11 - Nested JSON Data Sets
Sometimes you want to work with nested structures, but you don't want to deal with the explosion of rows as shown in Example 10. Imagine you want to show a list of the different types of items, and under each item, you also want to list the different types of batters and toppings available. Doing that with the data set used in Example 10 would require some JavaScript logic embedded in spry attribute conditionals to control when things showed up. A simpler approach would be to use NestedJSONDataSets.
In this example we use the same JSON data used in Example 10, but we will use 2 nested JSON data sets to track the "batter" and "topping" data. Nested data sets are special data sets that stay in sync with the current row of their parent data set. As the current row of the parent data set changes, so does the data inside of the nested data set.
var dsExample11_Items = new Spry.Data.JSONDataSet("../../data/json/donuts.js", { path: "items.item" });
var dsExample11_Batters = new Spry.Data.NestedJSONDataSet(dsExample11_Items, "batters.batter");
var dsExample11_Toppings = new Spry.Data.NestedJSONDataSet(dsExample11_Items, "topping");
The other interesting thing about nested data sets is that if their parent data set is used in a spry:repeat or spry:repeatchildren context, any data references from the nested data set are kept in sync with whatever the current row is that is being processed by the loop.
Here is a live example.
Cake
Batters:
Regular
Chocolate
Blueberry
Devil's Food
Toppings:
None
Glazed
Sugar
Powdered Sugar
Chocolate with Sprinkles
Chocolate
Maple
Raised
Batters:
Regular
Toppings:
None
Glazed
Sugar
Chocolate
Maple
Old Fashioned
Batters:
Regular
Chocolate
Toppings:
None
Glazed
Chocolate
Maple
Bar
Batters:
Regular
Toppings:
Chocolate
Maple
Twist
Batters:
Regular
Toppings:
Glazed
Sugar
Filled
Batters:
Regular
Toppings:
Glazed
Powdered Sugar
Chocolate
Maple
Example 12
Although you can use nested data sets to produce a table that looks like the one in Example 9, there's an important difference. Nested data sets can only sort and filter within groups constrained by the parent's row it is associated with. It is easier to illustrate this with an example. In this example, we have a table that looks like the one in Example 9 on the left side, and on the right side, we have the same data presented as a set of nested lists.
var dsExample12_Items = new Spry.Data.JSONDataSet("../../data/json/donuts.js", { path: "items.item" });
var dsExample12_Batters = new Spry.Data.NestedJSONDataSet(dsExample12_Items, "batters.batter");
Notice that when you sort any column associated with the parent data set, all of the rows in the table shift around, whereas when you click on the batter column, it seems as if only the data in the batter column is moving around. If you look at what happens in the list on the right as you sort, it becomes more apparent what is happening.
What is not yet supported:
Arrays of arrays.
Arrays that contain elements of different types. Example: [ 100, { "foo": "bar" }, true, null ][JSON for Modern C++](https://raw.githubusercontent.com/nlohmann/json/master/doc/json.gif)](https://github.com/nlohmann/json/releases)
[](https://isitmaintained.com/project/nlohmann/json "Average time to resolve an issue")
- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you'll know what I mean.
- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.
- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](https://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs.
- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set.
[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add
You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.
You can also use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.
#### External
To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:
To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:
:beer: If you are using OS X and [Homebrew](https://brew.sh), just type `brew tap nlohmann/json` and `brew install nlohmann-json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann-json --HEAD`.
If you are using the [Meson Build System](https://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging.
The provided meson.build can also be used as an alternative to cmake for installing `nlohmann_json` system-wide in which case a pkg-config file is installed. To use it, simply have your build system require the `nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than using the subproject directly.
If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `nlohmann_json/x.y.z` to your `conanfile`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/conan-io/conan-center-index/issues) if you experience problems with the packages.
If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging.
If you are using [hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging.
If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. Please file issues [here](https://github.com/buckaroo-pm/nlohmann-json). There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example).
If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can use the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json). Please see the vcpkg project for any issues regarding the packaging.
If you are using [cget](https://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).
If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).
If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please files issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues).
If you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues).
If you are using [MSYS2](https://www.msys2.org/), your can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages.
If you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository https://cppget.org or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml).
If you are using [`wsjcpp`](https://wsjcpp.org), you can use the command `wsjcpp install "https://github.com/nlohmann/json:develop"` to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch.
If you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), you can check this [`example`](https://github.com/TheLartians/CPM.cmake/tree/master/examples/json). After [adding CPM script](https://github.com/TheLartians/CPM.cmake#adding-cpm) to your project, implement the following snippet to your CMake:
Beside the examples below, you may want to check the [documentation](https://nlohmann.github.io/json/) where each function contains a separate code example (e.g., check out [`emplace()`](https://nlohmann.github.io/json/api/basic_json/emplace/)). All [example files](https://github.com/nlohmann/json/tree/develop/doc/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/doc/examples/emplace.cpp)).
Note that in all these cases, you never need to "tell" the compiler which JSON value type you want to use. If you want to be explicit or express some edge cases, the functions [`json::array()`](https://nlohmann.github.io/json/api/basic_json/array/) and [`json::object()`](https://nlohmann.github.io/json/api/basic_json/object/) will help:
Note that without appending the `_json` suffix, the passed string literal is not parsed, but just used as JSON string value. That is, `json j = "{ \"happy\": true, \"pi\": 3.141 }"` would just store the string `"{ "happy": true, "pi": 3.141 }"` rather than parsing the actual object.
Note the library only supports UTF-8. When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.
Please note that setting the exception bit for `failbit` is inappropriate for this use case. It will result in program termination due to the `noexcept` specifier in use.
You can also parse JSON from an iterator range; that is, from any container accessible by iterators whose `value_type` is an integral type of 1, 2 or 4 bytes, which will be interpreted as UTF-8, UTF-16 and UTF-32 respectively. For instance, a `std::vector<std::uint8_t>`, or a `std::list<std::uint16_t>`:
The return value of each function determines whether parsing should proceed.
To implement your own SAX handler, proceed as follows:
1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax<json>` as base class, but you can also use any class where the functions described above are implemented and public.
2. Create an object of your SAX interface class, e.g. `my_sax`.
3. Call `bool json::sax_parse(input, &my_sax)`; where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.
Note the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return a `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file [`json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp).
We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) requirement.
Any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON values (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends on how the elements are ordered in the respective STL container.
Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON values (see examples above) can be used to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container.
The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values. On top of this, **JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) allows to describe differences between two JSON values - effectively allowing patch and diff operations known from Unix.
The library supports **JSON Merge Patch** ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format. Instead of using JSON Pointer (see above) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified.
You can switch off implicit conversions by defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` before including the `json.hpp` header. When using CMake, you can also achieve this by setting the option `JSON_ImplicitConversions` to `OFF`.
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
* When using `get<your_type>()`, `your_type`**MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/api/basic_json/at/) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
If you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate.
There are two macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object:
-`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)` is to be defined inside of the namespace of the class/struct to create code for.
-`NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)` is to be defined inside of the class/struct to create code for. This macro can also access private members.
In both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members.
##### Examples
The `to_json`/`from_json` functions for the `person` struct above can be created with:
The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)).
This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`...
There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:
Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/test/src/unit-udt.cpp) in the test suite, to see a few examples.
By default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be undefined or a different enum value than was originally intended.
It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below:
The `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serialization code.
// undefined json value to enum (where the first map entry above is the default)
json jPi = 3.14;
assert(jPi.get<TaskState>() == TS_INVALID );
```
Just as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,
-`NLOHMANN_JSON_SERIALIZE_ENUM()` MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it and it will default to integer serialization.
- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.
Other Important points:
- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports[BSON](http://bsonspec.org) (Binary JSON), [CBOR](https://cbor.io) (Concise Binary Object Representation), [MessagePack](https://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors.
The library also supports binary types from BSON, CBOR (byte strings), and MessagePack (bin, ext, fixext). They are stored by default as `std::vector<std::uint8_t>` to be processed outside of the library.
```cpp
// CBOR byte string with payload 0xCAFE
std::vector<std::uint8_t> v = {0x42, 0xCA, 0xFE};
// read value
json j = json::from_cbor(v);
// the JSON value has type binary
j.is_binary(); // true
// get reference to stored binary value
auto& binary = j.get_binary();
// the binary value has no subtype (CBOR has no binary subtypes)
binary.has_subtype(); // false
// access std::vector<std::uint8_t> member functions
binary.size(); // 2
binary[0]; // 0xCA
binary[1]; // 0xFE
// set subtype to 0x10
binary.set_subtype(0x10);
// serialize to MessagePack
auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE
- GCC 4.8 has a bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)): multiline raw strings cannot be the arguments to macros. Don't use multiline raw strings directly in macros with this compiler.
- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.
The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10.
- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`) may occur. Note this is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](https://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219).
- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case.
The following compilers are currently used in continuous integration at [Travis](https://travis-ci.org/nlohmann/json), [AppVeyor](https://ci.appveyor.com/project/nlohmann/json), [GitHub Actions](https://github.com/nlohmann/json/actions), and [CircleCI](https://circleci.com/gh/nlohmann/json):
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
If you have questions regarding the library, I would like to invite you to [open an issue at GitHub](https://github.com/nlohmann/json/issues/new/choose). Please describe your request, problem, or question as detailed as possible, and also mention the version of the library you are using as well as the version of your compiler and operating system. Opening an issue at GitHub allows other users and contributors to this library to collaborate. For instance, I have little experience with MSVC, and most issues in this regard have been solved by a growing community. If you have a look at the [closed issues](https://github.com/nlohmann/json/issues?q=is%3Aissue+is%3Aclosed), you will see that we react quite timely in most cases.
Only if your request would contain confidential information, please [send me an email](mailto:mail@nlohmann.me). For encrypted messages, please use [this key](https://keybase.io/nlohmann/pgp_keys.asc).
[Commits by Niels Lohmann](https://github.com/nlohmann/json/commits) and [releases](https://github.com/nlohmann/json/releases) are signed with this [PGP Key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69).
- [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization.
- [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes.
- [kirkshoop](https://github.com/kirkshoop) made the iterators of the class composable to other libraries.
- [wancw](https://github.com/wanwc) fixed a bug that hindered the class to compile with Clang.
- Tomas Åblad found a bug in the iterator implementation.
- [Aaron Burghardt](https://github.com/aburgh) implemented code to parse streams incrementally. Furthermore, he greatly improved the parser class by allowing the definition of a filter function to discard undesired elements while parsing.
- [Eric Cornelius](https://github.com/EricMCornelius) pointed out a bug in the handling with NaN and infinity values. He also improved the performance of the string escaping.
- [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types.
- [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values.
- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers.
- [Théo DELRIEU](https://github.com/theodelrieu) patiently and constructively oversaw the long way toward [iterator-range parsing](https://github.com/nlohmann/json/issues/290). He also implemented the magic behind the serialization/deserialization of user-defined types and split the single header file into smaller chunks.
- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](https://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing.
- [Kert](https://github.com/kaidokert) allowed to template the string type in the serialization and added the possibility to override the exceptional behavior.
- [mark-99](https://github.com/mark-99) helped fixing an ICC error.
- [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration.
- [remyabel](https://github.com/remyabel) added GNUInstallDirs to the CMake files.
- [Taylor Howard](https://github.com/taylorhoward92) fixed a unit test.
- [Gabe Ron](https://github.com/Macr0Nerd) implemented the `to_string` method.
- [Watal M. Iwasaki](https://github.com/heavywatal) fixed a Clang warning.
- [Viktor Kirilov](https://github.com/onqtam) switched the unit tests from [Catch](https://github.com/philsquared/Catch) to [doctest](https://github.com/onqtam/doctest)
- [AODQ](https://github.com/AODQ) fixed a compiler warning.
- [jwittbrodt](https://github.com/jwittbrodt) made `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` inline.
- [pfeatherstone](https://github.com/pfeatherstone) improved the upper bound of arguments of the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.
- [Jan Procházka](https://github.com/jprochazk) fixed a bug in the CBOR parser for binary and string values.
- [T0b1-iOS](https://github.com/T0b1-iOS) fixed a bug in the new hash implementation.
- [Matthew Bauer](https://github.com/matthewbauer) adjusted the CBOR writer to create tags for binary subtypes.
- [gatopeich](https://github.com/gatopeich) implemented an ordered map container for `nlohmann::ordered_json`.
- [Érico Nogueira Rolim](https://github.com/ericonr) added support for pkg-config.
- [KonanM](https://github.com/KonanM) proposed an implementation for the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.
- [Guillaume Racicot](https://github.com/gracicot) implemented `string_view` support and allowed C++20 support.
- [Alex Reinking](https://github.com/alexreinking) improved CMake support for `FetchContent`.
The library itself consists of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot!
- [**GitHub Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md)
- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json))
- [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments.
- [**send_to_wandbox**](https://github.com/nlohmann/json/blob/develop/doc/scripts/send_to_wandbox.py) to send code examples to [Wandbox](http://melpon.org/wandbox)
- [**Travis**](https://travis-ci.org) for [continuous integration](https://travis-ci.org/nlohmann/json) on Linux and macOS
The library is currently used in Apple macOS Sierra and iOS 10. I am not sure what they are using the library for, but I am happy that it runs on so many devices.
The library supports **Unicode input** as follows:
- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1).
-`std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers.
- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors.
- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors.
- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.
- When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.
1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript.
2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012:
> I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't.
> Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.
3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this.
However, you can pass set parameter `ignore_comments` to true in the `parse` function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace.
By default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs".
If you do want to preserve the insertion order, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179). Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)).
If you find that a parsing program with this library does not release memory, please consider the following case and it maybe unrelated to this library.
**Your program is compiled with glibc.** There is a tunable threshold that glibc uses to decide whether to actually return memory to the system or whether to cache it for later reuse. If in your program you make lots of small allocations and those small allocations are not a contiguous block and are presumably below the threshold, then they will not get returned to the OS.
- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](https://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/api/basic_json/operator%5B%5D/) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/api/basic_json/at/). Furthermore, you can define `JSON_ASSERT(x)` to replace calls to `assert(x)`.
- As the exact type of a number is not defined in the [JSON specification](https://tools.ietf.org/html/rfc8259.html), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions.
- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
Note that during the `ctest` stage, several JSON test files are downloaded from an [external repository](https://github.com/nlohmann/json_test_data). If policies forbid downloading artifacts during testing, you can download the files yourself and pass the directory with the test files via `-DJSON_TestDataDirectory=path` to CMake. Then, no Internet connectivity is required. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.
In case you have downloaded the library rather than checked out the code via Git, test `cmake_fetch_content_configure`. Please execute `ctest -LE git_required` to skip these tests. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.
Some tests change the installed files and hence make the whole process not reproducible. Please execute `ctest -LE not_reproducible` to skip these tests. See [issue #2324](https://github.com/nlohmann/json/issues/2324) for more information.
Note you need to call `cmake -LE "not_reproducible|git_required"` to exclude both labels. See [issue #2596](https://github.com/nlohmann/json/issues/2596) for more information.
As Intel compilers use unsafe floating point optimization by default, the unit tests may fail. Use flag [`/fp:precise`](https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/floating-point-options/fp-model-fp.html) then.