README.md 6.8 KB
Newer Older
N
Niels 已提交
1
# JSON for Modern C++
N
Niels 已提交
2 3

[![Build Status](https://travis-ci.org/nlohmann/json.png?branch=master)](https://travis-ci.org/nlohmann/json)
N
Niels 已提交
4
[![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json)
N
Niels 已提交
5
[![Github Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](http://github.com/nlohmann/json/issues)
N
Niels 已提交
6

N
Niels 已提交
7 8 9 10
## Design goals

There are myriads of [JSON](http://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals:

N
Niels 已提交
11
- **Trivial integration**. Our whole code consists of just two files: A header file `JSON.h` and a source file `JSON.cc`. That's it. No library, no subproject, no dependencies. The class is written in vanilla C++11. All in all, the class should require no adjustment of your compiler flags or project settings.
N
Niels 已提交
12

N
Niels 已提交
13
- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you know, what I mean.
N
Niels 已提交
14

N
Niels 已提交
15 16
- **Serious testing**. Our library is heavily unit-tested and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we use [Valgrind](http://valgrind.org) to make sure no memory leaks exist.

N
Niels 已提交
17 18
Other aspects were not so important to us:

N
Niels 已提交
19
- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). We use the following C++ data types: `std::string` for strings, `int` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. We know that there are more efficient ways to store the values, but we are happy enough right now.
N
Niels 已提交
20

N
Niels 已提交
21
- **Speed**. We currently implement the parser as naive [recursive descent parser](http://en.wikipedia.org/wiki/Recursive_descent_parser) with hand coded string handling. It is fast enough, but a [LALR-parser](http://en.wikipedia.org/wiki/LALR_parser) with a decent regular expression processor should be even faster (but would consist of more files which makes the integration harder).
N
Niels 已提交
22

N
Niels 已提交
23
- **Rigorous standard compliance**. We followed the [specification](http://json.org) as close as possible, but did not invest too much in a 100% compliance with respect to Unicode support. As a result, there might be edge cases of false positives and false negatives, but as long as we have a hand-written parser, we won't invest too much to be fully compliant.
N
Niels 已提交
24 25 26 27 28 29 30 31 32

## Integration

All you need to do is add

```cpp
#include "JSON.h"
```

N
Niels 已提交
33
to the files you want to use JSON objects. Furthermore, you need to compile the file `JSON.cc` and link it to your binaries. Do not forget to set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
N
Niels 已提交
34 35 36 37 38 39

## Examples

Here are some examples to give you an idea how to use the class:

```cpp
N
Niels 已提交
40
// create an empty structure (null)
N
Niels 已提交
41 42
JSON j;

N
Niels 已提交
43
// add a number that is stored as double (note the implicit conversion of j to an object)
N
Niels 已提交
44 45 46 47 48 49 50 51
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";

N
Niels 已提交
52
// add another null object by passing nullptr
N
Niels 已提交
53 54
j["nothing"] = nullptr;

N
Niels 已提交
55 56 57
// add an object inside the object
j["further"]["entry"] = 42;

N
Niels 已提交
58
// add an array that is stored as std::vector (using an initializer list)
N
Niels 已提交
59
j["list"] = { 1, 0, 2 };
N
Niels 已提交
60

N
Niels 已提交
61
// add another object (using an initializer list of pairs)
N
Niels 已提交
62
j["object"] = { {"currency", "USD"}, {"value", "42.99"} };
N
Niels 已提交
63 64
```

N
Niels 已提交
65
### Input / Output
N
Niels 已提交
66

N
Niels 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
You can create an object by appending `_json` to a string literal:

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

You can also get a string representation:

```cpp
// explicit conversion to string
std::string s = j.toString();
```

The value of s could be `{"pi": 3.141, "happy": true}`, but the order of the entries in the object is not fixed.

You can also use streams:

N
Niels 已提交
85 86 87 88 89 90 91 92 93
```cpp
// create object from stream
JSON j;
j << "{ \"pi\": 3.141, \"happy\": true }";

// write string representation to stream
std::cout << j;
```

N
Niels 已提交
94
These operators work for any subclasses of `std::istream` or `std::ostream`.
N
Niels 已提交
95

N
Niels 已提交
96 97
### STL-like access

N
Niels 已提交
98 99
We designed the JSON class to behave just like an STL container:

N
Niels 已提交
100 101 102 103 104 105 106 107 108 109 110 111
```cpp
// create an array
JSON j;
j.push_back("foo");
j.push_back(1);
j.push_back(true);

// iterate the array
for (JSON::iterator it = j.begin(); it != j.end(); ++it) {
  std::cout << *it << '\n';
}

N
Niels 已提交
112
// range-based for
N
Niels 已提交
113 114 115 116
for (auto element : j) {
  std::cout << element << '\n';
}

N
Niels 已提交
117
// getter/setter
N
Niels 已提交
118
const std::string tmp = j[0];
N
Niels 已提交
119 120 121 122 123
j[1] = 42;

// other stuff
j.size();     // 3
j.empty();    // false
N
Niels 已提交
124 125
j.type();     // JSON::value_type::array
j.clear();    // the array is empty again
N
Niels 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

// create an object
JSON o;
o["foo"] = 23;
o["bar"] = false;
o["baz"] = 3.141;

// find an entry
if (o.find("foo") != o.end()) {
  // there is an entry with key "foo"
}

// iterate the object
for (JSON::iterator it = o.begin(); it != o.end(); ++it) {
  std::cout << it.key() << ':' << it.value() << '\n';
}
N
Niels 已提交
142
```
N
Niels 已提交
143 144 145

### Implicit conversions

N
Niels 已提交
146
The type of the JSON object is determined automatically by the expression to store. Likewise, the stored value is implicitly converted.
N
Niels 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

```cpp
/// strings
std::string s1 = "Hello, world!";
JSON js = s;
std::string s2 = j;

// Booleans
bool b1 = true;
JSON jb = b1;
bool b2 = jb;

// numbers
int i = 42;
JSON jn = i;
double f = jn;
N
Niels 已提交
163 164

// etc.
N
Niels 已提交
165 166
```

N
Niels 已提交
167 168 169 170 171 172 173 174 175 176 177 178
You can also explicitly ask for the value:

```cpp
std::string vs = js.get<std::string>();
bool vb = jb.get<bool>();
int vi = jn.get<int>();

// etc.
```

## License

N
Niels 已提交
179 180
<img style="float: right" src="http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png">

N
Niels 已提交
181 182 183 184 185 186 187 188 189
The library is licensed under the [MIT License](http://opensource.org/licenses/MIT):

Copyright (c) 2013-2014 Niels Lohmann

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 above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

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.