Commit 118ec996 authored by Niels's avatar Niels

Merge pull request #36 from nlohmann/template

template version with re2c scanner
parents c4d74856 c8c49dae
.DS_Store
src/.DS_Store
aclocal.m4
autom4te.cache/*
config.log
config.status
configure
depcomp
html
*.o
*.Po
install-sh
json_unit json_unit
html
Makefile
missing
.dirstamp
test-driver
Makefile.in
*.plist
json_parser
CMakeCache.txt
*.cmake
CMakeFiles
libjson.a
Testing
.idea
\ No newline at end of file
...@@ -6,15 +6,11 @@ compiler: ...@@ -6,15 +6,11 @@ compiler:
before_install: before_install:
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt-get update -qq - sudo apt-get update -qq
- if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.8; fi - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.9; fi
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi - if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
- sudo pip install cpp-coveralls pyyaml - sudo pip install cpp-coveralls pyyaml
- sudo apt-get install valgrind - sudo apt-get install valgrind
before_script:
- autoreconf -iv
- ./configure
script: script:
- make - make
- ./json_unit - ./json_unit
...@@ -22,6 +18,7 @@ script: ...@@ -22,6 +18,7 @@ script:
after_success: after_success:
- make clean - make clean
- make json_unit CXXFLAGS="-fprofile-arcs -ftest-coverage" - touch src/json.hpp
- make json_unit CXXFLAGS="-fprofile-arcs -ftest-coverage -std=c++11"
- ./json_unit - ./json_unit
- coveralls --exclude benchmark --exclude test --exclude header_only --gcov-options '\-lp' --gcov 'gcov-4.8' - coveralls --exclude test/catch.hpp --exclude test/unit.cpp --include src/json.hpp --gcov-options '\-lp' --gcov 'gcov-4.9'
cmake_minimum_required(VERSION 2.8.4)
project(json)
# Enable C++11 and set flags for coverage testing
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O0 --coverage -fprofile-arcs -ftest-coverage")
# Make everything public for testing purposes
add_definitions(-Dprivate=public)
# If not specified, use Debug as build type (necessary for coverage testing)
if( NOT CMAKE_BUILD_TYPE )
set( CMAKE_BUILD_TYPE Debug CACHE STRING
""
FORCE )
endif()
# CMake addons for lcov
# Only possible with g++ at the moment. We run otherwise just the test
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage -fprofile-arcs -ftest-coverage")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules)
include(CodeCoverage)
setup_coverage(coverage)
endif()
# Normal sources
include_directories(src/)
aux_source_directory(src/ json_list)
add_library(json ${json_list})
# Testing
enable_testing()
# Search all test files in the test directory with a .cc suffix
file(GLOB TEST_FILES "test/*.cc")
foreach(TEST_FILE ${TEST_FILES})
# We use the basename to identify the test. E.g "json_unit" for "json_unit.cc"
get_filename_component(BASENAME ${TEST_FILE} NAME_WE)
# Create a test executable
add_executable(${BASENAME} ${TEST_FILE})
# Link it with our main json file
target_link_libraries(${BASENAME} json)
# Add test if people want to use ctest
add_test(${BASENAME} ${BASENAME})
# If we are using g++, we also need to setup the commands for coverage
# testing
if(CMAKE_COMPILER_IS_GNUCXX)
# Add a run_XXX target that runs the executable and produces the
# coverage data automatically
add_custom_target(run_${BASENAME} COMMAND ./${BASENAME})
# Make sure that running requires the executable to be build
add_dependencies (run_${BASENAME} ${BASENAME})
# To create a valid coverage report, the executable has to be
# executed first
add_dependencies (coverage run_${BASENAME})
endif()
endforeach()
#
#
# 2012-01-31, Lars Bilke
# - Enable Code Coverage
#
# 2013-09-17, Joakim Söderberg
# - Added support for Clang.
# - Some additional usage instructions.
#
# USAGE:
# 0. (Mac only) If you use Xcode 5.1 make sure to patch geninfo as described here:
# http://stackoverflow.com/a/22404544/80480
#
# 1. Copy this file into your cmake modules path.
#
# 2. Add the following line to your CMakeLists.txt:
# INCLUDE(CodeCoverage)
#
# 3. Set compiler flags to turn off optimization and enable coverage:
# SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
# SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
#
# 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target
# which runs your test executable and produces a lcov code coverage report:
# Example:
# SETUP_TARGET_FOR_COVERAGE(
# my_coverage_target # Name for custom target.
# test_driver # Name of the test driver executable that runs the tests.
# # NOTE! This should always have a ZERO as exit code
# # otherwise the coverage generation will not complete.
# coverage # Name of output directory.
# )
#
# 4. Build a Debug build:
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# make
# make my_coverage_target
#
#
# Check prereqs
FIND_PROGRAM( GCOV_PATH gcov )
FIND_PROGRAM( LCOV_PATH lcov )
FIND_PROGRAM( GENHTML_PATH genhtml )
FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests)
IF(NOT GCOV_PATH)
MESSAGE(FATAL_ERROR "gcov not found! Aborting...")
ENDIF() # NOT GCOV_PATH
IF(NOT CMAKE_COMPILER_IS_GNUCXX)
# Clang version 3.0.0 and greater now supports gcov as well.
MESSAGE(WARNING "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.")
IF(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
ENDIF()
ENDIF() # NOT CMAKE_COMPILER_IS_GNUCXX
SET(CMAKE_CXX_FLAGS_COVERAGE
"-g -O0 --coverage -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C++ compiler during coverage builds."
FORCE )
SET(CMAKE_C_FLAGS_COVERAGE
"-g -O0 --coverage -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C compiler during coverage builds."
FORCE )
SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used for linking binaries during coverage builds."
FORCE )
SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
FORCE )
MARK_AS_ADVANCED(
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
IF ( NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "Coverage"))
MESSAGE( WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" )
ENDIF() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
# Param _outputname lcov output is generated as _outputname.info
# HTML report is generated in _outputname/index.html
FUNCTION(SETUP_COVERAGE _outputname)
IF(NOT LCOV_PATH)
MESSAGE(FATAL_ERROR "lcov not found! Aborting...")
ENDIF() # NOT LCOV_PATH
IF(NOT GENHTML_PATH)
MESSAGE(FATAL_ERROR "genhtml not found! Aborting...")
ENDIF() # NOT GENHTML_PATH
# Setup target
ADD_CUSTOM_TARGET(coverage
# Capturing lcov counters and generating report
COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory . --capture --output-file ${_outputname}.info
COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --remove ${_outputname}.info 'tests/*' '/usr/*' --output-file ${_outputname}.info.cleaned
COMMAND ${GENHTML_PATH} --branch-coverage --rc lcov_branch_coverage=1 -o ${_outputname} ${_outputname}.info.cleaned
COMMAND ${CMAKE_COMMAND} -E remove ${_outputname}.info ${_outputname}.info.cleaned
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
# Cleanup lcov
${LCOV_PATH} --directory . --zerocounters
)
ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE
This diff is collapsed.
The library is licensed under the MIT License The library is licensed under the MIT License
<http://opensource.org/licenses/MIT>: <http://opensource.org/licenses/MIT>:
Copyright (c) 2013-2014 Niels Lohmann Copyright (c) 2013-2015 Niels Lohmann
Permission is hereby granted, free of charge, to any person obtaining a copy of 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 this software and associated documentation files (the "Software"), to deal in
......
.PHONY: header_only # used programs
RE2C = re2c
SED = gsed
# the order is important: header before other sources # additional flags
CORE_SOURCES = src/json.h src/json.cc 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
noinst_PROGRAMS = json_unit json_parser all: 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 # clean up
clean:
rm -f json_unit
json_unit_SOURCES = $(CORE_SOURCES) test/catch.hpp test/json_unit.cc # build unit tests
json_unit_CXXFLAGS = $(FLAGS) -std=c++11 json_unit: test/unit.cpp src/json.hpp test/catch.hpp
json_unit_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/test -Dprivate=public $(CXX) -std=c++11 $(CXXFLAGS) $(FLAGS) $(CPPFLAGS) -I src -I test -Dprivate=public $< $(LDFLAGS) -o $@
json_parser_SOURCES = $(CORE_SOURCES) benchmark/parse.cc # create scanner with re2c
json_parser_CXXFLAGS = -O3 -std=c++11 -flto re2c: src/json.hpp.re2c
json_parser_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/benchmark $(RE2C) -b -s -i --no-generation-date $< | $(SED) '1d' > src/json.hpp
# static analyser
cppcheck: cppcheck:
cppcheck --enable=all --inconclusive --std=c++11 src/json.* cppcheck --enable=all --inconclusive --std=c++11 src/json.hpp
svn-clean: maintainer-clean
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
# pretty printer
pretty: pretty:
astyle --style=allman --indent=spaces=4 --indent-modifiers \ astyle --style=allman --indent=spaces=4 --indent-modifiers \
--indent-switches --indent-preproc-block --indent-preproc-define \ --indent-switches --indent-preproc-block --indent-preproc-define \
--indent-col1-comments --pad-oper --pad-header --align-pointer=type \ --indent-col1-comments --pad-oper --pad-header --align-pointer=type \
--align-reference=type --add-brackets --convert-tabs --close-templates \ --align-reference=type --add-brackets --convert-tabs --close-templates \
--lineend=linux --preserve-date --suffix=none \ --lineend=linux --preserve-date --suffix=none \
$(SOURCES) src/json.hpp src/json.hpp.re2c test/unit.cpp
parser:
make CXXFLAGS="" json_parser
header_only/json.h: $(CORE_SOURCES)
$(AM_V_GEN)
$(AM_V_at)mkdir -p header_only
$(AM_V_at)cat $(CORE_SOURCES) | $(SED) 's/#include "json.h"//' > header_only/json.h
BUILT_SOURCES = header_only/json.h
...@@ -10,34 +10,45 @@ ...@@ -10,34 +10,45 @@
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: 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:
- **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 the [reference](https://github.com/nlohmann/json/blob/master/doc/Reference.md), 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 modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you know, what I mean.
- **Trivial integration**. Our whole code consists of a class in 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, everything should require no adjustment of your compiler flags or project settings. - **Trivial integration**. Our whole code consists of a single header file `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/blob/master/test/json_unit.cc) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) that there are no memory leaks. - **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/blob/master/test/json_unit.cc) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) that there are no memory leaks.
Other aspects were not so important to us: Other aspects were not so important to us:
- **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, `int64_t` 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. - **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` 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**. 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). - **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).
- **Rigorous standard compliance**. Any [compliant](http://json.org) JSON file can be read by our class, and any output of the class is standard-compliant. However, we do not check for some details in the format of numbers and strings. For instance, `-0` will be treated as `0` whereas the standard forbids this. Furthermore, we allow for more escape symbols in strings as the JSON specification. While this may not be a problem in reality, we are aware of it, but as long as we have a hand-written parser, we won't invest too much to be fully compliant. - **Rigorous Unicode compliance**. We did our best to implement some robust Unicode support. There are still some issues with escaping, and if you run into a problem, please [tell me](https://github.com/nlohmann/json/issues).
## Updates since last version
As of February 2015, the following updates were made to the library
- *Changed:* In the generic class `basic_json`, all JSON value types (array, object, string, bool, integer number, and floating-point) are now **templated**. That is, you can choose whether you like a `std::list` for your arrays or an `std::unordered_map` for your objects. The specialization `json` sets some reasonable defaults.
- *Changed:* The library now consists of a single header, called `json.hpp`. Consequently, build systems such as Automake or CMake are not any longer required.
- *Changed:* The **deserialization** is now supported by a lexer generated with [re2c](http://re2c.org) from file [`src/json.hpp.re2c`](https://github.com/nlohmann/json/blob/master/src/json.hpp.re2c). As a result, we follow the JSON specification more strictly. Note neither the tool re2c nor its input are required to use the class.
- *Added:* The library now satisfies the [**ReversibleContainer**](http://en.cppreference.com/w/cpp/concept/ReversibleContainer) requirement. It hence provides four different iterators (`iterator`, `const_iterator`, `reverse_iterator`, and `const_reverse_iterator`), comparison functions, `swap()`, `size()`, `max_size()`, and `empty()` member functions.
- *Added*: The class uses **user-defined allocators** which default to `std::allocator`, but can be templated via parameter `Allocator`.
- *Added:* To simplify pretty-printing, the `std::setw` **stream manipulator** has been overloaded to set the desired indentation. Pretty-printing a JSON object `j` is as simple as `std::cout << std::setw(4) << j << '\n'.
- *Changed*: The type `json::value_t::number` is now called `json::value_t::number_integer` to be more symmetric compared to `json::value_t::number_float`.
- *Removed:* The `key()` and `value()` member functions for object iterators were nonstandard and yielded more problems than benefits. They were removed from the library.
## Integration ## Integration
The two required source files are in the `src` directory. All you need to do is add The single required source, `json.hpp` file is in the `src` directory. All you need to do is add
```cpp ```cpp
#include "json.h" #include "json.hpp"
// for convenience // for convenience
using json = nlohmann::json; using json = nlohmann::json;
``` ```
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). to the files you want to use JSON objects. That's it. Do not forget to set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
If you want a single header file, use the `json.h` file from the `header_only` directory.
## Examples ## Examples
...@@ -164,6 +175,9 @@ j << std::cin; ...@@ -164,6 +175,9 @@ j << std::cin;
// serialize to standard output // serialize to standard output
std::cout << j; std::cout << j;
// the setw manipulator was overloaded to set the indentation for pretty printing
std::cout << std::setw(4) << j << std::endl;
``` ```
These operators work for any subclasses of `std::istream` or `std::ostream`. These operators work for any subclasses of `std::istream` or `std::ostream`.
...@@ -213,11 +227,6 @@ o["baz"] = 3.141; ...@@ -213,11 +227,6 @@ o["baz"] = 3.141;
if (o.find("foo") != o.end()) { if (o.find("foo") != o.end()) {
// there is an entry with key "foo" // 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';
}
``` ```
### Conversion from STL containers ### Conversion from STL containers
...@@ -321,7 +330,7 @@ int vi = jn.get<int>(); ...@@ -321,7 +330,7 @@ int vi = jn.get<int>();
The class is licensed under the [MIT License](http://opensource.org/licenses/MIT): The class is licensed under the [MIT License](http://opensource.org/licenses/MIT):
Copyright &copy; 2013-2014 [Niels Lohmann](http://nlohmann.me) Copyright &copy; 2013-2015 [Niels Lohmann](http://nlohmann.me)
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: 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:
...@@ -341,44 +350,16 @@ I deeply appreciate the help of the following people. ...@@ -341,44 +350,16 @@ I deeply appreciate the help of the following people.
Thanks a lot for helping out! Thanks a lot for helping out!
## Execute unit tests with CMake ## Execute unit tests
To compile and run the tests, you need to execute To compile and run the tests, you need to execute
```sh ```sh
$ cmake .
$ make $ make
$ ctest
```
If you want to generate a coverage report with the lcov/genhtml tools, execute this instead:
```sh
$ cmake .
$ make coverage
```
**Note: You need to use GCC for now as otherwise the target coverage doesn't exist!**
The report is now in the subfolder coverage/index.html
## Execute unit tests with automake
To compile the unit tests, you need to execute
```sh
$ autoreconf -i
$ ./configure
$ make
```
The unit tests can then be executed with
```sh
$ ./json_unit $ ./json_unit
=============================================================================== ===============================================================================
All tests passed (887 assertions in 10 test cases) All tests passed (4280 assertions in 16 test cases)
``` ```
For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml). For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml).
#!/usr/bin/env python
import sys
import json
j = json.load(sys.stdin)
#include "json.h"
int main()
{
nlohmann::json j;
j << std::cin;
return 0;
}
AC_INIT([JSON], [2.0], [mail@nlohmann.me])
AC_CONFIG_SRCDIR([src/json.h])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AM_SILENT_RULES([yes])
AC_PROG_CXX
AC_PROG_SED
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
This source diff could not be displayed because it is too large. You can view the blob instead.
# Reference
## Nomenclature
We use the term "JSON" when we mean the [JavaScript Object Notation](http://json.org); that is, the file format. When we talk about the class implementing our library, we use "`json`" (typewriter font). Instances of this class are called "`json` values" to differentiate them from "JSON objects"; that is, unordered mappings, hashes, and whatnot.
## Types and default values
This table describes how JSON values are mapped to C++ types.
| JSON type | value_type | C++ type | type alias | default value |
| ----------------------- | -------------------------- | ----------------------------- | ---------------------- | --------------
| null | `value_type::null` | `nullptr_t` | - | `nullptr` |
| string | `value_type::string` | `std::string` | `json::string_t` | `""` |
| number (integer) | `value_type::number` | `int` | `json::number_t` | `0` |
| number (floating point) | `value_type::number_float` | `double` | `json::number_float_t` | `0.0` |
| array | `value_type::array ` | `std::array<json>` | `json::array_t` | `{}` |
| object | `value_type::object` | `std::map<std::string, json>` | `json::object_t` | `{}` |
The second column list entries of an enumeration `value_type` which can be queried by calling `type()` on a `json` value. The column "C++ types" list the internal type that is used to represent the respective JSON value. The "type alias" column furthermore lists type aliases that are used in the `json` class to allow for more flexibility. The last column list the default value; that is, the value that is set if none is passed to the constructor or that is set if `clear()` is called.
## Type conversions
There are only a few type conversions possible:
- An integer number can be translated to a floating point number.
- A floating point number can be translated to an integer number. Note the number is truncated and not rounded, ceiled or floored.
- Any value (i.e., boolean, string, number, null) but JSON objects can be translated into an array. The result is a singleton array that consists of the value before.
- Any other conversion will throw a `std::logic_error` exception.
When compatible, `json` values **implicitly convert** to `std::string`, `int`, `double`, `json::array_t`, and `json::object_t`. Furthermore, **explicit type conversion** is possible using the `get<>()` function with the aforementioned types.
## Initialization
`json` values can be created from many literals and variable types:
| JSON type | literal/variable types | examples |
| --------- | ---------------------- | -------- |
| none | null pointer literal, `nullptr_t` type, no value | `nullptr` |
| boolean | boolean literals, `bool` type, `json::boolean_t` type | `true`, `false` |
| string | string literal, `char*` type, `std::string` type, `std::string&&` rvalue reference, `json::string_t` type | `"Hello"` |
| number (integer) | integer literal, `short int` type, `int` type, `json_number_t` type | `42` |
| number (floating point) | floating point literal, `float` type, `double` type, `json::number_float_t` type | `3.141529`
| array | initializer list whose elements are `json` values (or can be translated into `json` values using the rules above), `std::vector<json>` type, `json::array_t` type, `json::array_t&&` rvalue reference | `{1, 2, 3, true, "foo"}` |
| object | initializer list whose elements are pairs of a string literal and a `json` value (or can be translated into `json` values using the rules above), `std::map<std::string, json>` type, `json::object_t` type, `json::object_t&&` rvalue reference | `{ {"key1", 42}, {"key2", false} }` |
## Number types
[![JSON number format](http://json.org/number.gif)](http://json.org)
The JSON specification explicitly does not define an internal number representation, but only the syntax of how numbers can be written down. Consequently, we would need to use the largest possible floating point number format (e.g., `long double`) to internally store JSON numbers.
However, this would be a waste of space, so we let the JSON parser decide which format to use: If the number can be precisely stored in an `int`, we use an `int` to store it. However, if it is a floating point number, we use `double` to store it.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment