Commit befd90de authored by Niels's avatar Niels

cleanup

parent b453cdb7
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
.PHONY: header_only
# the order is important: header before other sources
CORE_SOURCES = src/json.h src/json.cc
noinst_PROGRAMS = json_unit json_parser
noinst_PROGRAMS = 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_unit_SOURCES = $(CORE_SOURCES) test/catch.hpp test/json_unit.cc
json_unit_SOURCES = $(CORE_SOURCES) test/catch.hpp test/unit.cpp src/json.hpp
json_unit_CXXFLAGS = $(FLAGS) -std=c++11
json_unit_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/test -Dprivate=public
json_parser_SOURCES = $(CORE_SOURCES) benchmark/parse.cc
json_parser_CXXFLAGS = -O3 -std=c++11 -flto
json_parser_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/benchmark
cppcheck:
cppcheck --enable=all --inconclusive --std=c++11 src/json.*
......@@ -29,13 +22,3 @@ pretty:
--align-reference=type --add-brackets --convert-tabs --close-templates \
--lineend=linux --preserve-date --suffix=none \
$(SOURCES)
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
This diff is collapsed.
#!/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])
AC_INIT([JSON], [3.0], [mail@nlohmann.me])
AC_CONFIG_SRCDIR([src/json.hpp])
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.
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