more documentation
In this commit, also the semantics for values skipped via the parser callback has changed. Now, the top-level value is returned as “null” instead of “discarded”.
This commit is contained in:
parent
48545f5b18
commit
457572184c
25 changed files with 856 additions and 60 deletions
|
@ -163,7 +163,7 @@ CHM_FILE =
|
||||||
HHC_LOCATION =
|
HHC_LOCATION =
|
||||||
GENERATE_CHI = NO
|
GENERATE_CHI = NO
|
||||||
CHM_INDEX_ENCODING =
|
CHM_INDEX_ENCODING =
|
||||||
BINARY_TOC = YES
|
BINARY_TOC = NO
|
||||||
TOC_EXPAND = NO
|
TOC_EXPAND = NO
|
||||||
GENERATE_QHP = NO
|
GENERATE_QHP = NO
|
||||||
QCH_FILE =
|
QCH_FILE =
|
||||||
|
@ -176,7 +176,7 @@ QHG_LOCATION =
|
||||||
GENERATE_ECLIPSEHELP = NO
|
GENERATE_ECLIPSEHELP = NO
|
||||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||||
DISABLE_INDEX = NO
|
DISABLE_INDEX = NO
|
||||||
GENERATE_TREEVIEW = YES
|
GENERATE_TREEVIEW = NO
|
||||||
ENUM_VALUES_PER_LINE = 4
|
ENUM_VALUES_PER_LINE = 4
|
||||||
TREEVIEW_WIDTH = 250
|
TREEVIEW_WIDTH = 250
|
||||||
EXT_LINKS_IN_WINDOW = NO
|
EXT_LINKS_IN_WINDOW = NO
|
||||||
|
|
|
@ -56,8 +56,6 @@ docset: create_output
|
||||||
cp Doxyfile Doxyfile_docset
|
cp Doxyfile Doxyfile_docset
|
||||||
gsed -i 's/DISABLE_INDEX = NO/DISABLE_INDEX = YES/' Doxyfile_docset
|
gsed -i 's/DISABLE_INDEX = NO/DISABLE_INDEX = YES/' Doxyfile_docset
|
||||||
gsed -i 's/SEARCHENGINE = YES/SEARCHENGINE = NO/' Doxyfile_docset
|
gsed -i 's/SEARCHENGINE = YES/SEARCHENGINE = NO/' Doxyfile_docset
|
||||||
gsed -i 's/GENERATE_TREEVIEW = YES/GENERATE_TREEVIEW = NO/' Doxyfile_docset
|
|
||||||
gsed -i 's/BINARY_TOC = YES/BINARY_TOC = NO/' Doxyfile_docset
|
|
||||||
gsed -i 's@HTML_EXTRA_STYLESHEET = css/mylayout.css@HTML_EXTRA_STYLESHEET = css/mylayout_docset.css@' Doxyfile_docset
|
gsed -i 's@HTML_EXTRA_STYLESHEET = css/mylayout.css@HTML_EXTRA_STYLESHEET = css/mylayout_docset.css@' Doxyfile_docset
|
||||||
rm -fr html *.docset
|
rm -fr html *.docset
|
||||||
doxygen Doxyfile_docset
|
doxygen Doxyfile_docset
|
||||||
|
|
33
doc/examples/at__object_t_key_type.cpp
Normal file
33
doc/examples/at__object_t_key_type.cpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create JSON object
|
||||||
|
json object =
|
||||||
|
{
|
||||||
|
{"the good", "il buono"},
|
||||||
|
{"the bad", "il cativo"},
|
||||||
|
{"the ugly", "il brutto"}
|
||||||
|
};
|
||||||
|
|
||||||
|
// output element with key "the ugly"
|
||||||
|
std::cout << object.at("the ugly") << '\n';
|
||||||
|
|
||||||
|
// change element with key "the bad"
|
||||||
|
object.at("the bad") = "il cattivo";
|
||||||
|
|
||||||
|
// output changed array
|
||||||
|
std::cout << object << '\n';
|
||||||
|
|
||||||
|
// try to write at a nonexisting key
|
||||||
|
try
|
||||||
|
{
|
||||||
|
object.at("the fast") = "il rapido";
|
||||||
|
}
|
||||||
|
catch (std::out_of_range)
|
||||||
|
{
|
||||||
|
std::cout << "out of range" << '\n';
|
||||||
|
}
|
||||||
|
}
|
3
doc/examples/at__object_t_key_type.output
Normal file
3
doc/examples/at__object_t_key_type.output
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
"il brutto"
|
||||||
|
{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"}
|
||||||
|
out of range
|
27
doc/examples/at__object_t_key_type_const.cpp
Normal file
27
doc/examples/at__object_t_key_type_const.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create JSON object
|
||||||
|
json object =
|
||||||
|
{
|
||||||
|
{"the good", "il buono"},
|
||||||
|
{"the bad", "il cativo"},
|
||||||
|
{"the ugly", "il brutto"}
|
||||||
|
};
|
||||||
|
|
||||||
|
// output element with key "the ugly"
|
||||||
|
std::cout << object.at("the ugly") << '\n';
|
||||||
|
|
||||||
|
// try to read from a nonexisting key
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::cout << object.at("the fast") << '\n';
|
||||||
|
}
|
||||||
|
catch (std::out_of_range)
|
||||||
|
{
|
||||||
|
std::cout << "out of range" << '\n';
|
||||||
|
}
|
||||||
|
}
|
2
doc/examples/at__object_t_key_type_const.output
Normal file
2
doc/examples/at__object_t_key_type_const.output
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
"il brutto"
|
||||||
|
out of range
|
28
doc/examples/at__size_type.cpp
Normal file
28
doc/examples/at__size_type.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create JSON array
|
||||||
|
json array = {"first", "2nd", "third", "fourth"};
|
||||||
|
|
||||||
|
// output element at index 2 (third element)
|
||||||
|
std::cout << array.at(2) << '\n';
|
||||||
|
|
||||||
|
// change element at index 1 (second element) to "second"
|
||||||
|
array.at(1) = "second";
|
||||||
|
|
||||||
|
// output changed array
|
||||||
|
std::cout << array << '\n';
|
||||||
|
|
||||||
|
// try to write beyond the array limit
|
||||||
|
try
|
||||||
|
{
|
||||||
|
array.at(5) = "sixth";
|
||||||
|
}
|
||||||
|
catch (std::out_of_range)
|
||||||
|
{
|
||||||
|
std::cout << "out of range" << '\n';
|
||||||
|
}
|
||||||
|
}
|
3
doc/examples/at__size_type.output
Normal file
3
doc/examples/at__size_type.output
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
"third"
|
||||||
|
["first","second","third","fourth"]
|
||||||
|
out of range
|
22
doc/examples/at__size_type_const.cpp
Normal file
22
doc/examples/at__size_type_const.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create JSON array
|
||||||
|
json array = {"first", "2nd", "third", "fourth"};
|
||||||
|
|
||||||
|
// output element at index 2 (third element)
|
||||||
|
std::cout << array.at(2) << '\n';
|
||||||
|
|
||||||
|
// try to read beyond the array limit
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::cout << array.at(5) << '\n';
|
||||||
|
}
|
||||||
|
catch (std::out_of_range)
|
||||||
|
{
|
||||||
|
std::cout << "out of range" << '\n';
|
||||||
|
}
|
||||||
|
}
|
2
doc/examples/at__size_type_const.output
Normal file
2
doc/examples/at__size_type_const.output
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
"third"
|
||||||
|
out of range
|
24
doc/examples/operatorarray__size_type.cpp
Normal file
24
doc/examples/operatorarray__size_type.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create a JSON array
|
||||||
|
json array = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
|
// output element at index 3 (fourth element)
|
||||||
|
std::cout << array[3] << '\n';
|
||||||
|
|
||||||
|
// change last element to 6
|
||||||
|
array[array.size() - 1] = 6;
|
||||||
|
|
||||||
|
// output changed array
|
||||||
|
std::cout << array << '\n';
|
||||||
|
|
||||||
|
// write beyond array limit
|
||||||
|
array[10] = 11;
|
||||||
|
|
||||||
|
// output changed array
|
||||||
|
std::cout << array << '\n';
|
||||||
|
}
|
3
doc/examples/operatorarray__size_type.output
Normal file
3
doc/examples/operatorarray__size_type.output
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
4
|
||||||
|
[1,2,3,4,6]
|
||||||
|
[1,2,3,4,6,null,null,null,null,null,11]
|
12
doc/examples/operatorarray__size_type_const.cpp
Normal file
12
doc/examples/operatorarray__size_type_const.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create JSON array
|
||||||
|
json array = {"first", "2nd", "third", "fourth"};
|
||||||
|
|
||||||
|
// output element at index 2 (third element)
|
||||||
|
std::cout << array.at(2) << '\n';
|
||||||
|
}
|
1
doc/examples/operatorarray__size_type_const.output
Normal file
1
doc/examples/operatorarray__size_type_const.output
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"third"
|
55
doc/examples/parse__istream__parser_callback_t.cpp
Normal file
55
doc/examples/parse__istream__parser_callback_t.cpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a JSON text
|
||||||
|
auto text = R"(
|
||||||
|
{
|
||||||
|
"Image": {
|
||||||
|
"Width": 800,
|
||||||
|
"Height": 600,
|
||||||
|
"Title": "View from 15th Floor",
|
||||||
|
"Thumbnail": {
|
||||||
|
"Url": "http://www.example.com/image/481989943",
|
||||||
|
"Height": 125,
|
||||||
|
"Width": 100
|
||||||
|
},
|
||||||
|
"Animated" : false,
|
||||||
|
"IDs": [116, 943, 234, 38793]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
// fill a stream with JSON text
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << text;
|
||||||
|
|
||||||
|
// parse and serialize JSON
|
||||||
|
json j_complete = json::parse(ss);
|
||||||
|
std::cout << std::setw(4) << j_complete << "\n\n";
|
||||||
|
|
||||||
|
|
||||||
|
// define parser callback
|
||||||
|
json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)
|
||||||
|
{
|
||||||
|
// skip object elements with key "Thumbnail"
|
||||||
|
if (event == json::parse_event_t::key and parsed == json("Thumbnail"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// fill a stream with JSON text
|
||||||
|
ss.clear();
|
||||||
|
ss << text;
|
||||||
|
|
||||||
|
// parse (with callback) and serialize JSON
|
||||||
|
json j_filtered = json::parse(ss, cb);
|
||||||
|
std::cout << std::setw(4) << j_filtered << '\n';
|
||||||
|
}
|
34
doc/examples/parse__istream__parser_callback_t.output
Normal file
34
doc/examples/parse__istream__parser_callback_t.output
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"Image": {
|
||||||
|
"Animated": false,
|
||||||
|
"Height": 600,
|
||||||
|
"IDs": [
|
||||||
|
116,
|
||||||
|
943,
|
||||||
|
234,
|
||||||
|
38793
|
||||||
|
],
|
||||||
|
"Thumbnail": {
|
||||||
|
"Height": 125,
|
||||||
|
"Url": "http://www.example.com/image/481989943",
|
||||||
|
"Width": 100
|
||||||
|
},
|
||||||
|
"Title": "View from 15th Floor",
|
||||||
|
"Width": 800
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
"Image": {
|
||||||
|
"Animated": false,
|
||||||
|
"Height": 600,
|
||||||
|
"IDs": [
|
||||||
|
116,
|
||||||
|
943,
|
||||||
|
234,
|
||||||
|
38793
|
||||||
|
],
|
||||||
|
"Title": "View from 15th Floor",
|
||||||
|
"Width": 800
|
||||||
|
}
|
||||||
|
}
|
47
doc/examples/parse__string__parser_callback_t.cpp
Normal file
47
doc/examples/parse__string__parser_callback_t.cpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a JSON text
|
||||||
|
std::string text = R"(
|
||||||
|
{
|
||||||
|
"Image": {
|
||||||
|
"Width": 800,
|
||||||
|
"Height": 600,
|
||||||
|
"Title": "View from 15th Floor",
|
||||||
|
"Thumbnail": {
|
||||||
|
"Url": "http://www.example.com/image/481989943",
|
||||||
|
"Height": 125,
|
||||||
|
"Width": 100
|
||||||
|
},
|
||||||
|
"Animated" : false,
|
||||||
|
"IDs": [116, 943, 234, 38793]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
// parse and serialize JSON
|
||||||
|
json j_complete = json::parse(text);
|
||||||
|
std::cout << std::setw(4) << j_complete << "\n\n";
|
||||||
|
|
||||||
|
|
||||||
|
// define parser callback
|
||||||
|
json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)
|
||||||
|
{
|
||||||
|
// skip object elements with key "Thumbnail"
|
||||||
|
if (event == json::parse_event_t::key and parsed == json("Thumbnail"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// parse (with callback) and serialize JSON
|
||||||
|
json j_filtered = json::parse(text, cb);
|
||||||
|
std::cout << std::setw(4) << j_filtered << '\n';
|
||||||
|
}
|
34
doc/examples/parse__string__parser_callback_t.output
Normal file
34
doc/examples/parse__string__parser_callback_t.output
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"Image": {
|
||||||
|
"Animated": false,
|
||||||
|
"Height": 600,
|
||||||
|
"IDs": [
|
||||||
|
116,
|
||||||
|
943,
|
||||||
|
234,
|
||||||
|
38793
|
||||||
|
],
|
||||||
|
"Thumbnail": {
|
||||||
|
"Height": 125,
|
||||||
|
"Url": "http://www.example.com/image/481989943",
|
||||||
|
"Width": 100
|
||||||
|
},
|
||||||
|
"Title": "View from 15th Floor",
|
||||||
|
"Width": 800
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
"Image": {
|
||||||
|
"Animated": false,
|
||||||
|
"Height": 600,
|
||||||
|
"IDs": [
|
||||||
|
116,
|
||||||
|
943,
|
||||||
|
234,
|
||||||
|
38793
|
||||||
|
],
|
||||||
|
"Title": "View from 15th Floor",
|
||||||
|
"Width": 800
|
||||||
|
}
|
||||||
|
}
|
19
doc/examples/swap__array_t.cpp
Normal file
19
doc/examples/swap__array_t.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create a JSON value
|
||||||
|
json value = {{"array", {1, 2, 3, 4}}};
|
||||||
|
|
||||||
|
// create an array_t
|
||||||
|
json::array_t array = {"Snap", "Crackle", "Pop"};
|
||||||
|
|
||||||
|
// swap the array stored in the JSON value
|
||||||
|
value["array"].swap(array);
|
||||||
|
|
||||||
|
// output the values
|
||||||
|
std::cout << "value = " << value << '\n';
|
||||||
|
std::cout << "array = " << array << '\n';
|
||||||
|
}
|
2
doc/examples/swap__array_t.output
Normal file
2
doc/examples/swap__array_t.output
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
value = {"array":["Snap","Crackle","Pop"]}
|
||||||
|
array = [1,2,3,4]
|
17
doc/examples/swap__reference.cpp
Normal file
17
doc/examples/swap__reference.cpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// create two JSON values
|
||||||
|
json j1 = {1, 2, 3, 4, 5};
|
||||||
|
json j2 = {{"pi", 3.141592653589793}, {"e", 2.718281828459045}};
|
||||||
|
|
||||||
|
// swap the values
|
||||||
|
j1.swap(j2);
|
||||||
|
|
||||||
|
// output the values
|
||||||
|
std::cout << "j1 = " << j1 << '\n';
|
||||||
|
std::cout << "j2 = " << j2 << '\n';
|
||||||
|
}
|
2
doc/examples/swap__reference.output
Normal file
2
doc/examples/swap__reference.output
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
j1 = {"e":2.71828182845905,"pi":3.14159265358979}
|
||||||
|
j2 = [1,2,3,4,5]
|
260
src/json.hpp
260
src/json.hpp
|
@ -336,20 +336,77 @@ class basic_json
|
||||||
// JSON parser callback //
|
// JSON parser callback //
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
/// JSON callback event enumeration
|
/*!
|
||||||
|
@brief JSON callback events
|
||||||
|
|
||||||
|
This enumeration lists the parser events that can trigger calling a
|
||||||
|
callback function of type @ref parser_callback_t during parsing.
|
||||||
|
*/
|
||||||
enum class parse_event_t : uint8_t
|
enum class parse_event_t : uint8_t
|
||||||
{
|
{
|
||||||
object_start, ///< start an object scope (found a '{' token)
|
/// the parser read `{` and started to process a JSON object
|
||||||
object_end, ///< end of an object scope (found '}' token)
|
object_start,
|
||||||
array_start, ///< start of an array scope (found '[' token)
|
/// the parser read `}` and finished processing a JSON object
|
||||||
array_end, ///< end of an array scope (found ']' token)
|
object_end,
|
||||||
key, ///< found an object key within an object scope
|
/// the parser read `[` and started to process a JSON array
|
||||||
value ///< a value in an appropriate context (i.e., following a tag in an object scope)
|
array_start,
|
||||||
|
/// the parser read `]` and finished processing a JSON array
|
||||||
|
array_end,
|
||||||
|
/// the parser read a key of a value in an object
|
||||||
|
key,
|
||||||
|
/// the parser finished reading a JSON value
|
||||||
|
value
|
||||||
};
|
};
|
||||||
|
|
||||||
/// per-element parser callback type
|
/*!
|
||||||
using parser_callback_t = std::function<bool(int depth, parse_event_t event,
|
@brief per-element parser callback type
|
||||||
const basic_json& parsed)>;
|
|
||||||
|
With a parser callback function, the result of parsing a JSON text can be
|
||||||
|
influenced. When passed to @ref parse(std::istream&, parser_callback_t) or
|
||||||
|
@ref parse(const string_t&, parser_callback_t), it is called on certain
|
||||||
|
events (passed as @ref parse_event_t via parameter @a event) with a set
|
||||||
|
recursion depth @a depth and context JSON value @a parsed. The return value
|
||||||
|
of the callback function is a boolean indicating whether the element that
|
||||||
|
emitted the callback shall be kept or not.
|
||||||
|
|
||||||
|
We distinguish six scenarios (determined by the event type) in which the
|
||||||
|
callback function can be called. The following table describes the values
|
||||||
|
of the parameters @a depth, @a event, and @a parsed.
|
||||||
|
|
||||||
|
parameter @a event | description | parameter @a depth | parameter @a parsed
|
||||||
|
------------------ | ----------- | ------------------ | -------------------
|
||||||
|
parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
|
||||||
|
parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
|
||||||
|
parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
|
||||||
|
parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
|
||||||
|
parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
|
||||||
|
parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
|
||||||
|
|
||||||
|
Discarding a value (i.e., returning `false`) has different effects depending on the
|
||||||
|
context in which function was called:
|
||||||
|
|
||||||
|
- Discarded values in structured types are skipped. That is, the parser
|
||||||
|
will behave as if the discarded value was never read.
|
||||||
|
- In case a value outside a structured type is skipped, it is replaced with
|
||||||
|
`null`. This case happens if the top-level element is skipped.
|
||||||
|
|
||||||
|
@param[in] depth the depth of the recursion during parsing
|
||||||
|
|
||||||
|
@param[in] event an event of type parse_event_t indicating the context in
|
||||||
|
the callback function has been called
|
||||||
|
|
||||||
|
@param[in,out] parsed the current intermediate parse result; note that
|
||||||
|
writing to this value has no effect for parse_event_t::key events
|
||||||
|
|
||||||
|
@return Whether the JSON value which called the function during parsing
|
||||||
|
should be kept (`true`) or not (`false`). In the latter case, it is either
|
||||||
|
skipped completely or replaced by an empty discarded object.
|
||||||
|
|
||||||
|
@sa @ref parse(std::istream&, parser_callback_t) or
|
||||||
|
@ref parse(const string_t&, parser_callback_t) for examples
|
||||||
|
*/
|
||||||
|
using parser_callback_t = std::function<bool(
|
||||||
|
int depth, parse_event_t event, basic_json& parsed)>;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief comparison operator for JSON value types
|
@brief comparison operator for JSON value types
|
||||||
|
@ -1760,7 +1817,25 @@ class basic_json
|
||||||
/// @name element access
|
/// @name element access
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// access specified element with bounds checking
|
/*!
|
||||||
|
@brief access specified array element with bounds checking
|
||||||
|
|
||||||
|
Returns a reference to the element at specified location @a idx, with
|
||||||
|
bounds checking.
|
||||||
|
|
||||||
|
@param[in] idx index of the element to access
|
||||||
|
|
||||||
|
@return reference to the element at index @a idx
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an array
|
||||||
|
@throw std::out_of_range if the index @a idx is out of range of the array;
|
||||||
|
that is, `idx >= size()`
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how array elements can be read and
|
||||||
|
written using at.,at__size_type}
|
||||||
|
*/
|
||||||
reference at(size_type idx)
|
reference at(size_type idx)
|
||||||
{
|
{
|
||||||
// at only works for arrays
|
// at only works for arrays
|
||||||
|
@ -1772,7 +1847,25 @@ class basic_json
|
||||||
return m_value.array->at(idx);
|
return m_value.array->at(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element with bounds checking
|
/*!
|
||||||
|
@brief access specified array element with bounds checking
|
||||||
|
|
||||||
|
Returns a const reference to the element at specified location @a idx, with
|
||||||
|
bounds checking.
|
||||||
|
|
||||||
|
@param[in] idx index of the element to access
|
||||||
|
|
||||||
|
@return const reference to the element at index @a idx
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an array
|
||||||
|
@throw std::out_of_range if the index @a idx is out of range of the array;
|
||||||
|
that is, `idx >= size()`
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how array elements can be read using
|
||||||
|
at.,at__size_type_const}
|
||||||
|
*/
|
||||||
const_reference at(size_type idx) const
|
const_reference at(size_type idx) const
|
||||||
{
|
{
|
||||||
// at only works for arrays
|
// at only works for arrays
|
||||||
|
@ -1784,7 +1877,25 @@ class basic_json
|
||||||
return m_value.array->at(idx);
|
return m_value.array->at(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element with bounds checking
|
/*!
|
||||||
|
@brief access specified object element with bounds checking
|
||||||
|
|
||||||
|
Returns a reference to the element at with specified key @a key, with
|
||||||
|
bounds checking.
|
||||||
|
|
||||||
|
@param[in] key key of the element to access
|
||||||
|
|
||||||
|
@return reference to the element at key @a key
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an object
|
||||||
|
@throw std::out_of_range if the key @a key is is not stored in the object;
|
||||||
|
that is, `find(key) == end()`
|
||||||
|
|
||||||
|
@complexity Logarithmic in the size of the container.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how object elements can be read and
|
||||||
|
written using at.,at__object_t_key_type}
|
||||||
|
*/
|
||||||
reference at(const typename object_t::key_type& key)
|
reference at(const typename object_t::key_type& key)
|
||||||
{
|
{
|
||||||
// at only works for objects
|
// at only works for objects
|
||||||
|
@ -1796,7 +1907,25 @@ class basic_json
|
||||||
return m_value.object->at(key);
|
return m_value.object->at(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element with bounds checking
|
/*!
|
||||||
|
@brief access specified object element with bounds checking
|
||||||
|
|
||||||
|
Returns a const reference to the element at with specified key @a key, with
|
||||||
|
bounds checking.
|
||||||
|
|
||||||
|
@param[in] key key of the element to access
|
||||||
|
|
||||||
|
@return const reference to the element at key @a key
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an object
|
||||||
|
@throw std::out_of_range if the key @a key is is not stored in the object;
|
||||||
|
that is, `find(key) == end()`
|
||||||
|
|
||||||
|
@complexity Logarithmic in the size of the container.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how object elements can be read using
|
||||||
|
at.,at__object_t_key_type_const}
|
||||||
|
*/
|
||||||
const_reference at(const typename object_t::key_type& key) const
|
const_reference at(const typename object_t::key_type& key) const
|
||||||
{
|
{
|
||||||
// at only works for objects
|
// at only works for objects
|
||||||
|
@ -1808,7 +1937,28 @@ class basic_json
|
||||||
return m_value.object->at(key);
|
return m_value.object->at(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element
|
/*!
|
||||||
|
@brief access specified array element
|
||||||
|
|
||||||
|
Returns a reference to the element at specified location @a idx.
|
||||||
|
|
||||||
|
@note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
|
||||||
|
then the array is silently filled up with `null` values to make `idx` a
|
||||||
|
valid reference to the last stored element.
|
||||||
|
|
||||||
|
@param[in] idx index of the element to access
|
||||||
|
|
||||||
|
@return reference to the element at index @a idx
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an array or null
|
||||||
|
|
||||||
|
@complexity Constant if @a idx is in the range of the array. Otherwise
|
||||||
|
linear in `idx - size()`.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how array elements can be read and
|
||||||
|
written using [] operator. Note the addition of `null`
|
||||||
|
values.,operatorarray__size_type}
|
||||||
|
*/
|
||||||
reference operator[](size_type idx)
|
reference operator[](size_type idx)
|
||||||
{
|
{
|
||||||
// implicitly convert null to object
|
// implicitly convert null to object
|
||||||
|
@ -1834,7 +1984,22 @@ class basic_json
|
||||||
return m_value.array->operator[](idx);
|
return m_value.array->operator[](idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element
|
/*!
|
||||||
|
@brief access specified array element
|
||||||
|
|
||||||
|
Returns a const reference to the element at specified location @a idx.
|
||||||
|
|
||||||
|
@param[in] idx index of the element to access
|
||||||
|
|
||||||
|
@return const reference to the element at index @a idx
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an array
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how array elements can be read using
|
||||||
|
the [] operator.,operatorarray__size_type_const}
|
||||||
|
*/
|
||||||
const_reference operator[](size_type idx) const
|
const_reference operator[](size_type idx) const
|
||||||
{
|
{
|
||||||
// at only works for arrays
|
// at only works for arrays
|
||||||
|
@ -2750,6 +2915,19 @@ class basic_json
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief exchanges the values
|
@brief exchanges the values
|
||||||
|
|
||||||
|
Exchanges the contents of the JSON value with those of @a other. Does not
|
||||||
|
invoke any move, copy, or swap operations on individual elements. All
|
||||||
|
iterators and references remain valid. The past-the-end iterator is
|
||||||
|
invalidated.
|
||||||
|
|
||||||
|
@param[in,out] other JSON value to exchange the contents with
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how JSON arrays can be
|
||||||
|
swapped.,swap__reference}
|
||||||
|
|
||||||
@ingroup container
|
@ingroup container
|
||||||
*/
|
*/
|
||||||
void swap(reference other) noexcept (
|
void swap(reference other) noexcept (
|
||||||
|
@ -2763,7 +2941,25 @@ class basic_json
|
||||||
std::swap(m_value, other.m_value);
|
std::swap(m_value, other.m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// swaps the contents
|
/*!
|
||||||
|
@brief exchanges the values
|
||||||
|
|
||||||
|
Exchanges the contents of a JSON array with those of @a other. Does not
|
||||||
|
invoke any move, copy, or swap operations on individual elements. All
|
||||||
|
iterators and references remain valid. The past-the-end iterator is
|
||||||
|
invalidated.
|
||||||
|
|
||||||
|
@param[in,out] other array to exchange the contents with
|
||||||
|
|
||||||
|
@throw std::domain_error when JSON value is not an array
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how JSON values can be
|
||||||
|
swapped.,swap__array_t}
|
||||||
|
|
||||||
|
@ingroup container
|
||||||
|
*/
|
||||||
void swap(array_t& other)
|
void swap(array_t& other)
|
||||||
{
|
{
|
||||||
// swap only works for arrays
|
// swap only works for arrays
|
||||||
|
@ -3082,8 +3278,9 @@ class basic_json
|
||||||
@brief deserialize from string
|
@brief deserialize from string
|
||||||
|
|
||||||
@param[in] s string to read a serialized JSON value from
|
@param[in] s string to read a serialized JSON value from
|
||||||
@param[in] cb a parser callback function of type parser_callback_t which is
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
used to control the deserialization by filtering unwanted values (optional)
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
|
||||||
@return result of the deserialization
|
@return result of the deserialization
|
||||||
|
|
||||||
|
@ -3091,7 +3288,8 @@ class basic_json
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
@a cb has a super-linear complexity.
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
@todo Add example.
|
@liveexample{The example below demonstrates the parse function with and
|
||||||
|
without callback function.,parse__string__parser_callback_t}
|
||||||
|
|
||||||
@sa parse(std::istream&, parser_callback_t) for a version that reads from
|
@sa parse(std::istream&, parser_callback_t) for a version that reads from
|
||||||
an input stream
|
an input stream
|
||||||
|
@ -3105,8 +3303,9 @@ class basic_json
|
||||||
@brief deserialize from stream
|
@brief deserialize from stream
|
||||||
|
|
||||||
@param[in,out] i stream to read a serialized JSON value from
|
@param[in,out] i stream to read a serialized JSON value from
|
||||||
@param[in] cb a parser callback function of type parser_callback_t which is
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
used to control the deserialization by filtering unwanted values (optional)
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
|
||||||
@return result of the deserialization
|
@return result of the deserialization
|
||||||
|
|
||||||
|
@ -3114,7 +3313,8 @@ class basic_json
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
@a cb has a super-linear complexity.
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
@todo Add example.
|
@liveexample{The example below demonstrates the parse function with and
|
||||||
|
without callback function.,parse__istream__parser_callback_t}
|
||||||
|
|
||||||
@sa parse(const string_t&, parser_callback_t) for a version that reads
|
@sa parse(const string_t&, parser_callback_t) for a version that reads
|
||||||
from a string
|
from a string
|
||||||
|
@ -5710,7 +5910,9 @@ basic_json_parser_59:
|
||||||
|
|
||||||
expect(lexer::token_type::end_of_input);
|
expect(lexer::token_type::end_of_input);
|
||||||
|
|
||||||
return result;
|
// return parser result and replace it with null in case the
|
||||||
|
// top-level value was discarded by the callback function
|
||||||
|
return result.is_discarded() ? basic_json() : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -5763,7 +5965,15 @@ basic_json_parser_59:
|
||||||
bool keep_tag = false;
|
bool keep_tag = false;
|
||||||
if (keep)
|
if (keep)
|
||||||
{
|
{
|
||||||
keep_tag = callback ? callback(depth, parse_event_t::key, basic_json(key)) : true;
|
if (callback)
|
||||||
|
{
|
||||||
|
basic_json k(key);
|
||||||
|
keep_tag = callback(depth, parse_event_t::key, k);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keep_tag = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse separator (:)
|
// parse separator (:)
|
||||||
|
|
|
@ -336,20 +336,77 @@ class basic_json
|
||||||
// JSON parser callback //
|
// JSON parser callback //
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
/// JSON callback event enumeration
|
/*!
|
||||||
|
@brief JSON callback events
|
||||||
|
|
||||||
|
This enumeration lists the parser events that can trigger calling a
|
||||||
|
callback function of type @ref parser_callback_t during parsing.
|
||||||
|
*/
|
||||||
enum class parse_event_t : uint8_t
|
enum class parse_event_t : uint8_t
|
||||||
{
|
{
|
||||||
object_start, ///< start an object scope (found a '{' token)
|
/// the parser read `{` and started to process a JSON object
|
||||||
object_end, ///< end of an object scope (found '}' token)
|
object_start,
|
||||||
array_start, ///< start of an array scope (found '[' token)
|
/// the parser read `}` and finished processing a JSON object
|
||||||
array_end, ///< end of an array scope (found ']' token)
|
object_end,
|
||||||
key, ///< found an object key within an object scope
|
/// the parser read `[` and started to process a JSON array
|
||||||
value ///< a value in an appropriate context (i.e., following a tag in an object scope)
|
array_start,
|
||||||
|
/// the parser read `]` and finished processing a JSON array
|
||||||
|
array_end,
|
||||||
|
/// the parser read a key of a value in an object
|
||||||
|
key,
|
||||||
|
/// the parser finished reading a JSON value
|
||||||
|
value
|
||||||
};
|
};
|
||||||
|
|
||||||
/// per-element parser callback type
|
/*!
|
||||||
using parser_callback_t = std::function<bool(int depth, parse_event_t event,
|
@brief per-element parser callback type
|
||||||
const basic_json& parsed)>;
|
|
||||||
|
With a parser callback function, the result of parsing a JSON text can be
|
||||||
|
influenced. When passed to @ref parse(std::istream&, parser_callback_t) or
|
||||||
|
@ref parse(const string_t&, parser_callback_t), it is called on certain
|
||||||
|
events (passed as @ref parse_event_t via parameter @a event) with a set
|
||||||
|
recursion depth @a depth and context JSON value @a parsed. The return value
|
||||||
|
of the callback function is a boolean indicating whether the element that
|
||||||
|
emitted the callback shall be kept or not.
|
||||||
|
|
||||||
|
We distinguish six scenarios (determined by the event type) in which the
|
||||||
|
callback function can be called. The following table describes the values
|
||||||
|
of the parameters @a depth, @a event, and @a parsed.
|
||||||
|
|
||||||
|
parameter @a event | description | parameter @a depth | parameter @a parsed
|
||||||
|
------------------ | ----------- | ------------------ | -------------------
|
||||||
|
parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
|
||||||
|
parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
|
||||||
|
parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
|
||||||
|
parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
|
||||||
|
parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
|
||||||
|
parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
|
||||||
|
|
||||||
|
Discarding a value (i.e., returning `false`) has different effects depending on the
|
||||||
|
context in which function was called:
|
||||||
|
|
||||||
|
- Discarded values in structured types are skipped. That is, the parser
|
||||||
|
will behave as if the discarded value was never read.
|
||||||
|
- In case a value outside a structured type is skipped, it is replaced with
|
||||||
|
`null`. This case happens if the top-level element is skipped.
|
||||||
|
|
||||||
|
@param[in] depth the depth of the recursion during parsing
|
||||||
|
|
||||||
|
@param[in] event an event of type parse_event_t indicating the context in
|
||||||
|
the callback function has been called
|
||||||
|
|
||||||
|
@param[in,out] parsed the current intermediate parse result; note that
|
||||||
|
writing to this value has no effect for parse_event_t::key events
|
||||||
|
|
||||||
|
@return Whether the JSON value which called the function during parsing
|
||||||
|
should be kept (`true`) or not (`false`). In the latter case, it is either
|
||||||
|
skipped completely or replaced by an empty discarded object.
|
||||||
|
|
||||||
|
@sa @ref parse(std::istream&, parser_callback_t) or
|
||||||
|
@ref parse(const string_t&, parser_callback_t) for examples
|
||||||
|
*/
|
||||||
|
using parser_callback_t = std::function<bool(
|
||||||
|
int depth, parse_event_t event, basic_json& parsed)>;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief comparison operator for JSON value types
|
@brief comparison operator for JSON value types
|
||||||
|
@ -1760,7 +1817,25 @@ class basic_json
|
||||||
/// @name element access
|
/// @name element access
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// access specified element with bounds checking
|
/*!
|
||||||
|
@brief access specified array element with bounds checking
|
||||||
|
|
||||||
|
Returns a reference to the element at specified location @a idx, with
|
||||||
|
bounds checking.
|
||||||
|
|
||||||
|
@param[in] idx index of the element to access
|
||||||
|
|
||||||
|
@return reference to the element at index @a idx
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an array
|
||||||
|
@throw std::out_of_range if the index @a idx is out of range of the array;
|
||||||
|
that is, `idx >= size()`
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how array elements can be read and
|
||||||
|
written using at.,at__size_type}
|
||||||
|
*/
|
||||||
reference at(size_type idx)
|
reference at(size_type idx)
|
||||||
{
|
{
|
||||||
// at only works for arrays
|
// at only works for arrays
|
||||||
|
@ -1772,7 +1847,25 @@ class basic_json
|
||||||
return m_value.array->at(idx);
|
return m_value.array->at(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element with bounds checking
|
/*!
|
||||||
|
@brief access specified array element with bounds checking
|
||||||
|
|
||||||
|
Returns a const reference to the element at specified location @a idx, with
|
||||||
|
bounds checking.
|
||||||
|
|
||||||
|
@param[in] idx index of the element to access
|
||||||
|
|
||||||
|
@return const reference to the element at index @a idx
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an array
|
||||||
|
@throw std::out_of_range if the index @a idx is out of range of the array;
|
||||||
|
that is, `idx >= size()`
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how array elements can be read using
|
||||||
|
at.,at__size_type_const}
|
||||||
|
*/
|
||||||
const_reference at(size_type idx) const
|
const_reference at(size_type idx) const
|
||||||
{
|
{
|
||||||
// at only works for arrays
|
// at only works for arrays
|
||||||
|
@ -1784,7 +1877,25 @@ class basic_json
|
||||||
return m_value.array->at(idx);
|
return m_value.array->at(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element with bounds checking
|
/*!
|
||||||
|
@brief access specified object element with bounds checking
|
||||||
|
|
||||||
|
Returns a reference to the element at with specified key @a key, with
|
||||||
|
bounds checking.
|
||||||
|
|
||||||
|
@param[in] key key of the element to access
|
||||||
|
|
||||||
|
@return reference to the element at key @a key
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an object
|
||||||
|
@throw std::out_of_range if the key @a key is is not stored in the object;
|
||||||
|
that is, `find(key) == end()`
|
||||||
|
|
||||||
|
@complexity Logarithmic in the size of the container.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how object elements can be read and
|
||||||
|
written using at.,at__object_t_key_type}
|
||||||
|
*/
|
||||||
reference at(const typename object_t::key_type& key)
|
reference at(const typename object_t::key_type& key)
|
||||||
{
|
{
|
||||||
// at only works for objects
|
// at only works for objects
|
||||||
|
@ -1796,7 +1907,25 @@ class basic_json
|
||||||
return m_value.object->at(key);
|
return m_value.object->at(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element with bounds checking
|
/*!
|
||||||
|
@brief access specified object element with bounds checking
|
||||||
|
|
||||||
|
Returns a const reference to the element at with specified key @a key, with
|
||||||
|
bounds checking.
|
||||||
|
|
||||||
|
@param[in] key key of the element to access
|
||||||
|
|
||||||
|
@return const reference to the element at key @a key
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an object
|
||||||
|
@throw std::out_of_range if the key @a key is is not stored in the object;
|
||||||
|
that is, `find(key) == end()`
|
||||||
|
|
||||||
|
@complexity Logarithmic in the size of the container.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how object elements can be read using
|
||||||
|
at.,at__object_t_key_type_const}
|
||||||
|
*/
|
||||||
const_reference at(const typename object_t::key_type& key) const
|
const_reference at(const typename object_t::key_type& key) const
|
||||||
{
|
{
|
||||||
// at only works for objects
|
// at only works for objects
|
||||||
|
@ -1808,7 +1937,28 @@ class basic_json
|
||||||
return m_value.object->at(key);
|
return m_value.object->at(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element
|
/*!
|
||||||
|
@brief access specified array element
|
||||||
|
|
||||||
|
Returns a reference to the element at specified location @a idx.
|
||||||
|
|
||||||
|
@note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
|
||||||
|
then the array is silently filled up with `null` values to make `idx` a
|
||||||
|
valid reference to the last stored element.
|
||||||
|
|
||||||
|
@param[in] idx index of the element to access
|
||||||
|
|
||||||
|
@return reference to the element at index @a idx
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an array or null
|
||||||
|
|
||||||
|
@complexity Constant if @a idx is in the range of the array. Otherwise
|
||||||
|
linear in `idx - size()`.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how array elements can be read and
|
||||||
|
written using [] operator. Note the addition of `null`
|
||||||
|
values.,operatorarray__size_type}
|
||||||
|
*/
|
||||||
reference operator[](size_type idx)
|
reference operator[](size_type idx)
|
||||||
{
|
{
|
||||||
// implicitly convert null to object
|
// implicitly convert null to object
|
||||||
|
@ -1834,7 +1984,22 @@ class basic_json
|
||||||
return m_value.array->operator[](idx);
|
return m_value.array->operator[](idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// access specified element
|
/*!
|
||||||
|
@brief access specified array element
|
||||||
|
|
||||||
|
Returns a const reference to the element at specified location @a idx.
|
||||||
|
|
||||||
|
@param[in] idx index of the element to access
|
||||||
|
|
||||||
|
@return const reference to the element at index @a idx
|
||||||
|
|
||||||
|
@throw std::domain_error if JSON is not an array
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how array elements can be read using
|
||||||
|
the [] operator.,operatorarray__size_type_const}
|
||||||
|
*/
|
||||||
const_reference operator[](size_type idx) const
|
const_reference operator[](size_type idx) const
|
||||||
{
|
{
|
||||||
// at only works for arrays
|
// at only works for arrays
|
||||||
|
@ -2750,6 +2915,19 @@ class basic_json
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief exchanges the values
|
@brief exchanges the values
|
||||||
|
|
||||||
|
Exchanges the contents of the JSON value with those of @a other. Does not
|
||||||
|
invoke any move, copy, or swap operations on individual elements. All
|
||||||
|
iterators and references remain valid. The past-the-end iterator is
|
||||||
|
invalidated.
|
||||||
|
|
||||||
|
@param[in,out] other JSON value to exchange the contents with
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how JSON arrays can be
|
||||||
|
swapped.,swap__reference}
|
||||||
|
|
||||||
@ingroup container
|
@ingroup container
|
||||||
*/
|
*/
|
||||||
void swap(reference other) noexcept (
|
void swap(reference other) noexcept (
|
||||||
|
@ -2763,7 +2941,25 @@ class basic_json
|
||||||
std::swap(m_value, other.m_value);
|
std::swap(m_value, other.m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// swaps the contents
|
/*!
|
||||||
|
@brief exchanges the values
|
||||||
|
|
||||||
|
Exchanges the contents of a JSON array with those of @a other. Does not
|
||||||
|
invoke any move, copy, or swap operations on individual elements. All
|
||||||
|
iterators and references remain valid. The past-the-end iterator is
|
||||||
|
invalidated.
|
||||||
|
|
||||||
|
@param[in,out] other array to exchange the contents with
|
||||||
|
|
||||||
|
@throw std::domain_error when JSON value is not an array
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@liveexample{The example below shows how JSON values can be
|
||||||
|
swapped.,swap__array_t}
|
||||||
|
|
||||||
|
@ingroup container
|
||||||
|
*/
|
||||||
void swap(array_t& other)
|
void swap(array_t& other)
|
||||||
{
|
{
|
||||||
// swap only works for arrays
|
// swap only works for arrays
|
||||||
|
@ -3082,8 +3278,9 @@ class basic_json
|
||||||
@brief deserialize from string
|
@brief deserialize from string
|
||||||
|
|
||||||
@param[in] s string to read a serialized JSON value from
|
@param[in] s string to read a serialized JSON value from
|
||||||
@param[in] cb a parser callback function of type parser_callback_t which is
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
used to control the deserialization by filtering unwanted values (optional)
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
|
||||||
@return result of the deserialization
|
@return result of the deserialization
|
||||||
|
|
||||||
|
@ -3091,7 +3288,8 @@ class basic_json
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
@a cb has a super-linear complexity.
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
@todo Add example.
|
@liveexample{The example below demonstrates the parse function with and
|
||||||
|
without callback function.,parse__string__parser_callback_t}
|
||||||
|
|
||||||
@sa parse(std::istream&, parser_callback_t) for a version that reads from
|
@sa parse(std::istream&, parser_callback_t) for a version that reads from
|
||||||
an input stream
|
an input stream
|
||||||
|
@ -3105,8 +3303,9 @@ class basic_json
|
||||||
@brief deserialize from stream
|
@brief deserialize from stream
|
||||||
|
|
||||||
@param[in,out] i stream to read a serialized JSON value from
|
@param[in,out] i stream to read a serialized JSON value from
|
||||||
@param[in] cb a parser callback function of type parser_callback_t which is
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
used to control the deserialization by filtering unwanted values (optional)
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
|
||||||
@return result of the deserialization
|
@return result of the deserialization
|
||||||
|
|
||||||
|
@ -3114,7 +3313,8 @@ class basic_json
|
||||||
LL(1) parser. The complexity can be higher if the parser callback function
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
@a cb has a super-linear complexity.
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
@todo Add example.
|
@liveexample{The example below demonstrates the parse function with and
|
||||||
|
without callback function.,parse__istream__parser_callback_t}
|
||||||
|
|
||||||
@sa parse(const string_t&, parser_callback_t) for a version that reads
|
@sa parse(const string_t&, parser_callback_t) for a version that reads
|
||||||
from a string
|
from a string
|
||||||
|
@ -5016,7 +5216,9 @@ class basic_json
|
||||||
|
|
||||||
expect(lexer::token_type::end_of_input);
|
expect(lexer::token_type::end_of_input);
|
||||||
|
|
||||||
return result;
|
// return parser result and replace it with null in case the
|
||||||
|
// top-level value was discarded by the callback function
|
||||||
|
return result.is_discarded() ? basic_json() : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -5069,7 +5271,15 @@ class basic_json
|
||||||
bool keep_tag = false;
|
bool keep_tag = false;
|
||||||
if (keep)
|
if (keep)
|
||||||
{
|
{
|
||||||
keep_tag = callback ? callback(depth, parse_event_t::key, basic_json(key)) : true;
|
if (callback)
|
||||||
|
{
|
||||||
|
basic_json k(key);
|
||||||
|
keep_tag = callback(depth, parse_event_t::key, k);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keep_tag = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse separator (:)
|
// parse separator (:)
|
||||||
|
|
|
@ -7742,14 +7742,16 @@ TEST_CASE("parser class")
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
CHECK (j_object.is_discarded());
|
// the top-level object will be discarded, leaving a null
|
||||||
|
CHECK (j_object.is_null());
|
||||||
|
|
||||||
json j_array = json::parse(s_array, [](int, json::parse_event_t, const json&)
|
json j_array = json::parse(s_array, [](int, json::parse_event_t, const json&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
CHECK (j_array.is_discarded());
|
// the top-level array will be discarded, leaving a null
|
||||||
|
CHECK (j_array.is_null());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("filter specific element")
|
SECTION("filter specific element")
|
||||||
|
@ -7791,8 +7793,10 @@ TEST_CASE("parser class")
|
||||||
{
|
{
|
||||||
json j_object = json::parse(s_object, [](int, json::parse_event_t e, const json&)
|
json j_object = json::parse(s_object, [](int, json::parse_event_t e, const json&)
|
||||||
{
|
{
|
||||||
if (e == json::parse_event_t::object_end)
|
static bool first = true;
|
||||||
|
if (e == json::parse_event_t::object_end and first)
|
||||||
{
|
{
|
||||||
|
first = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7801,14 +7805,17 @@ TEST_CASE("parser class")
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
CHECK (j_object.is_discarded());
|
// the first completed object will be discarded
|
||||||
|
CHECK (j_object == json({{"foo", 2}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
json j_array = json::parse(s_array, [](int, json::parse_event_t e, const json&)
|
json j_array = json::parse(s_array, [](int, json::parse_event_t e, const json&)
|
||||||
{
|
{
|
||||||
if (e == json::parse_event_t::array_end)
|
static bool first = true;
|
||||||
|
if (e == json::parse_event_t::array_end and first)
|
||||||
{
|
{
|
||||||
|
first = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7817,7 +7824,8 @@ TEST_CASE("parser class")
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
CHECK (j_array.is_discarded());
|
// the first completed array will be discarded
|
||||||
|
CHECK (j_array == json({1, 2, 4, 5}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue