README.md 91.8 KB
Newer Older
Niels's avatar
Niels committed
1
[![JSON for Modern C++](https://raw.githubusercontent.com/nlohmann/json/master/doc/json.gif)](https://github.com/nlohmann/json/releases)
Niels's avatar
Niels committed
2

Niels's avatar
Niels committed
3
[![Build Status](https://travis-ci.org/nlohmann/json.svg?branch=master)](https://travis-ci.org/nlohmann/json)
4
[![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json)
5
6
7
[![Ubuntu](https://github.com/nlohmann/json/workflows/Ubuntu/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AUbuntu)
[![macOS](https://github.com/nlohmann/json/workflows/macOS/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AmacOS)
[![Windows](https://github.com/nlohmann/json/workflows/Windows/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AWindows)
Niels Lohmann's avatar
Niels Lohmann committed
8
[![Coverage Status](https://coveralls.io/repos/github/nlohmann/json/badge.svg?branch=develop)](https://coveralls.io/github/nlohmann/json?branch=develop)
9
[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
10
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade)
Niels Lohmann's avatar
Niels Lohmann committed
11
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/nlohmann/json.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/nlohmann/json/context:cpp)
12
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/json.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json)
13
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/3lCHrFUZANONKv7a)
Niels Lohmann's avatar
Niels Lohmann committed
14
[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](https://nlohmann.github.io/json/doxygen/index.html)
Niels's avatar
Niels committed
15
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
16
[![GitHub Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases)
Niels Lohmann's avatar
Niels Lohmann committed
17
[![GitHub Downloads](https://img.shields.io/github/downloads/nlohmann/json/total)](https://github.com/nlohmann/json/releases)
TotalCaesar659's avatar
TotalCaesar659 committed
18
19
[![GitHub Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](https://github.com/nlohmann/json/issues)
[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/nlohmann/json.svg)](https://isitmaintained.com/project/nlohmann/json "Average time to resolve an issue")
20
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/289/badge)](https://bestpractices.coreinfrastructure.org/projects/289)
Niels Lohmann's avatar
Niels Lohmann committed
21
[![GitHub Sponsors](https://img.shields.io/badge/GitHub-Sponsors-ff69b4)](https://github.com/sponsors/nlohmann)
Carlos Gomes Martinho's avatar
Carlos Gomes Martinho committed
22

23
- [Design goals](#design-goals)
Niels Lohmann's avatar
Niels Lohmann committed
24
- [Sponsors](#sponsors)
25
- [Integration](#integration)
26
27
  - [CMake](#cmake)
  - [Package Managers](#package-managers)
28
  - [Pkg-config](#pkg-config)
29
30
31
32
33
34
- [Examples](#examples)
  - [JSON as first-class data type](#json-as-first-class-data-type)
  - [Serialization / Deserialization](#serialization--deserialization)
  - [STL-like access](#stl-like-access)
  - [Conversion from STL containers](#conversion-from-stl-containers)
  - [JSON Pointer and JSON Patch](#json-pointer-and-json-patch)
35
  - [JSON Merge Patch](#json-merge-patch)
36
  - [Implicit conversions](#implicit-conversions)
Niels Lohmann's avatar
Niels Lohmann committed
37
  - [Conversions to/from arbitrary types](#arbitrary-types-conversions)
38
  - [Specializing enum conversion](#specializing-enum-conversion)
39
  - [Binary formats (BSON, CBOR, MessagePack, and UBJSON)](#binary-formats-bson-cbor-messagepack-and-ubjson)
40
41
- [Supported compilers](#supported-compilers)
- [License](#license)
42
- [Contact](#contact)
43
- [Thanks](#thanks)
44
- [Used third-party tools](#used-third-party-tools)
45
- [Projects using JSON for Modern C++](#projects-using-json-for-modern-c)
46
47
48
- [Notes](#notes)
- [Execute unit tests](#execute-unit-tests)

Niels's avatar
Niels committed
49
50
## Design goals

Antoine Cœur's avatar
Antoine Cœur committed
51
There are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals:
Niels's avatar
Niels committed
52

53
- **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.
Niels's avatar
Niels committed
54

55
- **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.
Niels's avatar
Niels committed
56

TotalCaesar659's avatar
TotalCaesar659 committed
57
- **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).
Niels's avatar
Niels committed
58
59
60

Other aspects were not so important to us:

Niels's avatar
Niels committed
61
- **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.
Niels's avatar
Niels committed
62

Niels Lohmann's avatar
Niels Lohmann committed
63
- **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.
Niels's avatar
Niels committed
64

Niels's avatar
cleanup    
Niels committed
65
See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information.
Niels's avatar
Niels committed
66

Niels's avatar
Niels committed
67

Niels Lohmann's avatar
Niels Lohmann committed
68
69
70
71
72
73
74
## Sponsors

You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann).

### :label: Named Sponsors

- [Michael Hartmann](https://github.com/reFX-Mike)
Niels Lohmann's avatar
Niels Lohmann committed
75
- [Stefan Hagen](https://github.com/sthagen)
Niels Lohmann's avatar
Niels Lohmann committed
76
- [Steve Sperandeo](https://github.com/homer6)
Niels Lohmann's avatar
Niels Lohmann committed
77
- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe)
Niels Lohmann's avatar
Niels Lohmann committed
78
- [Steve Wagner](https://github.com/ciroque)
Niels Lohmann's avatar
Niels Lohmann committed
79
80
81
82

Thanks everyone!


Niels's avatar
Niels committed
83
84
## Integration

Niels Lohmann's avatar
Niels Lohmann committed
85
[`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
Niels's avatar
Niels committed
86
87

```cpp
Patrik Huber's avatar
Patrik Huber committed
88
#include <nlohmann/json.hpp>
Niels's avatar
Niels committed
89
90

// for convenience
91
using nlohmann::json;
Niels's avatar
Niels committed
92
93
```

Wilson's avatar
Wilson committed
94
to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
Niels's avatar
Niels committed
95

Wilson's avatar
Wilson committed
96
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`.
97

98
99
100
101
102
103
104
### CMake

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:
Niels Lohmann's avatar
Niels Lohmann committed
105

106
107
```cmake
# CMakeLists.txt
108
find_package(nlohmann_json 3.2.0 REQUIRED)
109
110
111
112
113
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
Niels Lohmann's avatar
Niels Lohmann committed
114

115
116
The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.

117
118
119
#### Embedded

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:
Niels Lohmann's avatar
Niels Lohmann committed
120

121
122
123
124
125
```cmake
# Typically you don't care so much for a third party library's tests to be
# run from your own project's code.
set(JSON_BuildTests OFF CACHE INTERNAL "")

126
127
128
129
# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
# set(JSON_Install OFF CACHE INTERNAL "")

130
# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
Mark Beckwith's avatar
Mark Beckwith committed
131
# unintended consequences that will break the build.  It's generally
132
133
134
135
136
137
138
139
140
# discouraged (although not necessarily well documented as such) to use
# include(...) for pulling in other CMake projects anyways.
add_subdirectory(nlohmann_json)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```

141
##### Embedded (FetchContent)
142

143
144
Since CMake v3.11,
[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
Morten Fyhn Amundsen's avatar
Morten Fyhn Amundsen committed
145
be used to automatically download the repository as a dependency at configure time.
146
147

Example:
148
```cmake
149
150
151
include(FetchContent)

FetchContent_Declare(json
152
  GIT_REPOSITORY https://github.com/nlohmann/json.git
153
154
155
156
157
158
159
160
161
  GIT_TAG v3.7.3)

FetchContent_GetProperties(json)
if(NOT json_POPULATED)
  FetchContent_Populate(json)
  add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()

target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
ArthurSonzogni's avatar
ArthurSonzogni committed
162
```
163
164
165

**Note**: The repository https://github.com/nlohmann/json download size is huge.
It contains all the dataset used for the benchmarks. You might want to depend on
166
a smaller repository. For instance, you might want to replace the URL above by
167
168
https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent

169
#### Supporting Both
Niels Lohmann's avatar
Niels Lohmann committed
170

171
To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:
Niels Lohmann's avatar
Niels Lohmann committed
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
``` cmake
# Top level CMakeLists.txt
project(FOO)
...
option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
...
add_subdirectory(thirdparty)
...
add_library(foo ...)
...
# Note that the namespaced target will always be available regardless of the
# import method
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
```
```cmake
# thirdparty/CMakeLists.txt
...
if(FOO_USE_EXTERNAL_JSON)
  find_package(nlohmann_json 3.2.0 REQUIRED)
else()
  set(JSON_BuildTests OFF CACHE INTERNAL "")
  add_subdirectory(nlohmann_json)
endif()
...
```
Niels Lohmann's avatar
Niels Lohmann committed
198

199
`thirdparty/nlohmann_json` is then a complete copy of this source tree.
200

201
202
### Package Managers

TotalCaesar659's avatar
TotalCaesar659 committed
203
: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`.
Niels's avatar
Niels committed
204

TotalCaesar659's avatar
TotalCaesar659 committed
205
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.
206
207

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.
Jay Sistar's avatar
Jay Sistar committed
208

offa's avatar
offa committed
209
If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add [`nlohmann_json/x.y.z`](https://conan.io/center/nlohmann_json) 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.
210

Niels Lohmann's avatar
Niels Lohmann committed
211
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.
Axel Huebl's avatar
Axel Huebl committed
212

jothepro's avatar
jothepro committed
213
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.
gregmarr's avatar
gregmarr committed
214

njlr's avatar
njlr committed
215
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).
216

gregmarr's avatar
gregmarr committed
217
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.
218

TotalCaesar659's avatar
TotalCaesar659 committed
219
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`).
220

221
222
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).

223
224
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).

225
226
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).

TotalCaesar659's avatar
TotalCaesar659 committed
227
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.
228

TotalCaesar659's avatar
TotalCaesar659 committed
229
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).
230
231
Please file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages.

TotalCaesar659's avatar
TotalCaesar659 committed
232
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.
233

leozz37's avatar
leozz37 committed
234
235
236
237
238
239
240
241
242
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:

```cmake
CPMAddPackage(
    NAME nlohmann_json
    GITHUB_REPOSITORY nlohmann/json
    VERSION 3.9.1)
```

243
244
245
246
247
248
249
250
251
252
253
254
255
256
### Pkg-config

If you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed:

```sh
pkg-config nlohmann_json --cflags
```

Users of the Meson build system will also be able to use a system wide library, which will be found by `pkg-config`:

```meson
json = dependency('nlohmann_json', required: true)
```

Niels's avatar
Niels committed
257
258
## Examples

259
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)).
260

261
262
### JSON as first-class data type

Niels's avatar
Niels committed
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
Here are some examples to give you an idea how to use the class.

Assume you want to create the JSON object

```json
{
  "pi": 3.141,
  "happy": true,
  "name": "Niels",
  "nothing": null,
  "answer": {
    "everything": 42
  },
  "list": [1, 0, 2],
  "object": {
    "currency": "USD",
    "value": 42.99
  }
}
```

Niels Lohmann's avatar
Niels Lohmann committed
284
With this library, you could write:
Niels's avatar
Niels committed
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

```cpp
// create an empty structure (null)
json j;

// add a number that is stored as double (note the implicit conversion of j to an object)
j["pi"] = 3.141;

// add a Boolean that is stored as bool
j["happy"] = true;

// add a string that is stored as std::string
j["name"] = "Niels";

// add another null object by passing nullptr
j["nothing"] = nullptr;

// add an object inside the object
j["answer"]["everything"] = 42;

// add an array that is stored as std::vector (using an initializer list)
j["list"] = { 1, 0, 2 };

// add another object (using an initializer list of pairs)
j["object"] = { {"currency", "USD"}, {"value", 42.99} };

// instead, you could also write (which looks very similar to the JSON above)
json j2 = {
  {"pi", 3.141},
  {"happy", true},
  {"name", "Niels"},
  {"nothing", nullptr},
  {"answer", {
    {"everything", 42}
  }},
  {"list", {1, 0, 2}},
  {"object", {
    {"currency", "USD"},
    {"value", 42.99}
  }}
};
```

328
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:
Niels's avatar
Niels committed
329
330

```cpp
Niels's avatar
Niels committed
331
// a way to express the empty array []
Niels's avatar
Niels committed
332
333
json empty_array_explicit = json::array();

Niels's avatar
Niels committed
334
335
// ways to express the empty object {}
json empty_object_implicit = json({});
Niels's avatar
Niels committed
336
337
338
json empty_object_explicit = json::object();

// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
339
json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
Niels's avatar
Niels committed
340
341
342
343
```

### Serialization / Deserialization

Niels Lohmann's avatar
Niels Lohmann committed
344
345
#### To/from strings

Niels Lohmann's avatar
Niels Lohmann committed
346
You can create a JSON value (deserialization) by appending `_json` to a string literal:
Niels's avatar
Niels committed
347
348
349
350
351

```cpp
// create object from string literal
json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;

Niels's avatar
Niels committed
352
// or even nicer with a raw string literal
Niels's avatar
Niels committed
353
354
355
356
357
358
auto j2 = R"(
  {
    "happy": true,
    "pi": 3.141
  }
)"_json;
359
360
```

Niels Lohmann's avatar
Niels Lohmann committed
361
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.
Niels's avatar
Niels committed
362

363
The above example can also be expressed explicitly using [`json::parse()`](https://nlohmann.github.io/json/api/basic_json/parse/):
364
365
366

```cpp
// parse explicitly
367
auto j3 = json::parse(R"({"happy": true, "pi": 3.141})");
Niels's avatar
Niels committed
368
369
```

Niels Lohmann's avatar
Niels Lohmann committed
370
You can also get a string representation of a JSON value (serialize):
Niels's avatar
Niels committed
371
372
373

```cpp
// explicit conversion to string
374
std::string s = j.dump();    // {"happy":true,"pi":3.141}
Niels's avatar
Niels committed
375
376
377
378
379
380
381
382
383
384

// serialization with pretty printing
// pass in the amount of spaces to indent
std::cout << j.dump(4) << std::endl;
// {
//     "happy": true,
//     "pi": 3.141
// }
```

385
386
387
388
389
390
Note the difference between serialization and assignment:

```cpp
// store a string in a JSON value
json j_string = "this is a string";

391
392
393
394
395
// retrieve the string value
auto cpp_string = j_string.get<std::string>();
// retrieve the string value (alternative when an variable already exists)
std::string cpp_string2;
j_string.get_to(cpp_string2);
396
397
398
399
400

// retrieve the serialized value (explicit JSON serialization)
std::string serialized_string = j_string.dump();

// output of original string
401
std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << '\n';
402
403
404
405
// output of serialized value
std::cout << j_string << " == " << serialized_string << std::endl;
```

406
[`.dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) returns the originally stored string value.
407

408
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.
409

Niels Lohmann's avatar
Niels Lohmann committed
410
411
#### To/from streams (e.g. files, string streams)

Niels's avatar
Niels committed
412
413
414
415
416
You can also use streams to serialize and deserialize:

```cpp
// deserialize from standard input
json j;
Niels's avatar
Niels committed
417
std::cin >> j;
Niels's avatar
Niels committed
418
419
420
421
422
423
424
425

// serialize to standard output
std::cout << j;

// the setw manipulator was overloaded to set the indentation for pretty printing
std::cout << std::setw(4) << j << std::endl;
```

Niels Lohmann's avatar
Niels Lohmann committed
426
427
428
429
430
431
432
433
434
435
436
437
These operators work for any subclasses of `std::istream` or `std::ostream`. Here is the same example with files:

```cpp
// read a JSON file
std::ifstream i("file.json");
json j;
i >> j;

// write prettified JSON to another file
std::ofstream o("pretty.json");
o << std::setw(4) << j << std::endl;
```
Niels's avatar
Niels committed
438

Kevin Dixon's avatar
Kevin Dixon committed
439
440
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.

Niels Lohmann's avatar
Niels Lohmann committed
441
442
#### Read from iterator range

Francois Chabot's avatar
Francois Chabot committed
443
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>`:
Niels Lohmann's avatar
Niels Lohmann committed
444
445

```cpp
446
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
Niels Lohmann's avatar
Niels Lohmann committed
447
448
449
450
451
452
json j = json::parse(v.begin(), v.end());
```

You may leave the iterators for the range [begin, end):

```cpp
453
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
Niels Lohmann's avatar
Niels Lohmann committed
454
455
456
json j = json::parse(v);
```

Francois Chabot's avatar
Francois Chabot committed
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
#### Custom data source

Since the parse function accepts arbitrary iterator ranges, you can provide your own data sources by implementing the `LegacyInputIterator` concept.

```cpp
struct MyContainer {
  void advance();
  const char& get_current();
};

struct MyIterator {
    using difference_type = std::ptrdiff_t;
    using value_type = char;
    using pointer = const char*;
    using reference = const char&;
    using iterator_category = std::input_iterator_tag;

    MyIterator& operator++() {
        MyContainer.advance();
Francois Chabot's avatar
Francois Chabot committed
476
        return *this;
Francois Chabot's avatar
Francois Chabot committed
477
478
479
    }

    bool operator!=(const MyIterator& rhs) const {
480
        return rhs.target != target;
Francois Chabot's avatar
Francois Chabot committed
481
482
483
484
485
486
487
488
489
490
    }

    reference operator*() const {
        return target.get_current();
    }

    MyContainer* target = nullptr;
};

MyIterator begin(MyContainer& tgt) {
491
    return MyIterator{&tgt};
Francois Chabot's avatar
Francois Chabot committed
492
493
494
}

MyIterator end(const MyContainer&) {
495
    return {};
Francois Chabot's avatar
Francois Chabot committed
496
497
498
499
500
501
502
503
}

void foo() {
    MyContainer c;
    json j = json::parse(c);
}
```

504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
#### SAX interface

The library uses a SAX-like interface with the following functions:

```cpp
// called when null is parsed
bool null();

// called when a boolean is parsed; value is passed
bool boolean(bool val);

// called when a signed or unsigned integer number is parsed; value is passed
bool number_integer(number_integer_t val);
bool number_unsigned(number_unsigned_t val);

// called when a floating-point number is parsed; value and original string is passed
bool number_float(number_float_t val, const string_t& s);

// called when a string is parsed; value is passed and can be safely moved away
bool string(string_t& val);
524
525
// called when a binary value is parsed; value is passed and can be safely moved away
bool binary(binary_t& val);
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)
bool start_object(std::size_t elements);
bool end_object();
bool start_array(std::size_t elements);
bool end_array();
// called when an object key is parsed; value is passed and can be safely moved away
bool key(string_t& val);

// called when a parse error occurs; byte position, the last token, and an exception is passed
bool parse_error(std::size_t position, const std::string& last_token, const detail::exception& ex);
```

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).

Niels's avatar
Niels committed
549
550
### STL-like access

551
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.
Niels's avatar
Niels committed
552
553
554
555
556
557
558
559

```cpp
// create an array using push_back
json j;
j.push_back("foo");
j.push_back(1);
j.push_back(true);

Niels Lohmann's avatar
Niels Lohmann committed
560
561
562
// also use emplace_back
j.emplace_back(1.78);

Niels's avatar
Niels committed
563
564
565
566
567
568
// iterate the array
for (json::iterator it = j.begin(); it != j.end(); ++it) {
  std::cout << *it << '\n';
}

// range-based for
Niels's avatar
Niels committed
569
for (auto& element : j) {
Niels's avatar
Niels committed
570
571
572
573
  std::cout << element << '\n';
}

// getter/setter
574
const auto tmp = j[0].get<std::string>();
Niels's avatar
Niels committed
575
576
577
j[1] = 42;
bool foo = j.at(2);

Jonathan Lee's avatar
Jonathan Lee committed
578
// comparison
579
j == R"(["foo", 1, true, 1.78])"_json;  // true
Jonathan Lee's avatar
Jonathan Lee committed
580

Niels's avatar
Niels committed
581
// other stuff
582
j.size();     // 4 entries
Niels's avatar
Niels committed
583
584
585
586
j.empty();    // false
j.type();     // json::value_t::array
j.clear();    // the array is empty again

Niels's avatar
Niels committed
587
588
589
590
591
592
593
594
// convenience type checkers
j.is_null();
j.is_boolean();
j.is_number();
j.is_object();
j.is_array();
j.is_string();

Niels's avatar
Niels committed
595
596
597
598
599
600
// create an object
json o;
o["foo"] = 23;
o["bar"] = false;
o["baz"] = 3.141;

Niels Lohmann's avatar
Niels Lohmann committed
601
602
603
// also use emplace
o.emplace("weather", "sunny");

Niels's avatar
Niels committed
604
605
606
607
608
// special iterator member functions for objects
for (json::iterator it = o.begin(); it != o.end(); ++it) {
  std::cout << it.key() << " : " << it.value() << "\n";
}

Niels Lohmann's avatar
Niels Lohmann committed
609
610
611
612
613
614
615
616
617
618
// the same code as range for
for (auto& el : o.items()) {
  std::cout << el.key() << " : " << el.value() << "\n";
}

// even easier with structured bindings (C++17)
for (auto& [key, value] : o.items()) {
  std::cout << key << " : " << value << "\n";
}

Niels's avatar
Niels committed
619
// find an entry
620
621
622
623
624
if (o.contains("foo")) {
  // there is an entry with key "foo"
}

// or via find and an iterator
Niels's avatar
Niels committed
625
626
627
if (o.find("foo") != o.end()) {
  // there is an entry with key "foo"
}
Niels's avatar
Niels committed
628
629
630
631
632
633
634

// or simpler using count()
int foo_present = o.count("foo"); // 1
int fob_present = o.count("fob"); // 0

// delete an entry
o.erase("foo");
Niels's avatar
Niels committed
635
636
```

Niels's avatar
Niels committed
637

Niels's avatar
Niels committed
638
639
### Conversion from STL containers

Niels Lohmann's avatar
Niels Lohmann committed
640
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.
Niels's avatar
Niels committed
641
642
643
644
645
646

```cpp
std::vector<int> c_vector {1, 2, 3, 4};
json j_vec(c_vector);
// [1, 2, 3, 4]

Niels's avatar
Niels committed
647
std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};
Niels's avatar
Niels committed
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
json j_deque(c_deque);
// [1.2, 2.3, 3.4, 5.6]

std::list<bool> c_list {true, true, false, true};
json j_list(c_list);
// [true, true, false, true]

std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
json j_flist(c_flist);
// [12345678909876, 23456789098765, 34567890987654, 45678909876543]

std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
json j_array(c_array);
// [1, 2, 3, 4]

std::set<std::string> c_set {"one", "two", "three", "four", "one"};
json j_set(c_set); // only one entry for "one" is used
// ["four", "one", "three", "two"]

std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
json j_uset(c_uset); // only one entry for "one" is used
// maybe ["two", "three", "four", "one"]

std::multiset<std::string> c_mset {"one", "two", "one", "four"};
672
673
json j_mset(c_mset); // both entries for "one" are used
// maybe ["one", "two", "one", "four"]
Niels's avatar
Niels committed
674
675
676
677
678
679

std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
json j_umset(c_umset); // both entries for "one" are used
// maybe ["one", "two", "one", "four"]
```

Niels Lohmann's avatar
Niels Lohmann committed
680
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.
Niels's avatar
Niels committed
681
682
683
684

```cpp
std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
json j_map(c_map);
Annihil's avatar
Annihil committed
685
// {"one": 1, "three": 3, "two": 2 }
Niels's avatar
Niels committed
686

Niels's avatar
Niels committed
687
std::unordered_map<const char*, double> c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} };
Niels's avatar
Niels committed
688
689
690
691
692
693
694
695
696
697
698
699
json j_umap(c_umap);
// {"one": 1.2, "two": 2.3, "three": 3.4}

std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
json j_mmap(c_mmap); // only one entry for key "three" is used
// maybe {"one": true, "two": true, "three": true}

std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
json j_ummap(c_ummap); // only one entry for key "three" is used
// maybe {"one": true, "two": true, "three": true}
```

Niels's avatar
Niels committed
700
701
702
703
704
705
706
707
708
709
710
711
### JSON Pointer and JSON Patch

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.

```cpp
// a JSON value
json j_original = R"({
  "baz": ["one", "two", "three"],
  "foo": "bar"
})"_json;

// access members with a JSON pointer (RFC 6901)
Niels's avatar
Niels committed
712
j_original["/baz/1"_json_pointer];
Niels's avatar
Niels committed
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
// "two"

// a JSON patch (RFC 6902)
json j_patch = R"([
  { "op": "replace", "path": "/baz", "value": "boo" },
  { "op": "add", "path": "/hello", "value": ["world"] },
  { "op": "remove", "path": "/foo"}
])"_json;

// apply the patch
json j_result = j_original.patch(j_patch);
// {
//    "baz": "boo",
//    "hello": ["world"]
// }

// calculate a JSON patch from two JSON values
json::diff(j_result, j_original);
// [
//   { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
Niels's avatar
Niels committed
733
734
//   { "op": "remove","path": "/hello" },
//   { "op": "add", "path": "/foo", "value": "bar" }
Niels's avatar
Niels committed
735
736
737
// ]
```

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
### JSON Merge Patch

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.

```cpp
// a JSON value
json j_document = R"({
  "a": "b",
  "c": {
    "d": "e",
    "f": "g"
  }
})"_json;

// a patch
json j_patch = R"({
  "a":"z",
  "c": {
    "f": null
  }
})"_json;

// apply the patch
Isaac Nickaein's avatar
Isaac Nickaein committed
761
j_document.merge_patch(j_patch);
762
763
764
765
766
767
768
// {
//  "a": "z",
//  "c": {
//    "d": "e"
//  }
// }
```
Niels's avatar
Niels committed
769

Niels's avatar
Niels committed
770
771
### Implicit conversions

772
773
774
Supported types can be implicitly converted to JSON values.

It is recommended to **NOT USE** implicit conversions **FROM** a JSON value.
775
You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958).
Niels Lohmann's avatar
Niels Lohmann committed
776
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`.
Niels's avatar
Niels committed
777
778

```cpp
Niels's avatar
Niels committed
779
// strings
Niels's avatar
Niels committed
780
781
std::string s1 = "Hello, world!";
json js = s1;
782
783
784
785
786
auto s2 = js.get<std::string>();
// NOT RECOMMENDED
std::string s3 = js;
std::string s4;
s4 = js;
Niels's avatar
Niels committed
787
788
789
790

// Booleans
bool b1 = true;
json jb = b1;
791
792
793
794
795
auto b2 = jb.get<bool>();
// NOT RECOMMENDED
bool b3 = jb;
bool b4;
b4 = jb;
Niels's avatar
Niels committed
796
797
798
799

// numbers
int i = 42;
json jn = i;
800
801
802
803
804
auto f = jn.get<double>();
// NOT RECOMMENDED
double f2 = jb;
double f3;
f3 = jb;
Niels's avatar
Niels committed
805
806
807

// etc.
```
Niels Lohmann's avatar
Niels Lohmann committed
808

Niels Lohmann's avatar
Niels Lohmann committed
809
810
811
812
813
814
815
816
Note that `char` types are not automatically converted to JSON strings, but to integer numbers. A conversion to a string must be specified explicitly:

```cpp
char ch = 'A';                       // ASCII value 65
json j_default = ch;                 // stores integer number 65
json j_string = std::string(1, ch);  // stores string "A"
```

Théo DELRIEU's avatar
Théo DELRIEU committed
817
818
### Arbitrary types conversions

Niels Lohmann's avatar
Niels Lohmann committed
819
Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines:
Théo DELRIEU's avatar
Théo DELRIEU committed
820
821
822

```cpp
namespace ns {
Niels Lohmann's avatar
Niels Lohmann committed
823
    // a simple struct to model a person
Niels Lohmann's avatar
Niels Lohmann committed
824
825
826
827
828
    struct person {
        std::string name;
        std::string address;
        int age;
    };
Théo DELRIEU's avatar
Théo DELRIEU committed
829
}
Niels Lohmann's avatar
Niels Lohmann committed
830

Niels Lohmann's avatar
Niels Lohmann committed
831
832
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};

Niels Lohmann's avatar
Niels Lohmann committed
833
// convert to JSON: copy each value into the JSON object
Théo DELRIEU's avatar
Théo DELRIEU committed
834
835
836
837
838
839
840
json j;
j["name"] = p.name;
j["address"] = p.address;
j["age"] = p.age;

// ...

Niels Lohmann's avatar
Niels Lohmann committed
841
// convert from JSON: copy each value from the JSON object
Niels Lohmann's avatar
Niels Lohmann committed
842
843
844
845
846
ns::person p {
    j["name"].get<std::string>(),
    j["address"].get<std::string>(),
    j["age"].get<int>()
};
Théo DELRIEU's avatar
Théo DELRIEU committed
847
848
```

Niels Lohmann's avatar
Niels Lohmann committed
849
It works, but that's quite a lot of boilerplate... Fortunately, there's a better way:
Théo DELRIEU's avatar
Théo DELRIEU committed
850
851

```cpp
Niels Lohmann's avatar
Niels Lohmann committed
852
853
854
855
// create a person
ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60};

// conversion: person -> json
Théo DELRIEU's avatar
Théo DELRIEU committed
856
857
json j = p;

Niels Lohmann's avatar
Niels Lohmann committed
858
859
860
861
std::cout << j << std::endl;
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}

// conversion: json -> person
862
auto p2 = j.get<ns::person>();
Niels Lohmann's avatar
Niels Lohmann committed
863
864

// that's it
Théo DELRIEU's avatar
Théo DELRIEU committed
865
866
867
868
869
assert(p == p2);
```

#### Basic usage

Niels Lohmann's avatar
Niels Lohmann committed
870
To make this work with one of your types, you only need to provide two functions:
Théo DELRIEU's avatar
Théo DELRIEU committed
871
872
873
874
875

```cpp
using nlohmann::json;

namespace ns {
Niels Lohmann's avatar
Niels Lohmann committed
876
    void to_json(json& j, const person& p) {
Niels Lohmann's avatar
Niels Lohmann committed
877
878
879
        j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
    }

Niels Lohmann's avatar
Niels Lohmann committed
880
    void from_json(const json& j, person& p) {
881
882
883
        j.at("name").get_to(p.name);
        j.at("address").get_to(p.address);
        j.at("age").get_to(p.age);
Niels Lohmann's avatar
Niels Lohmann committed
884
    }
Théo DELRIEU's avatar
Théo DELRIEU committed
885
886
887
} // namespace ns
```

Niels Lohmann's avatar
Niels Lohmann committed
888
That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
889
Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
Théo DELRIEU's avatar
Théo DELRIEU committed
890
891
892

Some important things:

Niels Lohmann's avatar
Niels Lohmann committed
893
* 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).
Mark Beckwith's avatar
Mark Beckwith committed
894
* 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.
895
* 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.)
896
* 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.
Niels Lohmann's avatar
Niels Lohmann committed
897
898
* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.

Niels Lohmann's avatar
Niels Lohmann committed
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
#### Simplify your life with macros

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:

```cpp
namespace ns {
Niels Lohmann's avatar
Niels Lohmann committed
916
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)
Niels Lohmann's avatar
Niels Lohmann committed
917
918
919
920
921
922
923
924
925
926
927
928
}
```

Here is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed:

```cpp
namespace ns {
    class address {
      private:
        std::string street;
        int housenumber;
        int postcode;
929

Niels Lohmann's avatar
Niels Lohmann committed
930
      public:
Niels Lohmann's avatar
Niels Lohmann committed
931
        NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)
Niels Lohmann's avatar
Niels Lohmann committed
932
933
934
    };
}
```
Théo DELRIEU's avatar
Théo DELRIEU committed
935
936
937

#### How do I convert third-party types?

Niels Lohmann's avatar
Niels Lohmann committed
938
This requires a bit more advanced technique. But first, let's see how this conversion mechanism works:
Théo DELRIEU's avatar
Théo DELRIEU committed
939
940

The library uses **JSON Serializers** to convert types to json.
941
The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)).
Théo DELRIEU's avatar
Théo DELRIEU committed
942
943
944
945
946

It is implemented like this (simplified):

```cpp
template <typename T>
Niels Lohmann's avatar
Niels Lohmann committed
947
948
949
950
951
952
953
954
struct adl_serializer {
    static void to_json(json& j, const T& value) {
        // calls the "to_json" method in T's namespace
    }

    static void from_json(const json& j, T& value) {
        // same thing, but with the "from_json" method
    }
Théo DELRIEU's avatar
Théo DELRIEU committed
955
956
957
};
```

Niels Lohmann's avatar
Niels Lohmann committed
958
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`...
Théo DELRIEU's avatar
Théo DELRIEU committed
959
960
961
962
963
964

To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example:

```cpp
// partial specialization (full specialization works too)
namespace nlohmann {
Niels Lohmann's avatar
Niels Lohmann committed
965
966
967
968
969
970
    template <typename T>
    struct adl_serializer<boost::optional<T>> {
        static void to_json(json& j, const boost::optional<T>& opt) {
            if (opt == boost::none) {
                j = nullptr;
            } else {
Niels Lohmann's avatar
Niels Lohmann committed
971
972
              j = *opt; // this will call adl_serializer<T>::to_json which will
                        // find the free function to_json in T's namespace!
Niels Lohmann's avatar
Niels Lohmann committed
973
974
975
976
            }
        }

        static void from_json(const json& j, boost::optional<T>& opt) {
977
978
979
            if (j.is_null()) {
                opt = boost::none;
            } else {
Wilson's avatar
Wilson committed
980
                opt = j.get<T>(); // same as above, but with
Niels Lohmann's avatar
Niels Lohmann committed
981
982
983
984
                                  // adl_serializer<T>::from_json
            }
        }
    };
Théo DELRIEU's avatar
Théo DELRIEU committed
985
986
987
988
989
}
```

#### How can I use `get()` for non-default constructible/non-copyable types?

990
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:
Théo DELRIEU's avatar
Théo DELRIEU committed
991
992
993

```cpp
struct move_only_type {
Niels Lohmann's avatar
Niels Lohmann committed
994
995
996
997
    move_only_type() = delete;
    move_only_type(int ii): i(ii) {}
    move_only_type(const move_only_type&) = delete;
    move_only_type(move_only_type&&) = default;
Wilson's avatar
Wilson committed
998

Niels Lohmann's avatar
Niels Lohmann committed
999
    int i;
Théo DELRIEU's avatar
Théo DELRIEU committed
1000
};