提交 fbad7fac 编写于 作者: N Niels

2.0 preview

上级 d1ac3d99
language: cpp
compiler:
- gcc
- clang
before_install:
- sudo pip install cpp-coveralls
before_script:
- autoreconf -iv
- ./configure
......@@ -10,3 +14,9 @@ before_script:
script:
- make
- make check
after_success:
- make clean
- make json_unit CXXFLAGS="-fprofile-arcs -ftest-coverage"
- ./json_unit
- coveralls --exclude lib --exclude tests --gcov-options '\-lp'
此差异已折叠。
noinst_PROGRAMS = json json98 json98benchmark
TESTS = ./json ./json98
noinst_PROGRAMS = json json_unit
TESTS = ./json ./json_unit
FLAGS = -Wall -Wextra -pedantic -Weffc++ -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch -Wundef -Wno-unused -Wnon-virtual-dtor -Wreorder
json_SOURCES = src/JSON.cc src/JSON.h test/JSON_test.cc
json_CXXFLAGS = -std=c++11
json_CXXFLAGS = $(FLAGS) -Weffc++ -std=c++11
json_CPPFLAGS = -I$(top_srcdir)/src
json98_SOURCES = src/JSON.cc src/JSON.h test/JSON_test.cc
json98_CXXFLAGS = -std=c++98
json98_CPPFLAGS = -I$(top_srcdir)/src
json_unit_SOURCES = src/JSON.cc src/JSON.h test/catch.hpp test/JSON_unit.cc
json_unit_CXXFLAGS = $(FLAGS) -std=c++11
json_unit_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/test -Dprivate=public
json98benchmark_SOURCES = src/JSON.cc src/JSON.h benchmark/JSON_benchmark.cc
json98benchmark_CXXFLAGS = -std=c++98 -O3
json98benchmark_CPPFLAGS = -I$(top_srcdir)/src -DNDEBUG
cppcheck:
cppcheck --enable=all --inconclusive --std=c++11 src/JSON.*
svn-clean: maintainer-clean
rm -fr configure INSTALL aclocal.m4 build-aux depcomp install-sh missing test-driver cover_html *.gcda *.gcno coverage*.info
rm -fr configure INSTALL aclocal.m4 build-aux depcomp install-sh missing test-driver
for DIR in $(DIST_SUBDIRS) .; do rm -f $$DIR/Makefile.in; done
cover:
make clean
make json98 CXXFLAGS+="--coverage -g -fprofile-arcs -ftest-coverage" CPPFLAGS+="-DNDEBUG"
./json98
lcov --capture --directory . --output-file coverage98.info
genhtml coverage*.info --output-directory cover_html --show-details --title "$(PACKAGE_STRING)" --legend --demangle-cpp
pretty:
astyle --style=allman --indent=spaces=4 --indent-modifiers \
--indent-switches --indent-preproc-block --indent-preproc-define \
--indent-col1-comments --pad-oper --pad-header --align-pointer=type \
--align-reference=type --add-brackets --convert-tabs --close-templates \
--lineend=linux --preserve-date --suffix=none \
$(SOURCES)
......@@ -6,9 +6,9 @@
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:
- **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++98 and -- if possible -- uses some features of C++11 such as move constructors. All in all, the class should require no adjustment of your compiler flags or project settings.
- **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.
- **Intiuitve 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.
- **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.
Other aspects were not so important to us:
......@@ -16,7 +16,7 @@ Other aspects were not so important to us:
- **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).
- **Rigourous 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.
- **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.
## Integration
......@@ -45,11 +45,17 @@ j["happy"] = true;
// add a string that is stored as std::string
j["name"] = "Niels";
// add a null object
j["nothing"] = nullptr;
// add an object inside the object
j["further"]["entry"] = 42;
// add an array that is stored as std::vector (C++11)
// add an array that is stored as std::vector
j["list"] = { 1, 0, 2 };
// add another object
j["object"] = { {"currency", "USD"}, {"value", "42.99"} };
```
### Input / Output
......@@ -65,6 +71,11 @@ std::cout << j;
These operators work for any subclasses of `std::istream` or `std::ostream`.
```cpp
// create object from string literal
JSON j = "{ \"pi\": 3.141, \"happy\": true }"_json;
```
### STL-like access
```cpp
......@@ -79,13 +90,13 @@ for (JSON::iterator it = j.begin(); it != j.end(); ++it) {
std::cout << *it << '\n';
}
// C++11 style
// range-based for
for (auto element : j) {
std::cout << element << '\n';
}
// getter/setter
std::string tmp = j[0];
const std::string tmp = j[0];
j[1] = 42;
// other stuff
......
#include <iostream>
#include <fstream>
#include <ctime>
#include <JSON.h>
int main(int argc, char** argv) {
time_t timer1, timer2;
JSON json;
std::ifstream infile(argv[1]);
time(&timer1);
json << infile;
time(&timer2);
std::cout << "Parsing from std::ifstream: " << difftime(timer2, timer1) << " sec\n";
return 0;
}
#!/usr/bin/env python
import json
import sys
import datetime
a = datetime.datetime.now()
data = json.loads(open(sys.argv[1]).read())
b = datetime.datetime.now()
print (b-a)
#!/bin/sh
git clone https://github.com/zeMirco/sf-city-lots-json.git
mv sf-city-lots-json/citylots.json .
rm -fr sf-city-lots-json
wget http://eu.battle.net/auction-data/258993a3c6b974ef3e6f22ea6f822720/auctions.json
AC_INIT([JSON], [1.0], [niels.lohmann@uni-rostock.de])
AC_INIT([JSON], [2.0], [mail@nlohmann.me])
AC_CONFIG_SRCDIR([src/JSON.cc])
AM_INIT_AUTOMAKE([foreign subdir-objects])
......
此差异已折叠。
此差异已折叠。
......@@ -5,7 +5,8 @@
#include <JSON.h>
#include <sstream>
void test_null() {
void test_null()
{
std::cerr << "entering test_null()\n";
/* a null object */
......@@ -29,7 +30,7 @@ void test_null() {
assert(a == b);
// type
assert(a.type() == JSON::null);
assert(a.type() == JSON::value_type::null);
// empty and size
assert(a.size() == 0);
......@@ -42,43 +43,56 @@ void test_null() {
assert(a.toString() == std::string("null"));
// invalid conversion to int
try {
try
{
int i = 0;
i = a;
assert(false);
} catch (const std::exception& ex) {
}
catch (const std::exception& ex)
{
assert(ex.what() == std::string("cannot cast null to JSON number"));
}
// invalid conversion to double
try {
try
{
double f = 0;
f = a;
assert(false);
} catch (const std::exception& ex) {
}
catch (const std::exception& ex)
{
assert(ex.what() == std::string("cannot cast null to JSON number"));
}
// invalid conversion to bool
try {
try
{
bool b = a;
assert(false);
} catch (const std::exception& ex) {
}
catch (const std::exception& ex)
{
assert(ex.what() == std::string("cannot cast null to JSON Boolean"));
}
// invalid conversion to string
try {
try
{
std::string s = a;
assert(false);
} catch (const std::exception& ex) {
}
catch (const std::exception& ex)
{
assert(ex.what() == std::string("cannot cast null to JSON string"));
}
std::cerr << "leaving test_null()\n";
}
void test_bool() {
void test_bool()
{
std::cerr << "entering test_bool()\n";
JSON True = true;
......@@ -89,7 +103,8 @@ void test_bool() {
std::cerr << "leaving test_bool()\n";
}
void test_string() {
void test_string()
{
std::cerr << "entering test_string()\n";
/* a string object */
......@@ -114,7 +129,7 @@ void test_string() {
assert(a == b);
// type
assert(a.type() == JSON::string);
assert(a.type() == JSON::value_type::string);
// empty and size
assert(a.size() == 1);
......@@ -127,29 +142,38 @@ void test_string() {
assert(a.toString() == std::string("\"object a\""));
// invalid conversion to int
try {
try
{
int i = 0;
i = a;
assert(false);
} catch (const std::exception& ex) {
}
catch (const std::exception& ex)
{
assert(ex.what() == std::string("cannot cast string to JSON number"));
}
// invalid conversion to double
try {
try
{
double f = 0;
f = a;
assert(false);
} catch (const std::exception& ex) {
}
catch (const std::exception& ex)
{
assert(ex.what() == std::string("cannot cast string to JSON number"));
}
// invalid conversion to bool
try {
try
{
bool b = false;
b = a;
assert(false);
} catch (const std::exception& ex) {
}
catch (const std::exception& ex)
{
assert(ex.what() == std::string("cannot cast string to JSON Boolean"));
}
......@@ -163,7 +187,8 @@ void test_string() {
std::cerr << "leaving test_string()\n";
}
void test_array() {
void test_array()
{
std::cerr << "entering test_array()\n";
JSON a;
......@@ -174,7 +199,7 @@ void test_array() {
a += "string";
// type
assert(a.type() == JSON::array);
assert(a.type() == JSON::value_type::array);
// empty and size
assert(a.size() == 5);
......@@ -190,10 +215,13 @@ void test_array() {
assert(a[4] == JSON("string"));
// invalid access to element
try {
try
{
a[5] = 1;
assert(false);
} catch (const std::exception& ex) {
// assert(false);
}
catch (const std::exception& ex)
{
assert(ex.what() == std::string("cannot access element at index 5"));
}
......@@ -217,7 +245,8 @@ void test_array() {
// iterators
{
size_t count = 0;
for (JSON::iterator i = a.begin(); i != a.end(); ++i) {
for (JSON::iterator i = a.begin(); i != a.end(); ++i)
{
std::cerr << *i << '\n';
count++;
}
......@@ -226,7 +255,8 @@ void test_array() {
{
size_t count = 0;
for (JSON::const_iterator i = a.begin(); i != a.end(); ++i) {
for (JSON::const_iterator i = a.begin(); i != a.end(); ++i)
{
std::cerr << *i << '\n';
count++;
}
......@@ -235,7 +265,8 @@ void test_array() {
{
size_t count = 0;
for (JSON::const_iterator i = a.cbegin(); i != a.cend(); ++i) {
for (JSON::const_iterator i = a.cbegin(); i != a.cend(); ++i)
{
std::cerr << *i << '\n';
count++;
}
......@@ -245,7 +276,8 @@ void test_array() {
#ifdef __cplusplus11
{
size_t count = 0;
for (auto element : a) {
for (auto element : a)
{
std::cerr << element << '\n';
count++;
}
......@@ -256,7 +288,8 @@ void test_array() {
{
JSON::iterator i;
size_t count = 0;
for (i = a.begin(); i != a.end(); ++i) {
for (i = a.begin(); i != a.end(); ++i)
{
std::cerr << *i << '\n';
count++;
}
......@@ -266,7 +299,8 @@ void test_array() {
{
JSON::const_iterator i;
size_t count = 0;
for (i = a.begin(); i != a.end(); ++i) {
for (i = a.begin(); i != a.end(); ++i)
{
std::cerr << *i << '\n';
count++;
}
......@@ -276,7 +310,8 @@ void test_array() {
{
JSON::const_iterator i;
size_t count = 0;
for (i = a.cbegin(); i != a.cend(); ++i) {
for (i = a.cbegin(); i != a.cend(); ++i)
{
std::cerr << *i << '\n';
count++;
}
......@@ -293,7 +328,8 @@ void test_array() {
std::cerr << "leaving test_array()\n";
}
void test_object() {
void test_object()
{
std::cerr << "entering test_object()\n";
// check find()
......@@ -309,7 +345,7 @@ void test_object() {
JSON::iterator i2 = o.find("baz");
assert(i2 == o.end());
JSON a;
a += "foo";
a += "bar";
......@@ -321,9 +357,10 @@ void test_object() {
std::cerr << "leaving test_object()\n";
}
void test_streaming() {
void test_streaming()
{
std::cerr << "entering test_streaming()\n";
// stream text representation into stream
std::stringstream i;
i << "{ \"foo\": true, \"baz\": [1,2,3,4] }";
......@@ -343,13 +380,13 @@ void test_streaming() {
i >> j;
j >> o;
o >> k;
assert(j.toString() == k.toString());
// assert(j.toString() == k.toString()); (order is not preserved)
}
// check numbers
{
std::stringstream number_stream;
number_stream << "[0, -1, 1, 1.0, -1.0, 1.0e+1, 1.0e-1, 1.0E+1, 1.0E-1, -1.2345678e-12345678]";
number_stream << "[0, -1, 1, 1.0, -1.0, 1.0e+1, 1.0e-1, 1.0E+1, 1.0E-1, -1.2345678e-12]";
JSON j;
j << number_stream;
}
......@@ -373,7 +410,8 @@ void test_streaming() {
std::cerr << "leaving test_streaming()\n";
}
int main() {
int main()
{
test_null();
test_bool();
test_string();
......
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册