diff --git a/.gitignore b/.gitignore index c0913edf..599a4332 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ json_unit +json_benchmarks working + +html diff --git a/Doxyfile b/Doxyfile index fa52af79..9d827589 100644 --- a/Doxyfile +++ b/Doxyfile @@ -27,7 +27,9 @@ MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 4 -ALIASES = +ALIASES = "complexity=@par Complexity\n" +ALIASES += liveexample{2}="@par Example\n \1 \n @includelineno \2.cpp \n Output:\n @verbinclude \2.output" +ALIASES += requirement="@par Requirements\n" TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO @@ -50,7 +52,7 @@ LOOKUP_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES +EXTRACT_PRIVATE = NO EXTRACT_PACKAGE = YES EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES @@ -69,7 +71,7 @@ SHOW_GROUPED_MEMB_INC = NO FORCE_LOCAL_INCLUDES = NO INLINE_INFO = YES SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO +SORT_BRIEF_DOCS = YES SORT_MEMBERS_CTORS_1ST = YES SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO @@ -80,9 +82,9 @@ GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES +SHOW_USED_FILES = NO SHOW_FILES = YES -SHOW_NAMESPACES = YES +SHOW_NAMESPACES = NO FILE_VERSION_FILTER = LAYOUT_FILE = CITE_BIB_FILES = @@ -99,18 +101,18 @@ WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- -INPUT = src/json.hpp +INPUT = src/json.hpp docs/doxyindex.cpp INPUT_ENCODING = UTF-8 FILE_PATTERNS = RECURSIVE = NO EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = +EXCLUDE_SYMBOLS = nlohmann::internals +EXAMPLE_PATH = docs/examples EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO -IMAGE_PATH = +IMAGE_PATH = docs/images INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO @@ -119,15 +121,15 @@ USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = YES +SOURCE_BROWSER = NO +INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -REFERENCES_LINK_SOURCE = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = NO SOURCE_TOOLTIPS = YES USE_HTAGS = NO -VERBATIM_HEADERS = YES +VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -153,15 +155,15 @@ HTML_DYNAMIC_SECTIONS = NO HTML_INDEX_NUM_ENTRIES = 100 GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" -DOCSET_BUNDLE_ID = org.doxygen.Project -DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_BUNDLE_ID = me.nlohmann.json +DOCSET_PUBLISHER_ID = me.nlohmann DOCSET_PUBLISHER_NAME = Publisher GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO CHM_INDEX_ENCODING = -BINARY_TOC = NO +BINARY_TOC = YES TOC_EXPAND = NO GENERATE_QHP = NO QCH_FILE = @@ -277,7 +279,7 @@ PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES +CLASS_DIAGRAMS = NO MSCGEN_PATH = DIA_PATH = HIDE_UNDOC_RELATIONS = YES @@ -286,18 +288,18 @@ DOT_NUM_THREADS = 0 DOT_FONTNAME = Helvetica DOT_FONTSIZE = 10 DOT_FONTPATH = -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES +CLASS_GRAPH = NO +COLLABORATION_GRAPH = NO GROUP_GRAPHS = YES UML_LOOK = YES UML_LIMIT_NUM_FIELDS = 10 -TEMPLATE_RELATIONS = YES -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = YES -CALLER_GRAPH = YES -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO DOT_IMAGE_FORMAT = svg INTERACTIVE_SVG = YES DOT_PATH = diff --git a/Makefile b/Makefile index e2ad6094..7b043f95 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,11 @@ pretty: --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 \ - src/json.hpp src/json.hpp.re2c test/unit.cpp benchmarks/benchmarks.cpp + src/json.hpp src/json.hpp.re2c test/unit.cpp benchmarks/benchmarks.cpp docs/examples/*.cpp + +# update docs +update_docs: + make create -C docs/examples # benchmarks json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/cxxopts.hpp src/json.hpp diff --git a/README.md b/README.md index 9d5c7762..202a6d67 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ std::vector c_vector {1, 2, 3, 4}; json j_vec(c_vector); // [1, 2, 3, 4] -std::deque c_deque {1.2, 2.3, 3.4, 5.6}; +std::deque c_deque {1.2, 2.3, 3.4, 5.6}; json j_deque(c_deque); // [1.2, 2.3, 3.4, 5.6] @@ -312,7 +312,7 @@ std::map c_map { {"one", 1}, {"two", 2}, {"three", 3} }; json j_map(c_map); // {"one": 1, "two": 2, "three": 3} -std::unordered_map c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; +std::unordered_map c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; json j_umap(c_umap); // {"one": 1.2, "two": 2.3, "three": 3.4} diff --git a/docs/doxyindex.cpp b/docs/doxyindex.cpp new file mode 100644 index 00000000..74ba79fa --- /dev/null +++ b/docs/doxyindex.cpp @@ -0,0 +1,21 @@ +/*! +@mainpage + +@copyright Niels Lohmann\n +@include "../../LICENSE.MIT" +*/ + +/*! +@defgroup container Container + +@brief methods and types to satisfy the Container requirements + +A Container is an object used to store other objects and taking care of the +management of the memory used by the objects it contains. + +@see http://en.cppreference.com/w/cpp/concept/Container +*/ + +/*! +@defgroup reversiblecontainer Reversible Container +*/ \ No newline at end of file diff --git a/docs/examples/Makefile b/docs/examples/Makefile new file mode 100644 index 00000000..71182ee3 --- /dev/null +++ b/docs/examples/Makefile @@ -0,0 +1,25 @@ +SRCDIR = ../../src + +EXAMPLES = $(wildcard *.cpp) + +all: + @echo "check" + @echo "create" + +clean: + rm -f $(EXAMPLES:.cpp=) $(EXAMPLES:.cpp=.output) $(EXAMPLES:.cpp=.test) + +%.output: %.cpp + make $(<:.cpp=) CPPFLAGS="-I $(SRCDIR)" CXXFLAGS="-std=c++11" + ./$(<:.cpp=) > $@ + rm $(<:.cpp=) + +%.test: %.cpp + make $(<:.cpp=) CPPFLAGS="-I $(SRCDIR)" CXXFLAGS="-std=c++11" + ./$(<:.cpp=) > $@ + diff $@ $(<:.cpp=.output) + rm $(<:.cpp=) $@ + +create: $(EXAMPLES:.cpp=.output) + +check: $(EXAMPLES:.cpp=.test) diff --git a/docs/examples/basic_json.cpp b/docs/examples/basic_json.cpp new file mode 100644 index 00000000..ceb47c5e --- /dev/null +++ b/docs/examples/basic_json.cpp @@ -0,0 +1,12 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create a JSON value with default null value + json j; + + // serialize the JSON null value + std::cout << j << '\n'; +} diff --git a/docs/examples/basic_json.output b/docs/examples/basic_json.output new file mode 100644 index 00000000..19765bd5 --- /dev/null +++ b/docs/examples/basic_json.output @@ -0,0 +1 @@ +null diff --git a/docs/examples/basic_json__CompatibleArrayType.cpp b/docs/examples/basic_json__CompatibleArrayType.cpp new file mode 100644 index 00000000..e63529b6 --- /dev/null +++ b/docs/examples/basic_json__CompatibleArrayType.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include + +using namespace nlohmann; + +int main() +{ + // create an array from std::vector + std::vector c_vector {1, 2, 3, 4}; + json j_vec(c_vector); + + // create an array from std::deque + std::deque c_deque {1.2, 2.3, 3.4, 5.6}; + json j_deque(c_deque); + + // create an array from std::list + std::list c_list {true, true, false, true}; + json j_list(c_list); + + // create an array from std::forward_list + std::forward_list c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; + json j_flist(c_flist); + + // create an array from std::array + std::array c_array {{1, 2, 3, 4}}; + json j_array(c_array); + + // create an array from std::set + std::set c_set {"one", "two", "three", "four", "one"}; + json j_set(c_set); // only one entry for "one" is used + + // create an array from std::unordered_set + std::unordered_set c_uset {"one", "two", "three", "four", "one"}; + json j_uset(c_uset); // only one entry for "one" is used + + // create an array from std::multiset + std::multiset c_mset {"one", "two", "one", "four"}; + json j_mset(c_mset); // only one entry for "one" is used + + // create an array from std::unordered_multiset + std::unordered_multiset c_umset {"one", "two", "one", "four"}; + json j_umset(c_umset); // both entries for "one" are used + + // serialize the JSON arrays + std::cout << j_vec << '\n'; + std::cout << j_deque << '\n'; + std::cout << j_list << '\n'; + std::cout << j_flist << '\n'; + std::cout << j_array << '\n'; + std::cout << j_set << '\n'; + std::cout << j_uset << '\n'; + std::cout << j_mset << '\n'; + std::cout << j_umset << '\n'; +} diff --git a/docs/examples/basic_json__CompatibleArrayType.output b/docs/examples/basic_json__CompatibleArrayType.output new file mode 100644 index 00000000..428505a1 --- /dev/null +++ b/docs/examples/basic_json__CompatibleArrayType.output @@ -0,0 +1,9 @@ +[1,2,3,4] +[1.2,2.3,3.4,5.6] +[true,true,false,true] +[12345678909876,23456789098765,34567890987654,45678909876543] +[1,2,3,4] +["four","one","three","two"] +["four","three","two","one"] +["four","one","one","two"] +["four","two","one","one"] diff --git a/docs/examples/basic_json__CompatibleObjectType.cpp b/docs/examples/basic_json__CompatibleObjectType.cpp new file mode 100644 index 00000000..8aa0dc73 --- /dev/null +++ b/docs/examples/basic_json__CompatibleObjectType.cpp @@ -0,0 +1,41 @@ +#include +#include + +using namespace nlohmann; + +int main() +{ + // create an object from std::map + std::map c_map + { + {"one", 1}, {"two", 2}, {"three", 3} + }; + json j_map(c_map); + + // create an object from std::unordered_map + std::unordered_map c_umap + { + {"one", 1.2}, {"two", 2.3}, {"three", 3.4} + }; + json j_umap(c_umap); + + // create an object from std::multimap + std::multimap c_mmap + { + {"one", true}, {"two", true}, {"three", false}, {"three", true} + }; + json j_mmap(c_mmap); // only one entry for key "three" is used + + // create an object from std::unordered_multimap + std::unordered_multimap c_ummap + { + {"one", true}, {"two", true}, {"three", false}, {"three", true} + }; + json j_ummap(c_ummap); // only one entry for key "three" is used + + // serialize the JSON objects + std::cout << j_map << '\n'; + std::cout << j_umap << '\n'; + std::cout << j_mmap << '\n'; + std::cout << j_ummap << '\n'; +} diff --git a/docs/examples/basic_json__CompatibleObjectType.output b/docs/examples/basic_json__CompatibleObjectType.output new file mode 100644 index 00000000..c70f7184 --- /dev/null +++ b/docs/examples/basic_json__CompatibleObjectType.output @@ -0,0 +1,4 @@ +{"one":1,"three":3,"two":2} +{"one":1.2,"three":3.4,"two":2.3} +{"one":true,"three":false,"two":true} +{"one":true,"three":false,"two":true} diff --git a/docs/examples/basic_json__array_t.cpp b/docs/examples/basic_json__array_t.cpp new file mode 100644 index 00000000..641c56e0 --- /dev/null +++ b/docs/examples/basic_json__array_t.cpp @@ -0,0 +1,15 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array_t value + json::array_t value = {"one", "two", 3, 4.5, false}; + + // create a JSON array from the value + json j(value); + + // serialize the JSON array + std::cout << j << '\n'; +} diff --git a/docs/examples/basic_json__array_t.output b/docs/examples/basic_json__array_t.output new file mode 100644 index 00000000..d379a756 --- /dev/null +++ b/docs/examples/basic_json__array_t.output @@ -0,0 +1 @@ +["one","two",3,4.5,false] diff --git a/docs/examples/basic_json__basic_json.cpp b/docs/examples/basic_json__basic_json.cpp new file mode 100644 index 00000000..c61827e9 --- /dev/null +++ b/docs/examples/basic_json__basic_json.cpp @@ -0,0 +1,16 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create a JSON array + json j1 = {"one", "two", 3, 4.5, false}; + + // create a copy + json j2(j1); + + // serialize the JSON array + std::cout << j1 << " = " << j2 << '\n'; + std::cout << std::boolalpha << (j1 == j2) << '\n'; +} diff --git a/docs/examples/basic_json__basic_json.output b/docs/examples/basic_json__basic_json.output new file mode 100644 index 00000000..ee93a41c --- /dev/null +++ b/docs/examples/basic_json__basic_json.output @@ -0,0 +1,2 @@ +["one","two",3,4.5,false] = ["one","two",3,4.5,false] +true diff --git a/docs/examples/basic_json__nullptr_t.cpp b/docs/examples/basic_json__nullptr_t.cpp new file mode 100644 index 00000000..f2f1a8c0 --- /dev/null +++ b/docs/examples/basic_json__nullptr_t.cpp @@ -0,0 +1,12 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create a JSON null value + json j(nullptr); + + // serialize the JSON null value + std::cout << j << '\n'; +} diff --git a/docs/examples/basic_json__nullptr_t.output b/docs/examples/basic_json__nullptr_t.output new file mode 100644 index 00000000..19765bd5 --- /dev/null +++ b/docs/examples/basic_json__nullptr_t.output @@ -0,0 +1 @@ +null diff --git a/docs/examples/basic_json__object_t.cpp b/docs/examples/basic_json__object_t.cpp new file mode 100644 index 00000000..0a296d1a --- /dev/null +++ b/docs/examples/basic_json__object_t.cpp @@ -0,0 +1,15 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an object_t value + json::object_t value = { {"one", 1}, {"two", 2} }; + + // create a JSON object from the value + json j(value); + + // serialize the JSON object + std::cout << j << '\n'; +} diff --git a/docs/examples/basic_json__object_t.output b/docs/examples/basic_json__object_t.output new file mode 100644 index 00000000..62376d83 --- /dev/null +++ b/docs/examples/basic_json__object_t.output @@ -0,0 +1 @@ +{"one":1,"two":2} diff --git a/docs/examples/basic_json__value_t.cpp b/docs/examples/basic_json__value_t.cpp new file mode 100644 index 00000000..c36e0e51 --- /dev/null +++ b/docs/examples/basic_json__value_t.cpp @@ -0,0 +1,24 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create the different JSON values with default values + json j_null(json::value_t::null); + json j_boolean(json::value_t::boolean); + json j_number_integer(json::value_t::number_integer); + json j_number_float(json::value_t::number_float); + json j_object(json::value_t::object); + json j_array(json::value_t::array); + json j_string(json::value_t::string); + + // serialize the JSON values + std::cout << j_null << '\n'; + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} diff --git a/docs/examples/basic_json__value_t.output b/docs/examples/basic_json__value_t.output new file mode 100644 index 00000000..0a6269fb --- /dev/null +++ b/docs/examples/basic_json__value_t.output @@ -0,0 +1,7 @@ +null +false +0 +0 +{} +[] +"" diff --git a/docs/examples/begin.cpp b/docs/examples/begin.cpp new file mode 100644 index 00000000..f6b1b1e4 --- /dev/null +++ b/docs/examples/begin.cpp @@ -0,0 +1,15 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get am iterator to the first element + json::iterator it = array.begin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/docs/examples/begin.output b/docs/examples/begin.output new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/docs/examples/begin.output @@ -0,0 +1 @@ +1 diff --git a/docs/examples/cbegin.cpp b/docs/examples/cbegin.cpp new file mode 100644 index 00000000..43a11939 --- /dev/null +++ b/docs/examples/cbegin.cpp @@ -0,0 +1,15 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array value + const json array = {1, 2, 3, 4, 5}; + + // get am iterator to the first element + json::const_iterator it = array.cbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/docs/examples/cbegin.output b/docs/examples/cbegin.output new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/docs/examples/cbegin.output @@ -0,0 +1 @@ +1 diff --git a/docs/examples/cend.cpp b/docs/examples/cend.cpp new file mode 100644 index 00000000..f796c905 --- /dev/null +++ b/docs/examples/cend.cpp @@ -0,0 +1,18 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get am iterator to one past the last element + json::const_iterator it = array.cend(); + + // decrement the iterator to point to the last element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/docs/examples/cend.output b/docs/examples/cend.output new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/docs/examples/cend.output @@ -0,0 +1 @@ +5 diff --git a/docs/examples/crbegin.cpp b/docs/examples/crbegin.cpp new file mode 100644 index 00000000..b36692fa --- /dev/null +++ b/docs/examples/crbegin.cpp @@ -0,0 +1,15 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-beginning + json::const_reverse_iterator it = array.crbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/docs/examples/crbegin.output b/docs/examples/crbegin.output new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/docs/examples/crbegin.output @@ -0,0 +1 @@ +5 diff --git a/docs/examples/crend.cpp b/docs/examples/crend.cpp new file mode 100644 index 00000000..d61804e8 --- /dev/null +++ b/docs/examples/crend.cpp @@ -0,0 +1,18 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-end + json::const_reverse_iterator it = array.crend(); + + // increment the iterator to point to the first element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/docs/examples/crend.output b/docs/examples/crend.output new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/docs/examples/crend.output @@ -0,0 +1 @@ +1 diff --git a/docs/examples/empty.cpp b/docs/examples/empty.cpp new file mode 100644 index 00000000..0da27d27 --- /dev/null +++ b/docs/examples/empty.cpp @@ -0,0 +1,29 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call empty() + std::cout << std::boolalpha; + std::cout << j_null.empty() << '\n'; + std::cout << j_boolean.empty() << '\n'; + std::cout << j_number_integer.empty() << '\n'; + std::cout << j_number_float.empty() << '\n'; + std::cout << j_object.empty() << '\n'; + std::cout << j_object_empty.empty() << '\n'; + std::cout << j_array.empty() << '\n'; + std::cout << j_array_empty.empty() << '\n'; + std::cout << j_string.empty() << '\n'; +} diff --git a/docs/examples/empty.output b/docs/examples/empty.output new file mode 100644 index 00000000..d071a398 --- /dev/null +++ b/docs/examples/empty.output @@ -0,0 +1,9 @@ +true +false +false +false +false +true +false +true +false diff --git a/docs/examples/end.cpp b/docs/examples/end.cpp new file mode 100644 index 00000000..11a65575 --- /dev/null +++ b/docs/examples/end.cpp @@ -0,0 +1,18 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get am iterator to one past the last element + json::iterator it = array.end(); + + // decrement the iterator to point to the last element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/docs/examples/end.output b/docs/examples/end.output new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/docs/examples/end.output @@ -0,0 +1 @@ +5 diff --git a/docs/examples/is_array.cpp b/docs/examples/is_array.cpp new file mode 100644 index 00000000..a5a544f0 --- /dev/null +++ b/docs/examples/is_array.cpp @@ -0,0 +1,25 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_array() + std::cout << std::boolalpha; + std::cout << j_null.is_array() << '\n'; + std::cout << j_boolean.is_array() << '\n'; + std::cout << j_number_integer.is_array() << '\n'; + std::cout << j_number_float.is_array() << '\n'; + std::cout << j_object.is_array() << '\n'; + std::cout << j_array.is_array() << '\n'; + std::cout << j_string.is_array() << '\n'; +} diff --git a/docs/examples/is_array.output b/docs/examples/is_array.output new file mode 100644 index 00000000..65ffc69e --- /dev/null +++ b/docs/examples/is_array.output @@ -0,0 +1,7 @@ +false +false +false +false +false +true +false diff --git a/docs/examples/is_boolean.cpp b/docs/examples/is_boolean.cpp new file mode 100644 index 00000000..0143b0bf --- /dev/null +++ b/docs/examples/is_boolean.cpp @@ -0,0 +1,25 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_boolean() + std::cout << std::boolalpha; + std::cout << j_null.is_boolean() << '\n'; + std::cout << j_boolean.is_boolean() << '\n'; + std::cout << j_number_integer.is_boolean() << '\n'; + std::cout << j_number_float.is_boolean() << '\n'; + std::cout << j_object.is_boolean() << '\n'; + std::cout << j_array.is_boolean() << '\n'; + std::cout << j_string.is_boolean() << '\n'; +} diff --git a/docs/examples/is_boolean.output b/docs/examples/is_boolean.output new file mode 100644 index 00000000..54f16b97 --- /dev/null +++ b/docs/examples/is_boolean.output @@ -0,0 +1,7 @@ +false +true +false +false +false +false +false diff --git a/docs/examples/is_null.cpp b/docs/examples/is_null.cpp new file mode 100644 index 00000000..d107f730 --- /dev/null +++ b/docs/examples/is_null.cpp @@ -0,0 +1,25 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_null() + std::cout << std::boolalpha; + std::cout << j_null.is_null() << '\n'; + std::cout << j_boolean.is_null() << '\n'; + std::cout << j_number_integer.is_null() << '\n'; + std::cout << j_number_float.is_null() << '\n'; + std::cout << j_object.is_null() << '\n'; + std::cout << j_array.is_null() << '\n'; + std::cout << j_string.is_null() << '\n'; +} diff --git a/docs/examples/is_null.output b/docs/examples/is_null.output new file mode 100644 index 00000000..828ea891 --- /dev/null +++ b/docs/examples/is_null.output @@ -0,0 +1,7 @@ +true +false +false +false +false +false +false diff --git a/docs/examples/is_number.cpp b/docs/examples/is_number.cpp new file mode 100644 index 00000000..992ec183 --- /dev/null +++ b/docs/examples/is_number.cpp @@ -0,0 +1,25 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_number() + std::cout << std::boolalpha; + std::cout << j_null.is_number() << '\n'; + std::cout << j_boolean.is_number() << '\n'; + std::cout << j_number_integer.is_number() << '\n'; + std::cout << j_number_float.is_number() << '\n'; + std::cout << j_object.is_number() << '\n'; + std::cout << j_array.is_number() << '\n'; + std::cout << j_string.is_number() << '\n'; +} diff --git a/docs/examples/is_number.output b/docs/examples/is_number.output new file mode 100644 index 00000000..b031a141 --- /dev/null +++ b/docs/examples/is_number.output @@ -0,0 +1,7 @@ +false +false +true +true +false +false +false diff --git a/docs/examples/is_number_float.cpp b/docs/examples/is_number_float.cpp new file mode 100644 index 00000000..3ede378f --- /dev/null +++ b/docs/examples/is_number_float.cpp @@ -0,0 +1,25 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_number_float() + std::cout << std::boolalpha; + std::cout << j_null.is_number_float() << '\n'; + std::cout << j_boolean.is_number_float() << '\n'; + std::cout << j_number_integer.is_number_float() << '\n'; + std::cout << j_number_float.is_number_float() << '\n'; + std::cout << j_object.is_number_float() << '\n'; + std::cout << j_array.is_number_float() << '\n'; + std::cout << j_string.is_number_float() << '\n'; +} diff --git a/docs/examples/is_number_float.output b/docs/examples/is_number_float.output new file mode 100644 index 00000000..c2470282 --- /dev/null +++ b/docs/examples/is_number_float.output @@ -0,0 +1,7 @@ +false +false +false +true +false +false +false diff --git a/docs/examples/is_number_integer.cpp b/docs/examples/is_number_integer.cpp new file mode 100644 index 00000000..281bf432 --- /dev/null +++ b/docs/examples/is_number_integer.cpp @@ -0,0 +1,25 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_number_integer() + std::cout << std::boolalpha; + std::cout << j_null.is_number_integer() << '\n'; + std::cout << j_boolean.is_number_integer() << '\n'; + std::cout << j_number_integer.is_number_integer() << '\n'; + std::cout << j_number_float.is_number_integer() << '\n'; + std::cout << j_object.is_number_integer() << '\n'; + std::cout << j_array.is_number_integer() << '\n'; + std::cout << j_string.is_number_integer() << '\n'; +} diff --git a/docs/examples/is_number_integer.output b/docs/examples/is_number_integer.output new file mode 100644 index 00000000..26051afd --- /dev/null +++ b/docs/examples/is_number_integer.output @@ -0,0 +1,7 @@ +false +false +true +false +false +false +false diff --git a/docs/examples/is_object.cpp b/docs/examples/is_object.cpp new file mode 100644 index 00000000..268c0224 --- /dev/null +++ b/docs/examples/is_object.cpp @@ -0,0 +1,25 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_object() + std::cout << std::boolalpha; + std::cout << j_null.is_object() << '\n'; + std::cout << j_boolean.is_object() << '\n'; + std::cout << j_number_integer.is_object() << '\n'; + std::cout << j_number_float.is_object() << '\n'; + std::cout << j_object.is_object() << '\n'; + std::cout << j_array.is_object() << '\n'; + std::cout << j_string.is_object() << '\n'; +} diff --git a/docs/examples/is_object.output b/docs/examples/is_object.output new file mode 100644 index 00000000..8416200c --- /dev/null +++ b/docs/examples/is_object.output @@ -0,0 +1,7 @@ +false +false +false +false +true +false +false diff --git a/docs/examples/is_string.cpp b/docs/examples/is_string.cpp new file mode 100644 index 00000000..6bcbcec5 --- /dev/null +++ b/docs/examples/is_string.cpp @@ -0,0 +1,25 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call is_string() + std::cout << std::boolalpha; + std::cout << j_null.is_string() << '\n'; + std::cout << j_boolean.is_string() << '\n'; + std::cout << j_number_integer.is_string() << '\n'; + std::cout << j_number_float.is_string() << '\n'; + std::cout << j_object.is_string() << '\n'; + std::cout << j_array.is_string() << '\n'; + std::cout << j_string.is_string() << '\n'; +} diff --git a/docs/examples/is_string.output b/docs/examples/is_string.output new file mode 100644 index 00000000..2cead02b --- /dev/null +++ b/docs/examples/is_string.output @@ -0,0 +1,7 @@ +false +false +false +false +false +false +true diff --git a/docs/examples/rbegin.cpp b/docs/examples/rbegin.cpp new file mode 100644 index 00000000..58514b73 --- /dev/null +++ b/docs/examples/rbegin.cpp @@ -0,0 +1,15 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-beginning + json::reverse_iterator it = array.rbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/docs/examples/rbegin.output b/docs/examples/rbegin.output new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/docs/examples/rbegin.output @@ -0,0 +1 @@ +5 diff --git a/docs/examples/rend.cpp b/docs/examples/rend.cpp new file mode 100644 index 00000000..319a75c1 --- /dev/null +++ b/docs/examples/rend.cpp @@ -0,0 +1,18 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-end + json::reverse_iterator it = array.rend(); + + // increment the iterator to point to the first element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} diff --git a/docs/examples/rend.output b/docs/examples/rend.output new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/docs/examples/rend.output @@ -0,0 +1 @@ +1 diff --git a/docs/examples/size.cpp b/docs/examples/size.cpp new file mode 100644 index 00000000..db012861 --- /dev/null +++ b/docs/examples/size.cpp @@ -0,0 +1,28 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call size() + std::cout << j_null.size() << '\n'; + std::cout << j_boolean.size() << '\n'; + std::cout << j_number_integer.size() << '\n'; + std::cout << j_number_float.size() << '\n'; + std::cout << j_object.size() << '\n'; + std::cout << j_object_empty.size() << '\n'; + std::cout << j_array.size() << '\n'; + std::cout << j_array_empty.size() << '\n'; + std::cout << j_string.size() << '\n'; +} diff --git a/docs/examples/size.output b/docs/examples/size.output new file mode 100644 index 00000000..3831387b --- /dev/null +++ b/docs/examples/size.output @@ -0,0 +1,9 @@ +0 +1 +1 +1 +2 +0 +5 +0 +1 diff --git a/docs/images/range-begin-end.svg b/docs/images/range-begin-end.svg new file mode 100644 index 00000000..8e2b2fb6 --- /dev/null +++ b/docs/images/range-begin-end.svg @@ -0,0 +1,435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Past-the-last element + + + + begin + + + + end + + + + + diff --git a/docs/images/range-rbegin-rend.svg b/docs/images/range-rbegin-rend.svg new file mode 100644 index 00000000..dc6045fc --- /dev/null +++ b/docs/images/range-rbegin-rend.svg @@ -0,0 +1,1232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Past-the-last element + + + + begin + + + + end + + + + + + + + + + + + + + + + + + + + + + + + + Reversed sequence + + Reverse past-the-last element + + + + + + + + rend + + + + rbegin + + + Reverse iterator stores an iterator to the nextelement than the one it actually refers to + + + + + + + + + diff --git a/src/json.hpp b/src/json.hpp index 3633151d..262552e7 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -50,6 +50,9 @@ namespace nlohmann { +/// namespace with internal helper functions +namespace internals +{ // Helper to determine whether there's a key_type for T. // http://stackoverflow.com/a/7728728/266378 template @@ -61,9 +64,10 @@ struct has_mapped_type public: enum { value = sizeof(test(0)) == sizeof(char) }; }; +} /*! -@brief JSON +@brief a class to store JSON values @tparam ObjectType type for JSON objects (@c std::map by default) @@ -101,6 +105,9 @@ class basic_json // container types // ///////////////////// + /// @name container types + /// @{ + /// the type of elements in a basic_json container using value_type = basic_json; @@ -133,6 +140,9 @@ class basic_json /// a const reverse iterator for a basic_json container class const_reverse_iterator; + /// @} + + /// returns the allocator associated with the container static allocator_type get_allocator() { @@ -144,6 +154,9 @@ class basic_json // JSON value data types // /////////////////////////// + /// @name JSON value data types + /// @{ + /// a type for an object using object_t = ObjectType, AllocatorType>>; @@ -160,12 +173,19 @@ class basic_json /// a type for list initialization using list_init_t = std::initializer_list; + /// @} + ///////////////////////////////// // JSON value type enumeration // ///////////////////////////////// - /// JSON value type enumeration + /*! + @brief the JSON value type enumeration + + This enumeration collects the different JSON value types. It is used to + distinguish the stored values in the union @ref json_value. + */ enum class value_t : uint8_t { null, ///< null value @@ -178,6 +198,7 @@ class basic_json discarded ///< (internal) indicates the parser callback chose not to keep the value }; + //////////////////////// // JSON value storage // //////////////////////// @@ -341,9 +362,28 @@ class basic_json /*! @brief create an empty value with a given type - @param value the type to create an value of - @exception std::bad_alloc if allocation for object, array, or string fails. + Create an empty JSON value with a given type. The value will be default + initialized with an empty value which depends on the type: + + Value type | initial value + ----------- | ------------- + null | @c null + boolean | @c false + string | @c "" + number | @c 0 + object | @c {} + array | @c [] + + @param value the type of the value to create + + @complexity Constant. + + @exception std::bad_alloc if allocation for object, array, or string value + fails (thrown by the constructors of @ref json_value) + + @liveexample{The following code shows the constructor for different @ref + value_t values,basic_json__value_t} */ basic_json(const value_t value) : m_type(value), m_value(value) @@ -351,27 +391,93 @@ class basic_json /*! @brief create a null object (implicitly) + + Create a `null` JSON value. This is the implicit version of the `null` + value constructor as it takes no parameters. + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - As postcondition, it holds: `basic_json().empty() == true`. + + @liveexample{The following code shows the constructor for a `null` JSON + value.,basic_json} + + @sa basic_json(std::nullptr_t) @ingroup container */ basic_json() noexcept = default; - /// create a null object (explicitly) + /*! + @brief create a null object (explicitly) + + Create a `null` JSON value. This is the explicitly version of the `null` + value constructor as it takes a null pointer as parameter. It allows to + create `null` values by explicitly assigning a @c nullptr to a JSON value. + The passed null pointer itself is not read - it is only used to choose the + right constructor. + + @complexity Constant. + + @liveexample{The following code shows the constructor with null pointer + parameter.,basic_json__nullptr_t} + + @sa basic_json() + */ basic_json(std::nullptr_t) noexcept : basic_json(value_t::null) {} - /// create an object (explicit) + /*! + @brief create an object (explicit) + + Create an object JSON value with a given content. + + @param value a value for the object + + @complexity Linear in the size of the passed @a value. + + @exception std::bad_alloc if allocation for object value fails (thrown by + the constructor of @ref json_value) + + @liveexample{The following code shows the constructor with an @ref object_t + parameter.,basic_json__object_t} + + @sa basic_json(const CompatibleObjectType&) + */ basic_json(const object_t& value) : m_type(value_t::object), m_value(value) {} - /// create an object (implicit) - template ::value and - std::is_constructible::value, int>::type + std::is_constructible::value and + std::is_constructible::value, int>::type = 0> - basic_json(const V& value) + basic_json(const CompatibleObjectType& value) : m_type(value_t::object) { AllocatorType alloc; @@ -381,23 +487,60 @@ class basic_json alloc.construct(m_value.object, begin(value), end(value)); } - /// create an array (explicit) + /*! + @brief create an array (explicit) + + Create an array JSON value with a given content. + + @param value a value for the array + + @complexity Linear in the size of the passed @a value. + + @exception std::bad_alloc if allocation for array value fails (thrown by + the constructor of @ref json_value) + + @liveexample{The following code shows the constructor with an @ref array_t + parameter.,basic_json__array_t} + + @sa basic_json(const CompatibleArrayType&) + */ basic_json(const array_t& value) : m_type(value_t::array), m_value(value) {} - /// create an array (implicit) - template ::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - std::is_constructible::value, int>::type + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + std::is_constructible::value, int>::type = 0> - basic_json(const V& value) + basic_json(const CompatibleArrayType& value) : m_type(value_t::array) { AllocatorType alloc; @@ -675,7 +818,20 @@ class basic_json /*! @brief copy constructor - @exception std::bad_alloc if allocation for object, array, or string fails. + Creates a copy of a given JSON value. + + @param other the JSON value to copy + + @complexity Linear in the size of @a other. + + @requirement This function satisfies the Container requirements: + - The complexity is linear. + - As postcondition, it holds: `other == basic_json(other)`. + + @exception std::bad_alloc if allocation for object, array, or string fails. + + @liveexample{The following code shows an example for the copy + constructor.,basic_json__basic_json} @ingroup container */ @@ -740,6 +896,15 @@ class basic_json /*! @brief copy assignment + + The copy assignment operator is expressed in terms of the copy constructor, + destructor, and the swap() member function. + + @complexity Linear. + + @requirement This function satisfies the Container requirements: + - The complexity is linear. + @ingroup container */ reference& operator=(basic_json other) noexcept ( @@ -757,6 +922,15 @@ class basic_json /*! @brief destructor + + Destroys the JSON value and frees all memory. + + @complexity Linear. + + @requirement This function satisfies the Container requirements: + - The complexity is linear. + - All stored elements are destroyed and all memory is freed. + @ingroup container */ ~basic_json() noexcept @@ -804,6 +978,9 @@ class basic_json // object inspection // /////////////////////// + /// @name object inspection + /// @{ + /*! @brief serialization @@ -840,49 +1017,140 @@ class basic_json return m_type; } - // return whether value is null + /*! + @brief return whether value is null + + This function returns true iff the JSON value is null. + + @return `true` if value type is null, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_null for all JSON + value types.,is_null} + */ bool is_null() const noexcept { return m_type == value_t::null; } - // return whether value is boolean + /*! + @brief return whether value is a boolean + + This function returns true iff the JSON value is a boolean. + + @return `true` if value type is boolean, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_boolean for all JSON + value types.,is_boolean} + */ bool is_boolean() const noexcept { return m_type == value_t::boolean; } - // return whether value is number + /*! + @brief return whether value is a number + + This function returns true iff the JSON value is a number. This includes + both integer and floating-point values. + + @return `true` if value type is number, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_number for all JSON + value types.,is_number} + */ bool is_number() const noexcept { return (m_type == value_t::number_integer) or (m_type == value_t::number_float); } - // return whether value an integer is number + /*! + @brief return whether value is an integer number + + This function returns true iff the JSON value is an integer number. This + excludes floating-point values. + + @return `true` if value type is an integer number, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_number_integer for all + JSON value types.,is_number_integer} + */ bool is_number_integer() const noexcept { return m_type == value_t::number_integer; } - // return whether value is a floating-point number + /*! + @brief return whether value is a floating-point number + + This function returns true iff the JSON value is a floating-point number. + This excludes integer values. + + @return `true` if value type is a floating-point number, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_number_float for all + JSON value types.,is_number_float} + */ bool is_number_float() const noexcept { return m_type == value_t::number_float; } - // return whether value is object + /*! + @brief return whether value is an object + + This function returns true iff the JSON value is an object. + + @return `true` if value type is object, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_object for all JSON + value types.,is_object} + */ bool is_object() const noexcept { return m_type == value_t::object; } - // return whether value is array + /*! + @brief return whether value is an array + + This function returns true iff the JSON value is an array. + + @return `true` if value type is array, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_array for all JSON + value types.,is_array} + */ bool is_array() const noexcept { return m_type == value_t::array; } - // return whether value is string + /*! + @brief return whether value is a string + + This function returns true iff the JSON value is a string. + + @return `true` if value type is string, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_string for all JSON + value types.,is_string} + */ bool is_string() const noexcept { return m_type == value_t::string; @@ -900,10 +1168,12 @@ class basic_json return m_type; } + /// @} + private: - ////////////////////// - // value conversion // - ////////////////////// + ////////////////// + // value access // + ////////////////// /// get an object (explicit) template ::value and not std::is_arithmetic::value and not std::is_convertible::value and - not has_mapped_type::value + not internals::has_mapped_type::value , int>::type = 0> T get_impl(T*) const { @@ -1004,7 +1274,7 @@ class basic_json template ::value and - not has_mapped_type::value + not internals::has_mapped_type::value , int>::type = 0> T get_impl(T*) const { @@ -1097,6 +1367,10 @@ class basic_json } public: + + /// @name value access + /// @{ + /// get a value (explicit) // template @@ -1112,11 +1386,16 @@ class basic_json return get(); } + /// @} + //////////////////// // element access // //////////////////// + /// @name element access + /// @{ + /// access specified element with bounds checking reference at(size_type idx) { @@ -1482,13 +1761,32 @@ class basic_json return (m_type == value_t::object) ? m_value.object->count(key) : 0; } + /// @} + /////////////// // iterators // /////////////// + /// @name iterators + /// @{ + /*! @brief returns an iterator to the first element + + Returns an iterator to the first element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return iterator to the first element + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + + @liveexample{The following code shows an example for @ref begin.,begin} + @ingroup container */ iterator begin() noexcept @@ -1499,7 +1797,7 @@ class basic_json } /*! - @brief returns a const iterator to the first element + @copydoc basic_json::cbegin() @ingroup container */ const_iterator begin() const noexcept @@ -1509,6 +1807,21 @@ class basic_json /*! @brief returns a const iterator to the first element + + Returns a const iterator to the first element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return const iterator to the first element + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).begin()`. + + @liveexample{The following code shows an example for @ref cbegin.,cbegin} + @ingroup container */ const_iterator cbegin() const noexcept @@ -1520,6 +1833,20 @@ class basic_json /*! @brief returns an iterator to one past the last element + + Returns an iterator to one past the last element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return iterator one past the last element + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + + @liveexample{The following code shows an example for @ref end.,end} + @ingroup container */ iterator end() noexcept @@ -1530,7 +1857,7 @@ class basic_json } /*! - @brief returns a const iterator to one past the last element + @copydoc basic_json::cend() @ingroup container */ const_iterator end() const noexcept @@ -1540,6 +1867,21 @@ class basic_json /*! @brief returns a const iterator to one past the last element + + Returns a const iterator to one past the last element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return const iterator one past the last element + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).end()`. + + @liveexample{The following code shows an example for @ref cend.,cend} + @ingroup container */ const_iterator cend() const noexcept @@ -1550,7 +1892,20 @@ class basic_json } /*! - @brief returns a reverse iterator to the first element + @brief returns an iterator to the reverse-beginning + + Returns an iterator to the reverse-beginning; that is, the last element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function satisfies the ReversibleContainer requirements: + - The complexity is constant. + - Has the semantics of `reverse_iterator(end())`. + + @liveexample{The following code shows an example for @ref rbegin.,rbegin} + @ingroup reversiblecontainer */ reverse_iterator rbegin() noexcept @@ -1559,7 +1914,7 @@ class basic_json } /*! - @brief returns a const reverse iterator to the first element + @copydoc basic_json::crbegin() @ingroup reversiblecontainer */ const_reverse_iterator rbegin() const noexcept @@ -1568,7 +1923,21 @@ class basic_json } /*! - @brief returns a reverse iterator to one past the last element + @brief returns an iterator to the reverse-end + + Returns an iterator to the reverse-end; that is, one before the first + element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function satisfies the ReversibleContainer requirements: + - The complexity is constant. + - Has the semantics of `reverse_iterator(begin())`. + + @liveexample{The following code shows an example for @ref rend.,rend} + @ingroup reversiblecontainer */ reverse_iterator rend() noexcept @@ -1577,7 +1946,7 @@ class basic_json } /*! - @brief returns a const reverse iterator to one past the last element + @copydoc basic_json::crend() @ingroup reversiblecontainer */ const_reverse_iterator rend() const noexcept @@ -1586,7 +1955,21 @@ class basic_json } /*! - @brief returns a const reverse iterator to the first element + @brief returns a const reverse iterator to the last element + + Returns a const iterator to the reverse-beginning; that is, the last + element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function satisfies the ReversibleContainer requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).rbegin()`. + + @liveexample{The following code shows an example for @ref crbegin.,crbegin} + @ingroup reversiblecontainer */ const_reverse_iterator crbegin() const noexcept @@ -1595,7 +1978,21 @@ class basic_json } /*! - @brief returns a const reverse iterator to one past the last element + @brief returns a const reverse iterator to one before the first + + Returns a const reverse iterator to the reverse-end; that is, one before + the first element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function satisfies the ReversibleContainer requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).rend()`. + + @liveexample{The following code shows an example for @ref crend.,crend} + @ingroup reversiblecontainer */ const_reverse_iterator crend() const noexcept @@ -1603,13 +2000,43 @@ class basic_json return const_reverse_iterator(cbegin()); } + /// @} + ////////////// // capacity // ////////////// + /// @name capacity + /// @{ + /*! @brief checks whether the container is empty + + Checks if a JSON value has no elements. + + @return The return value depends on the different value types and is + defined as follows: + Value type | return value + ----------- | ------------- + null | @c true + boolean | @c false + string | @c false + number | @c false + object | result of function object_t::empty() + array | result of function array_t::empty() + + @complexity Constant, as long as @ref array_t and @ref object_t satisfy the + Container concept; that is, their empty() functions have + constant complexity. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - Has the semantics of `begin() == end()`. + + @liveexample{The following code uses @ref empty to check if a @ref json + object contains any elements.,empty} + @ingroup container */ bool empty() const noexcept @@ -1641,6 +2068,31 @@ class basic_json /*! @brief returns the number of elements + + Returns the number of elements in a JSON value. + + @return The return value depends on the different value types and is + defined as follows: + Value type | return value + ----------- | ------------- + null | @c 0 + boolean | @c 1 + string | @c 1 + number | @c 1 + object | result of function object_t::size() + array | result of function array_t::size() + + @complexity Constant, as long as @ref array_t and @ref object_t satisfy the + Container concept; that is, their size() functions have + constant complexity. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - Has the semantics of `std::distance(begin(), end())`. + + @liveexample{The following code calls @ref size on the different value + types.,size} + @ingroup container */ size_type size() const noexcept @@ -1701,11 +2153,16 @@ class basic_json } } + /// @} + /////////////// // modifiers // /////////////// + /// @name modifiers + /// @{ + /// clears the contents void clear() noexcept { @@ -1892,11 +2349,16 @@ class basic_json std::swap(*(m_value.string), other); } + /// @} + ////////////////////////////////////////// // lexicographical comparison operators // ////////////////////////////////////////// + /// @name lexicographical comparison operators + /// @{ + /*! @brief comparison: equal @ingroup container @@ -2012,11 +2474,16 @@ class basic_json return not (lhs < rhs); } + /// @} + /////////////////// // serialization // /////////////////// + /// @name serialization + /// @{ + /// serialize to stream friend std::ostream& operator<<(std::ostream& o, const basic_json& j) { @@ -2038,11 +2505,16 @@ class basic_json return o << j; } + /// @} + ///////////////////// // deserialization // ///////////////////// + /// @name deserialization + /// @{ + /// deserialize from string static basic_json parse(const string_t& s, parser_callback_t cb = nullptr) { @@ -2069,6 +2541,8 @@ class basic_json return i; } + /// @} + private: /////////////////////////// @@ -3633,758 +4107,369 @@ class basic_json // remember the begin of the token m_start = m_cursor; + + { + lexer_char_t yych; + unsigned int yyaccept = 0; + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 0, 0, 32, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 96, 64, 0, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 0, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + }; - { - lexer_char_t yych; - unsigned int yyaccept = 0; - static const unsigned char yybm[] = - { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 32, 0, 0, 32, 0, 0, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 96, 64, 0, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 0, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }; - - if ((m_limit - m_cursor) < 5) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '9') - { - if (yych <= ' ') - { - if (yych <= '\n') - { - if (yych <= 0x00) - { - goto basic_json_parser_27; - } - if (yych <= 0x08) - { - goto basic_json_parser_29; - } - if (yych >= '\n') - { - goto basic_json_parser_4; - } - } - else - { - if (yych == '\r') - { - goto basic_json_parser_2; - } - if (yych <= 0x1F) - { - goto basic_json_parser_29; - } - } - } - else - { - if (yych <= ',') - { - if (yych == '"') - { - goto basic_json_parser_26; - } - if (yych <= '+') - { - goto basic_json_parser_29; - } - goto basic_json_parser_14; - } - else - { - if (yych <= '-') - { - goto basic_json_parser_22; - } - if (yych <= '/') - { - goto basic_json_parser_29; - } - if (yych <= '0') - { - goto basic_json_parser_23; - } - goto basic_json_parser_25; - } - } - } - else - { - if (yych <= 'm') - { - if (yych <= '\\') - { - if (yych <= ':') - { - goto basic_json_parser_16; - } - if (yych == '[') - { - goto basic_json_parser_6; - } - goto basic_json_parser_29; - } - else - { - if (yych <= ']') - { - goto basic_json_parser_8; - } - if (yych == 'f') - { - goto basic_json_parser_21; - } - goto basic_json_parser_29; - } - } - else - { - if (yych <= 'z') - { - if (yych <= 'n') - { - goto basic_json_parser_18; - } - if (yych == 't') - { - goto basic_json_parser_20; - } - goto basic_json_parser_29; - } - else - { - if (yych <= '{') - { - goto basic_json_parser_10; - } - if (yych == '}') - { - goto basic_json_parser_12; - } - goto basic_json_parser_29; - } - } - } -basic_json_parser_2: - ++m_cursor; - yych = *m_cursor; - goto basic_json_parser_5; -basic_json_parser_3: - { - return scan(); - } -basic_json_parser_4: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; -basic_json_parser_5: - if (yybm[0 + yych] & 32) - { - goto basic_json_parser_4; - } - goto basic_json_parser_3; -basic_json_parser_6: - ++m_cursor; - { - return token_type::begin_array; - } -basic_json_parser_8: - ++m_cursor; - { - return token_type::end_array; - } -basic_json_parser_10: - ++m_cursor; - { - return token_type::begin_object; - } -basic_json_parser_12: - ++m_cursor; - { - return token_type::end_object; - } -basic_json_parser_14: - ++m_cursor; - { - return token_type::value_separator; - } -basic_json_parser_16: - ++m_cursor; - { - return token_type::name_separator; - } -basic_json_parser_18: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'u') - { - goto basic_json_parser_59; - } -basic_json_parser_19: - { - return token_type::parse_error; - } -basic_json_parser_20: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'r') - { - goto basic_json_parser_55; - } - goto basic_json_parser_19; -basic_json_parser_21: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'a') - { - goto basic_json_parser_50; - } - goto basic_json_parser_19; -basic_json_parser_22: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_19; - } - if (yych <= '0') - { - goto basic_json_parser_49; - } - if (yych <= '9') - { - goto basic_json_parser_40; - } - goto basic_json_parser_19; -basic_json_parser_23: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') - { - if (yych == '.') - { - goto basic_json_parser_42; - } - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_43; - } - if (yych == 'e') - { - goto basic_json_parser_43; - } - } -basic_json_parser_24: - { - return token_type::value_number; - } -basic_json_parser_25: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - goto basic_json_parser_41; -basic_json_parser_26: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych <= 0x0F) - { - goto basic_json_parser_19; - } - goto basic_json_parser_31; -basic_json_parser_27: - ++m_cursor; - { - return token_type::end_of_input; - } -basic_json_parser_29: - yych = *++m_cursor; - goto basic_json_parser_19; -basic_json_parser_30: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; -basic_json_parser_31: - if (yybm[0 + yych] & 64) - { - goto basic_json_parser_30; - } - if (yych <= 0x0F) - { - goto basic_json_parser_32; - } - if (yych <= '"') - { - goto basic_json_parser_34; - } - goto basic_json_parser_33; -basic_json_parser_32: - m_cursor = m_marker; - if (yyaccept == 0) - { - goto basic_json_parser_19; - } - else - { - goto basic_json_parser_24; - } -basic_json_parser_33: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= 'e') - { - if (yych <= '/') - { - if (yych == '"') - { - goto basic_json_parser_30; - } - if (yych <= '.') - { - goto basic_json_parser_32; - } - goto basic_json_parser_30; - } - else - { - if (yych <= '\\') - { - if (yych <= '[') - { - goto basic_json_parser_32; - } - goto basic_json_parser_30; - } - else - { - if (yych == 'b') - { - goto basic_json_parser_30; - } - goto basic_json_parser_32; - } - } - } - else - { - if (yych <= 'q') - { - if (yych <= 'f') - { - goto basic_json_parser_30; - } - if (yych == 'n') - { - goto basic_json_parser_30; - } - goto basic_json_parser_32; - } - else - { - if (yych <= 's') - { - if (yych <= 'r') - { - goto basic_json_parser_30; - } - goto basic_json_parser_32; - } - else - { - if (yych <= 't') - { - goto basic_json_parser_30; - } - if (yych <= 'u') - { - goto basic_json_parser_36; - } - goto basic_json_parser_32; - } - } - } -basic_json_parser_34: - ++m_cursor; - { - return token_type::value_string; - } -basic_json_parser_36: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '@') - { - if (yych <= '/') - { - goto basic_json_parser_32; - } - if (yych >= ':') - { - goto basic_json_parser_32; - } - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_37; - } - if (yych <= '`') - { - goto basic_json_parser_32; - } - if (yych >= 'g') - { - goto basic_json_parser_32; - } - } -basic_json_parser_37: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '@') - { - if (yych <= '/') - { - goto basic_json_parser_32; - } - if (yych >= ':') - { - goto basic_json_parser_32; - } - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_38; - } - if (yych <= '`') - { - goto basic_json_parser_32; - } - if (yych >= 'g') - { - goto basic_json_parser_32; - } - } -basic_json_parser_38: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '@') - { - if (yych <= '/') - { - goto basic_json_parser_32; - } - if (yych >= ':') - { - goto basic_json_parser_32; - } - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_39; - } - if (yych <= '`') - { - goto basic_json_parser_32; - } - if (yych >= 'g') - { - goto basic_json_parser_32; - } - } -basic_json_parser_39: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '@') - { - if (yych <= '/') - { - goto basic_json_parser_32; - } - if (yych <= '9') - { - goto basic_json_parser_30; - } - goto basic_json_parser_32; - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_30; - } - if (yych <= '`') - { - goto basic_json_parser_32; - } - if (yych <= 'f') - { - goto basic_json_parser_30; - } - goto basic_json_parser_32; - } -basic_json_parser_40: - yyaccept = 1; - m_marker = ++m_cursor; - if ((m_limit - m_cursor) < 3) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; -basic_json_parser_41: - if (yybm[0 + yych] & 128) - { - goto basic_json_parser_40; - } - if (yych <= 'D') - { - if (yych != '.') - { - goto basic_json_parser_24; - } - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_43; - } - if (yych == 'e') - { - goto basic_json_parser_43; - } - goto basic_json_parser_24; - } -basic_json_parser_42: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_32; - } - if (yych <= '9') - { - goto basic_json_parser_47; - } - goto basic_json_parser_32; -basic_json_parser_43: - yych = *++m_cursor; - if (yych <= ',') - { - if (yych != '+') - { - goto basic_json_parser_32; - } - } - else - { - if (yych <= '-') - { - goto basic_json_parser_44; - } - if (yych <= '/') - { - goto basic_json_parser_32; - } - if (yych <= '9') - { - goto basic_json_parser_45; - } - goto basic_json_parser_32; - } -basic_json_parser_44: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_32; - } - if (yych >= ':') - { - goto basic_json_parser_32; - } -basic_json_parser_45: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '/') - { - goto basic_json_parser_24; - } - if (yych <= '9') - { - goto basic_json_parser_45; - } - goto basic_json_parser_24; -basic_json_parser_47: - yyaccept = 1; - m_marker = ++m_cursor; - if ((m_limit - m_cursor) < 3) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= 'D') - { - if (yych <= '/') - { - goto basic_json_parser_24; - } - if (yych <= '9') - { - goto basic_json_parser_47; - } - goto basic_json_parser_24; - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_43; - } - if (yych == 'e') - { - goto basic_json_parser_43; - } - goto basic_json_parser_24; - } -basic_json_parser_49: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') - { - if (yych == '.') - { - goto basic_json_parser_42; - } - goto basic_json_parser_24; - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_43; - } - if (yych == 'e') - { - goto basic_json_parser_43; - } - goto basic_json_parser_24; - } -basic_json_parser_50: - yych = *++m_cursor; - if (yych != 'l') - { - goto basic_json_parser_32; - } - yych = *++m_cursor; - if (yych != 's') - { - goto basic_json_parser_32; - } - yych = *++m_cursor; - if (yych != 'e') - { - goto basic_json_parser_32; - } - ++m_cursor; - { - return token_type::literal_false; - } -basic_json_parser_55: - yych = *++m_cursor; - if (yych != 'u') - { - goto basic_json_parser_32; - } - yych = *++m_cursor; - if (yych != 'e') - { - goto basic_json_parser_32; - } - ++m_cursor; - { - return token_type::literal_true; - } -basic_json_parser_59: - yych = *++m_cursor; - if (yych != 'l') - { - goto basic_json_parser_32; - } - yych = *++m_cursor; - if (yych != 'l') - { - goto basic_json_parser_32; - } - ++m_cursor; - { - return token_type::literal_null; + if ((m_limit - m_cursor) < 5) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '9') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x00) goto basic_json_parser_27; + if (yych <= 0x08) goto basic_json_parser_29; + if (yych >= '\n') goto basic_json_parser_4; + } else { + if (yych == '\r') goto basic_json_parser_2; + if (yych <= 0x1F) goto basic_json_parser_29; + } + } else { + if (yych <= ',') { + if (yych == '"') goto basic_json_parser_26; + if (yych <= '+') goto basic_json_parser_29; + goto basic_json_parser_14; + } else { + if (yych <= '-') goto basic_json_parser_22; + if (yych <= '/') goto basic_json_parser_29; + if (yych <= '0') goto basic_json_parser_23; + goto basic_json_parser_25; } } + } else { + if (yych <= 'm') { + if (yych <= '\\') { + if (yych <= ':') goto basic_json_parser_16; + if (yych == '[') goto basic_json_parser_6; + goto basic_json_parser_29; + } else { + if (yych <= ']') goto basic_json_parser_8; + if (yych == 'f') goto basic_json_parser_21; + goto basic_json_parser_29; + } + } else { + if (yych <= 'z') { + if (yych <= 'n') goto basic_json_parser_18; + if (yych == 't') goto basic_json_parser_20; + goto basic_json_parser_29; + } else { + if (yych <= '{') goto basic_json_parser_10; + if (yych == '}') goto basic_json_parser_12; + goto basic_json_parser_29; + } + } + } +basic_json_parser_2: + ++m_cursor; + yych = *m_cursor; + goto basic_json_parser_5; +basic_json_parser_3: + { return scan(); } +basic_json_parser_4: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; +basic_json_parser_5: + if (yybm[0+yych] & 32) { + goto basic_json_parser_4; + } + goto basic_json_parser_3; +basic_json_parser_6: + ++m_cursor; + { return token_type::begin_array; } +basic_json_parser_8: + ++m_cursor; + { return token_type::end_array; } +basic_json_parser_10: + ++m_cursor; + { return token_type::begin_object; } +basic_json_parser_12: + ++m_cursor; + { return token_type::end_object; } +basic_json_parser_14: + ++m_cursor; + { return token_type::value_separator; } +basic_json_parser_16: + ++m_cursor; + { return token_type::name_separator; } +basic_json_parser_18: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'u') goto basic_json_parser_59; +basic_json_parser_19: + { return token_type::parse_error; } +basic_json_parser_20: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'r') goto basic_json_parser_55; + goto basic_json_parser_19; +basic_json_parser_21: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'a') goto basic_json_parser_50; + goto basic_json_parser_19; +basic_json_parser_22: + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_19; + if (yych <= '0') goto basic_json_parser_49; + if (yych <= '9') goto basic_json_parser_40; + goto basic_json_parser_19; +basic_json_parser_23: + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') { + if (yych == '.') goto basic_json_parser_42; + } else { + if (yych <= 'E') goto basic_json_parser_43; + if (yych == 'e') goto basic_json_parser_43; + } +basic_json_parser_24: + { return token_type::value_number; } +basic_json_parser_25: + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + goto basic_json_parser_41; +basic_json_parser_26: + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych <= 0x0F) goto basic_json_parser_19; + goto basic_json_parser_31; +basic_json_parser_27: + ++m_cursor; + { return token_type::end_of_input; } +basic_json_parser_29: + yych = *++m_cursor; + goto basic_json_parser_19; +basic_json_parser_30: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; +basic_json_parser_31: + if (yybm[0+yych] & 64) { + goto basic_json_parser_30; + } + if (yych <= 0x0F) goto basic_json_parser_32; + if (yych <= '"') goto basic_json_parser_34; + goto basic_json_parser_33; +basic_json_parser_32: + m_cursor = m_marker; + if (yyaccept == 0) { + goto basic_json_parser_19; + } else { + goto basic_json_parser_24; + } +basic_json_parser_33: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= 'e') { + if (yych <= '/') { + if (yych == '"') goto basic_json_parser_30; + if (yych <= '.') goto basic_json_parser_32; + goto basic_json_parser_30; + } else { + if (yych <= '\\') { + if (yych <= '[') goto basic_json_parser_32; + goto basic_json_parser_30; + } else { + if (yych == 'b') goto basic_json_parser_30; + goto basic_json_parser_32; + } + } + } else { + if (yych <= 'q') { + if (yych <= 'f') goto basic_json_parser_30; + if (yych == 'n') goto basic_json_parser_30; + goto basic_json_parser_32; + } else { + if (yych <= 's') { + if (yych <= 'r') goto basic_json_parser_30; + goto basic_json_parser_32; + } else { + if (yych <= 't') goto basic_json_parser_30; + if (yych <= 'u') goto basic_json_parser_36; + goto basic_json_parser_32; + } + } + } +basic_json_parser_34: + ++m_cursor; + { return token_type::value_string; } +basic_json_parser_36: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '@') { + if (yych <= '/') goto basic_json_parser_32; + if (yych >= ':') goto basic_json_parser_32; + } else { + if (yych <= 'F') goto basic_json_parser_37; + if (yych <= '`') goto basic_json_parser_32; + if (yych >= 'g') goto basic_json_parser_32; + } +basic_json_parser_37: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '@') { + if (yych <= '/') goto basic_json_parser_32; + if (yych >= ':') goto basic_json_parser_32; + } else { + if (yych <= 'F') goto basic_json_parser_38; + if (yych <= '`') goto basic_json_parser_32; + if (yych >= 'g') goto basic_json_parser_32; + } +basic_json_parser_38: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '@') { + if (yych <= '/') goto basic_json_parser_32; + if (yych >= ':') goto basic_json_parser_32; + } else { + if (yych <= 'F') goto basic_json_parser_39; + if (yych <= '`') goto basic_json_parser_32; + if (yych >= 'g') goto basic_json_parser_32; + } +basic_json_parser_39: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '@') { + if (yych <= '/') goto basic_json_parser_32; + if (yych <= '9') goto basic_json_parser_30; + goto basic_json_parser_32; + } else { + if (yych <= 'F') goto basic_json_parser_30; + if (yych <= '`') goto basic_json_parser_32; + if (yych <= 'f') goto basic_json_parser_30; + goto basic_json_parser_32; + } +basic_json_parser_40: + yyaccept = 1; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; +basic_json_parser_41: + if (yybm[0+yych] & 128) { + goto basic_json_parser_40; + } + if (yych <= 'D') { + if (yych != '.') goto basic_json_parser_24; + } else { + if (yych <= 'E') goto basic_json_parser_43; + if (yych == 'e') goto basic_json_parser_43; + goto basic_json_parser_24; + } +basic_json_parser_42: + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_32; + if (yych <= '9') goto basic_json_parser_47; + goto basic_json_parser_32; +basic_json_parser_43: + yych = *++m_cursor; + if (yych <= ',') { + if (yych != '+') goto basic_json_parser_32; + } else { + if (yych <= '-') goto basic_json_parser_44; + if (yych <= '/') goto basic_json_parser_32; + if (yych <= '9') goto basic_json_parser_45; + goto basic_json_parser_32; + } +basic_json_parser_44: + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_32; + if (yych >= ':') goto basic_json_parser_32; +basic_json_parser_45: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '/') goto basic_json_parser_24; + if (yych <= '9') goto basic_json_parser_45; + goto basic_json_parser_24; +basic_json_parser_47: + yyaccept = 1; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= 'D') { + if (yych <= '/') goto basic_json_parser_24; + if (yych <= '9') goto basic_json_parser_47; + goto basic_json_parser_24; + } else { + if (yych <= 'E') goto basic_json_parser_43; + if (yych == 'e') goto basic_json_parser_43; + goto basic_json_parser_24; + } +basic_json_parser_49: + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') { + if (yych == '.') goto basic_json_parser_42; + goto basic_json_parser_24; + } else { + if (yych <= 'E') goto basic_json_parser_43; + if (yych == 'e') goto basic_json_parser_43; + goto basic_json_parser_24; + } +basic_json_parser_50: + yych = *++m_cursor; + if (yych != 'l') goto basic_json_parser_32; + yych = *++m_cursor; + if (yych != 's') goto basic_json_parser_32; + yych = *++m_cursor; + if (yych != 'e') goto basic_json_parser_32; + ++m_cursor; + { return token_type::literal_false; } +basic_json_parser_55: + yych = *++m_cursor; + if (yych != 'u') goto basic_json_parser_32; + yych = *++m_cursor; + if (yych != 'e') goto basic_json_parser_32; + ++m_cursor; + { return token_type::literal_true; } +basic_json_parser_59: + yych = *++m_cursor; + if (yych != 'l') goto basic_json_parser_32; + yych = *++m_cursor; + if (yych != 'l') goto basic_json_parser_32; + ++m_cursor; + { return token_type::literal_null; } + } } @@ -4878,7 +4963,12 @@ basic_json_parser_59: // presets // ///////////// -/// default JSON class +/*! +@brief default JSON class + +This type is the default specialization of the @ref basic_json class which uses +the standard template types. +*/ using json = basic_json<>; } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 0468076f..b1de4494 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -50,6 +50,9 @@ namespace nlohmann { +/// namespace with internal helper functions +namespace internals +{ // Helper to determine whether there's a key_type for T. // http://stackoverflow.com/a/7728728/266378 template @@ -61,9 +64,10 @@ struct has_mapped_type public: enum { value = sizeof(test(0)) == sizeof(char) }; }; +} /*! -@brief JSON +@brief a class to store JSON values @tparam ObjectType type for JSON objects (@c std::map by default) @@ -101,6 +105,9 @@ class basic_json // container types // ///////////////////// + /// @name container types + /// @{ + /// the type of elements in a basic_json container using value_type = basic_json; @@ -133,6 +140,9 @@ class basic_json /// a const reverse iterator for a basic_json container class const_reverse_iterator; + /// @} + + /// returns the allocator associated with the container static allocator_type get_allocator() { @@ -144,6 +154,9 @@ class basic_json // JSON value data types // /////////////////////////// + /// @name JSON value data types + /// @{ + /// a type for an object using object_t = ObjectType, AllocatorType>>; @@ -160,12 +173,19 @@ class basic_json /// a type for list initialization using list_init_t = std::initializer_list; + /// @} + ///////////////////////////////// // JSON value type enumeration // ///////////////////////////////// - /// JSON value type enumeration + /*! + @brief the JSON value type enumeration + + This enumeration collects the different JSON value types. It is used to + distinguish the stored values in the union @ref json_value. + */ enum class value_t : uint8_t { null, ///< null value @@ -178,6 +198,7 @@ class basic_json discarded ///< (internal) indicates the parser callback chose not to keep the value }; + //////////////////////// // JSON value storage // //////////////////////// @@ -341,9 +362,28 @@ class basic_json /*! @brief create an empty value with a given type - @param value the type to create an value of - @exception std::bad_alloc if allocation for object, array, or string fails. + Create an empty JSON value with a given type. The value will be default + initialized with an empty value which depends on the type: + + Value type | initial value + ----------- | ------------- + null | @c null + boolean | @c false + string | @c "" + number | @c 0 + object | @c {} + array | @c [] + + @param value the type of the value to create + + @complexity Constant. + + @exception std::bad_alloc if allocation for object, array, or string value + fails (thrown by the constructors of @ref json_value) + + @liveexample{The following code shows the constructor for different @ref + value_t values,basic_json__value_t} */ basic_json(const value_t value) : m_type(value), m_value(value) @@ -351,27 +391,93 @@ class basic_json /*! @brief create a null object (implicitly) + + Create a `null` JSON value. This is the implicit version of the `null` + value constructor as it takes no parameters. + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - As postcondition, it holds: `basic_json().empty() == true`. + + @liveexample{The following code shows the constructor for a `null` JSON + value.,basic_json} + + @sa basic_json(std::nullptr_t) @ingroup container */ basic_json() noexcept = default; - /// create a null object (explicitly) + /*! + @brief create a null object (explicitly) + + Create a `null` JSON value. This is the explicitly version of the `null` + value constructor as it takes a null pointer as parameter. It allows to + create `null` values by explicitly assigning a @c nullptr to a JSON value. + The passed null pointer itself is not read - it is only used to choose the + right constructor. + + @complexity Constant. + + @liveexample{The following code shows the constructor with null pointer + parameter.,basic_json__nullptr_t} + + @sa basic_json() + */ basic_json(std::nullptr_t) noexcept : basic_json(value_t::null) {} - /// create an object (explicit) + /*! + @brief create an object (explicit) + + Create an object JSON value with a given content. + + @param value a value for the object + + @complexity Linear in the size of the passed @a value. + + @exception std::bad_alloc if allocation for object value fails (thrown by + the constructor of @ref json_value) + + @liveexample{The following code shows the constructor with an @ref object_t + parameter.,basic_json__object_t} + + @sa basic_json(const CompatibleObjectType&) + */ basic_json(const object_t& value) : m_type(value_t::object), m_value(value) {} - /// create an object (implicit) - template ::value and - std::is_constructible::value, int>::type + std::is_constructible::value and + std::is_constructible::value, int>::type = 0> - basic_json(const V& value) + basic_json(const CompatibleObjectType& value) : m_type(value_t::object) { AllocatorType alloc; @@ -381,23 +487,60 @@ class basic_json alloc.construct(m_value.object, begin(value), end(value)); } - /// create an array (explicit) + /*! + @brief create an array (explicit) + + Create an array JSON value with a given content. + + @param value a value for the array + + @complexity Linear in the size of the passed @a value. + + @exception std::bad_alloc if allocation for array value fails (thrown by + the constructor of @ref json_value) + + @liveexample{The following code shows the constructor with an @ref array_t + parameter.,basic_json__array_t} + + @sa basic_json(const CompatibleArrayType&) + */ basic_json(const array_t& value) : m_type(value_t::array), m_value(value) {} - /// create an array (implicit) - template ::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - not std::is_same::value and - std::is_constructible::value, int>::type + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + not std::is_same::value and + std::is_constructible::value, int>::type = 0> - basic_json(const V& value) + basic_json(const CompatibleArrayType& value) : m_type(value_t::array) { AllocatorType alloc; @@ -675,7 +818,20 @@ class basic_json /*! @brief copy constructor - @exception std::bad_alloc if allocation for object, array, or string fails. + Creates a copy of a given JSON value. + + @param other the JSON value to copy + + @complexity Linear in the size of @a other. + + @requirement This function satisfies the Container requirements: + - The complexity is linear. + - As postcondition, it holds: `other == basic_json(other)`. + + @exception std::bad_alloc if allocation for object, array, or string fails. + + @liveexample{The following code shows an example for the copy + constructor.,basic_json__basic_json} @ingroup container */ @@ -740,6 +896,15 @@ class basic_json /*! @brief copy assignment + + The copy assignment operator is expressed in terms of the copy constructor, + destructor, and the swap() member function. + + @complexity Linear. + + @requirement This function satisfies the Container requirements: + - The complexity is linear. + @ingroup container */ reference& operator=(basic_json other) noexcept ( @@ -757,6 +922,15 @@ class basic_json /*! @brief destructor + + Destroys the JSON value and frees all memory. + + @complexity Linear. + + @requirement This function satisfies the Container requirements: + - The complexity is linear. + - All stored elements are destroyed and all memory is freed. + @ingroup container */ ~basic_json() noexcept @@ -804,6 +978,9 @@ class basic_json // object inspection // /////////////////////// + /// @name object inspection + /// @{ + /*! @brief serialization @@ -840,49 +1017,140 @@ class basic_json return m_type; } - // return whether value is null + /*! + @brief return whether value is null + + This function returns true iff the JSON value is null. + + @return `true` if value type is null, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_null for all JSON + value types.,is_null} + */ bool is_null() const noexcept { return m_type == value_t::null; } - // return whether value is boolean + /*! + @brief return whether value is a boolean + + This function returns true iff the JSON value is a boolean. + + @return `true` if value type is boolean, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_boolean for all JSON + value types.,is_boolean} + */ bool is_boolean() const noexcept { return m_type == value_t::boolean; } - // return whether value is number + /*! + @brief return whether value is a number + + This function returns true iff the JSON value is a number. This includes + both integer and floating-point values. + + @return `true` if value type is number, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_number for all JSON + value types.,is_number} + */ bool is_number() const noexcept { return (m_type == value_t::number_integer) or (m_type == value_t::number_float); } - // return whether value an integer is number + /*! + @brief return whether value is an integer number + + This function returns true iff the JSON value is an integer number. This + excludes floating-point values. + + @return `true` if value type is an integer number, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_number_integer for all + JSON value types.,is_number_integer} + */ bool is_number_integer() const noexcept { return m_type == value_t::number_integer; } - // return whether value is a floating-point number + /*! + @brief return whether value is a floating-point number + + This function returns true iff the JSON value is a floating-point number. + This excludes integer values. + + @return `true` if value type is a floating-point number, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_number_float for all + JSON value types.,is_number_float} + */ bool is_number_float() const noexcept { return m_type == value_t::number_float; } - // return whether value is object + /*! + @brief return whether value is an object + + This function returns true iff the JSON value is an object. + + @return `true` if value type is object, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_object for all JSON + value types.,is_object} + */ bool is_object() const noexcept { return m_type == value_t::object; } - // return whether value is array + /*! + @brief return whether value is an array + + This function returns true iff the JSON value is an array. + + @return `true` if value type is array, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_array for all JSON + value types.,is_array} + */ bool is_array() const noexcept { return m_type == value_t::array; } - // return whether value is string + /*! + @brief return whether value is a string + + This function returns true iff the JSON value is a string. + + @return `true` if value type is string, `false` otherwise. + + @complexity Constant. + + @liveexample{The following code exemplifies @ref is_string for all JSON + value types.,is_string} + */ bool is_string() const noexcept { return m_type == value_t::string; @@ -900,10 +1168,12 @@ class basic_json return m_type; } + /// @} + private: - ////////////////////// - // value conversion // - ////////////////////// + ////////////////// + // value access // + ////////////////// /// get an object (explicit) template ::value and not std::is_arithmetic::value and not std::is_convertible::value and - not has_mapped_type::value + not internals::has_mapped_type::value , int>::type = 0> T get_impl(T*) const { @@ -1004,7 +1274,7 @@ class basic_json template ::value and - not has_mapped_type::value + not internals::has_mapped_type::value , int>::type = 0> T get_impl(T*) const { @@ -1097,6 +1367,10 @@ class basic_json } public: + + /// @name value access + /// @{ + /// get a value (explicit) // template @@ -1112,11 +1386,16 @@ class basic_json return get(); } + /// @} + //////////////////// // element access // //////////////////// + /// @name element access + /// @{ + /// access specified element with bounds checking reference at(size_type idx) { @@ -1482,13 +1761,32 @@ class basic_json return (m_type == value_t::object) ? m_value.object->count(key) : 0; } + /// @} + /////////////// // iterators // /////////////// + /// @name iterators + /// @{ + /*! @brief returns an iterator to the first element + + Returns an iterator to the first element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return iterator to the first element + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + + @liveexample{The following code shows an example for @ref begin.,begin} + @ingroup container */ iterator begin() noexcept @@ -1499,7 +1797,7 @@ class basic_json } /*! - @brief returns a const iterator to the first element + @copydoc basic_json::cbegin() @ingroup container */ const_iterator begin() const noexcept @@ -1509,6 +1807,21 @@ class basic_json /*! @brief returns a const iterator to the first element + + Returns a const iterator to the first element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return const iterator to the first element + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).begin()`. + + @liveexample{The following code shows an example for @ref cbegin.,cbegin} + @ingroup container */ const_iterator cbegin() const noexcept @@ -1520,6 +1833,20 @@ class basic_json /*! @brief returns an iterator to one past the last element + + Returns an iterator to one past the last element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return iterator one past the last element + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + + @liveexample{The following code shows an example for @ref end.,end} + @ingroup container */ iterator end() noexcept @@ -1530,7 +1857,7 @@ class basic_json } /*! - @brief returns a const iterator to one past the last element + @copydoc basic_json::cend() @ingroup container */ const_iterator end() const noexcept @@ -1540,6 +1867,21 @@ class basic_json /*! @brief returns a const iterator to one past the last element + + Returns a const iterator to one past the last element. + + @image html range-begin-end.svg "Illustration from cppreference.com" + + @return const iterator one past the last element + + @complexity Constant. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).end()`. + + @liveexample{The following code shows an example for @ref cend.,cend} + @ingroup container */ const_iterator cend() const noexcept @@ -1550,7 +1892,20 @@ class basic_json } /*! - @brief returns a reverse iterator to the first element + @brief returns an iterator to the reverse-beginning + + Returns an iterator to the reverse-beginning; that is, the last element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function satisfies the ReversibleContainer requirements: + - The complexity is constant. + - Has the semantics of `reverse_iterator(end())`. + + @liveexample{The following code shows an example for @ref rbegin.,rbegin} + @ingroup reversiblecontainer */ reverse_iterator rbegin() noexcept @@ -1559,7 +1914,7 @@ class basic_json } /*! - @brief returns a const reverse iterator to the first element + @copydoc basic_json::crbegin() @ingroup reversiblecontainer */ const_reverse_iterator rbegin() const noexcept @@ -1568,7 +1923,21 @@ class basic_json } /*! - @brief returns a reverse iterator to one past the last element + @brief returns an iterator to the reverse-end + + Returns an iterator to the reverse-end; that is, one before the first + element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function satisfies the ReversibleContainer requirements: + - The complexity is constant. + - Has the semantics of `reverse_iterator(begin())`. + + @liveexample{The following code shows an example for @ref rend.,rend} + @ingroup reversiblecontainer */ reverse_iterator rend() noexcept @@ -1577,7 +1946,7 @@ class basic_json } /*! - @brief returns a const reverse iterator to one past the last element + @copydoc basic_json::crend() @ingroup reversiblecontainer */ const_reverse_iterator rend() const noexcept @@ -1586,7 +1955,21 @@ class basic_json } /*! - @brief returns a const reverse iterator to the first element + @brief returns a const reverse iterator to the last element + + Returns a const iterator to the reverse-beginning; that is, the last + element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function satisfies the ReversibleContainer requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).rbegin()`. + + @liveexample{The following code shows an example for @ref crbegin.,crbegin} + @ingroup reversiblecontainer */ const_reverse_iterator crbegin() const noexcept @@ -1595,7 +1978,21 @@ class basic_json } /*! - @brief returns a const reverse iterator to one past the last element + @brief returns a const reverse iterator to one before the first + + Returns a const reverse iterator to the reverse-end; that is, one before + the first element. + + @image html range-rbegin-rend.svg "Illustration from cppreference.com" + + @complexity Constant. + + @requirement This function satisfies the ReversibleContainer requirements: + - The complexity is constant. + - Has the semantics of `const_cast(*this).rend()`. + + @liveexample{The following code shows an example for @ref crend.,crend} + @ingroup reversiblecontainer */ const_reverse_iterator crend() const noexcept @@ -1603,13 +2000,43 @@ class basic_json return const_reverse_iterator(cbegin()); } + /// @} + ////////////// // capacity // ////////////// + /// @name capacity + /// @{ + /*! @brief checks whether the container is empty + + Checks if a JSON value has no elements. + + @return The return value depends on the different value types and is + defined as follows: + Value type | return value + ----------- | ------------- + null | @c true + boolean | @c false + string | @c false + number | @c false + object | result of function object_t::empty() + array | result of function array_t::empty() + + @complexity Constant, as long as @ref array_t and @ref object_t satisfy the + Container concept; that is, their empty() functions have + constant complexity. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - Has the semantics of `begin() == end()`. + + @liveexample{The following code uses @ref empty to check if a @ref json + object contains any elements.,empty} + @ingroup container */ bool empty() const noexcept @@ -1641,6 +2068,31 @@ class basic_json /*! @brief returns the number of elements + + Returns the number of elements in a JSON value. + + @return The return value depends on the different value types and is + defined as follows: + Value type | return value + ----------- | ------------- + null | @c 0 + boolean | @c 1 + string | @c 1 + number | @c 1 + object | result of function object_t::size() + array | result of function array_t::size() + + @complexity Constant, as long as @ref array_t and @ref object_t satisfy the + Container concept; that is, their size() functions have + constant complexity. + + @requirement This function satisfies the Container requirements: + - The complexity is constant. + - Has the semantics of `std::distance(begin(), end())`. + + @liveexample{The following code calls @ref size on the different value + types.,size} + @ingroup container */ size_type size() const noexcept @@ -1701,11 +2153,16 @@ class basic_json } } + /// @} + /////////////// // modifiers // /////////////// + /// @name modifiers + /// @{ + /// clears the contents void clear() noexcept { @@ -1892,11 +2349,16 @@ class basic_json std::swap(*(m_value.string), other); } + /// @} + ////////////////////////////////////////// // lexicographical comparison operators // ////////////////////////////////////////// + /// @name lexicographical comparison operators + /// @{ + /*! @brief comparison: equal @ingroup container @@ -2012,11 +2474,16 @@ class basic_json return not (lhs < rhs); } + /// @} + /////////////////// // serialization // /////////////////// + /// @name serialization + /// @{ + /// serialize to stream friend std::ostream& operator<<(std::ostream& o, const basic_json& j) { @@ -2038,11 +2505,16 @@ class basic_json return o << j; } + /// @} + ///////////////////// // deserialization // ///////////////////// + /// @name deserialization + /// @{ + /// deserialize from string static basic_json parse(const string_t& s, parser_callback_t cb = nullptr) { @@ -2069,6 +2541,8 @@ class basic_json return i; } + /// @} + private: /////////////////////////// @@ -4184,7 +4658,12 @@ class basic_json // presets // ///////////// -/// default JSON class +/*! +@brief default JSON class + +This type is the default specialization of the @ref basic_json class which uses +the standard template types. +*/ using json = basic_json<>; }