Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
json
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
json
Commits
76be1ae1
Commit
76be1ae1
authored
10 years ago
by
Niels
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
+ more adjustments toward a real container
parent
3c780f0f
develop
bon8
coverity_scan
feature/optional
gcc_warning_flags
gh-pages
icpc
issue2228
issue2615
issue2932
issue3232_use_catch
master
release/3.10.2
release/3.10.3
release/3.10.4
release/3.10.5
string_view
string_view2
update_doctest
3.6.1
3.3.0
3.2.0
3.1.2
3.1.0
3.0.1
3.0.0
2.1.1
2.1.0
2.0.10
2.0.9
2.0.8
v3.10.5
v3.10.4
v3.10.3
v3.10.2
v3.10.1
v3.10.0
v3.9.1
v3.9.0
v3.8.0
v3.7.3
v3.7.2
v3.7.1
v3.7.0
v3.6.1
v3.6.0
v3.5.0
v3.4.0
v3.3.0
v3.2.0
v3.1.2
v3.1.1
v3.1.0
v3.0.1
v3.0.0
v2.1.1
v2.1.0
v2.0.10
v2.0.9
v2.0.8
v2.0.7
v2.0.6
v2.0.5
v2.0.4
v2.0.3
v2.0.2
v2.0.1
v2.0.0
v1.1.0
v1.0.0
v1.0.0-rc1
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
632 additions
and
490 deletions
+632
-490
README.md
README.md
+1
-1
header_only/json.h
header_only/json.h
+255
-191
src/json.cc
src/json.cc
+179
-150
src/json.h
src/json.h
+76
-41
test/json_unit.cc
test/json_unit.cc
+121
-107
No files found.
README.md
View file @
76be1ae1
...
@@ -184,7 +184,7 @@ bool foo = j.at(2);
...
@@ -184,7 +184,7 @@ bool foo = j.at(2);
// other stuff
// other stuff
j
.
size
();
// 3 entries
j
.
size
();
// 3 entries
j
.
empty
();
// false
j
.
empty
();
// false
j
.
type
();
// json::value_t
ype
::array
j
.
type
();
// json::value_t::array
j
.
clear
();
// the array is empty again
j
.
clear
();
// the array is empty again
// comparison
// comparison
...
...
This diff is collapsed.
Click to expand it.
header_only/json.h
View file @
76be1ae1
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
@file
@file
@copyright The code is licensed under the MIT License
@copyright The code is licensed under the MIT License
<http://opensource.org/licenses/MIT>,
<http://opensource.org/licenses/MIT>,
Copyright (c) 2013-201
4
Niels Lohmann.
Copyright (c) 2013-201
5
Niels Lohmann.
@author Niels Lohmann <http://nlohmann.me>
@author Niels Lohmann <http://nlohmann.me>
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
#include <vector> // std::vector
#include <vector> // std::vector
#include <iterator> // std::iterator
#include <iterator> // std::iterator
#include <limits> // std::numeric_limits
#include <limits> // std::numeric_limits
#include <functional> // std::hash
namespace
nlohmann
namespace
nlohmann
{
{
...
@@ -41,30 +42,21 @@ due to alignment.
...
@@ -41,30 +42,21 @@ due to alignment.
*/
*/
class
json
class
json
{
{
// forward declaration to friend this class
public:
public:
// forward declaration to friend this class
class
iterator
;
class
iterator
;
class
const_iterator
;
class
const_iterator
;
public:
// container types
/// possible types of a JSON object
using
value_type
=
json
;
enum
class
value_type
:
uint8_t
using
reference
=
json
&
;
{
using
const_reference
=
const
json
&
;
/// ordered collection of values
using
pointer
=
json
*
;
array
=
0
,
using
const_pointer
=
const
json
*
;
/// unordered set of name/value pairs
using
iterator
=
json
::
iterator
;
object
,
using
const_iterator
=
json
::
const_iterator
;
/// null value
using
difference_type
=
std
::
ptrdiff_t
;
null
,
using
size_type
=
std
::
size_t
;
/// string value
string
,
/// Boolean value
boolean
,
/// number value (integer)
number
,
/// number value (float)
number_float
};
/// a type for an object
/// a type for an object
using
object_t
=
std
::
map
<
std
::
string
,
json
>
;
using
object_t
=
std
::
map
<
std
::
string
,
json
>
;
...
@@ -113,9 +105,28 @@ class json
...
@@ -113,9 +105,28 @@ class json
value
(
number_float_t
);
value
(
number_float_t
);
};
};
/// possible types of a JSON object
enum
class
value_t
:
uint8_t
{
/// ordered collection of values
array
=
0
,
/// unordered set of name/value pairs
object
,
/// null value
null
,
/// string value
string
,
/// Boolean value
boolean
,
/// number value (integer)
number
,
/// number value (float)
number_float
};
public:
public:
/// create an object according to given type
/// create an object according to given type
json
(
const
value_t
ype
);
json
(
const
value_t
);
/// create a null object
/// create a null object
json
()
=
default
;
json
()
=
default
;
/// create a null object
/// create a null object
...
@@ -140,15 +151,23 @@ class json
...
@@ -140,15 +151,23 @@ class json
json
(
list_init_t
);
json
(
list_init_t
);
/// create a number object (integer)
/// create a number object (integer)
template
<
typename
T
,
typename
std
::
enable_if
<
std
::
numeric_limits
<
T
>
::
is_integer
,
T
>::
type
=
0
>
template
<
typename
T
,
typename
std
::
enable_if
<
std
::
numeric_limits
<
T
>
::
is_integer
,
T
>::
type
=
0
>
json
(
const
T
n
)
noexcept
json
(
const
T
n
)
noexcept
:
type_
(
value_type
::
number
),
value_
(
static_cast
<
number_t
>
(
n
))
:
type_
(
value_t
::
number
),
value_
(
static_cast
<
number_t
>
(
n
))
{}
{}
/// create a number object (float)
/// create a number object (float)
template
<
typename
T
,
typename
=
typename
std
::
enable_if
<
std
::
is_floating_point
<
T
>
::
value
>::
type
>
template
<
typename
T
,
typename
=
typename
std
::
enable_if
<
std
::
is_floating_point
<
T
>
::
value
>::
type
>
json
(
const
T
n
)
noexcept
json
(
const
T
n
)
noexcept
:
type_
(
value_type
::
number_float
),
value_
(
static_cast
<
number_float_t
>
(
n
))
:
type_
(
value_t
::
number_float
),
value_
(
static_cast
<
number_float_t
>
(
n
))
{}
{}
/// create an array object
/// create an array object
...
@@ -284,27 +303,29 @@ class json
...
@@ -284,27 +303,29 @@ class json
/// operator to get an element in an array
/// operator to get an element in an array
const
json
&
operator
[](
const
int
)
const
;
const
json
&
operator
[](
const
int
)
const
;
/// operator to get an element in an array
/// operator to get an element in an array
json
&
at
(
const
int
);
reference
at
(
const
int
);
/// operator to get an element in an array
/// operator to get an element in an array
const
json
&
at
(
const
int
)
const
;
const
_reference
at
(
const
int
)
const
;
/// operator to set an element in an object
/// operator to set an element in an object
json
&
operator
[](
const
std
::
string
&
);
reference
operator
[](
const
std
::
string
&
);
/// operator to set an element in an object
/// operator to set an element in an object
json
&
operator
[](
const
char
*
);
reference
operator
[](
const
char
*
);
/// operator to get an element in an object
/// operator to get an element in an object
const
json
&
operator
[](
const
std
::
string
&
)
const
;
const
_reference
operator
[](
const
std
::
string
&
)
const
;
/// operator to set an element in an object
/// operator to set an element in an object
json
&
at
(
const
std
::
string
&
);
reference
at
(
const
std
::
string
&
);
/// operator to set an element in an object
/// operator to set an element in an object
json
&
at
(
const
char
*
);
reference
at
(
const
char
*
);
/// operator to get an element in an object
/// operator to get an element in an object
const
json
&
at
(
const
std
::
string
&
)
const
;
const
_reference
at
(
const
std
::
string
&
)
const
;
/// operator to get an element in an object
/// operator to get an element in an object
const
json
&
at
(
const
char
*
)
const
;
const
_reference
at
(
const
char
*
)
const
;
/// return the number of stored values
/// return the number of stored values
std
::
size_t
size
()
const
noexcept
;
size_type
size
()
const
noexcept
;
/// return the maximal number of values that can be stored
size_type
max_size
()
const
noexcept
;
/// checks whether object is empty
/// checks whether object is empty
bool
empty
()
const
noexcept
;
bool
empty
()
const
noexcept
;
/// removes all elements from compounds and resets values to default
/// removes all elements from compounds and resets values to default
...
@@ -314,7 +335,7 @@ class json
...
@@ -314,7 +335,7 @@ class json
void
swap
(
json
&
)
noexcept
;
void
swap
(
json
&
)
noexcept
;
/// return the type of the object
/// return the type of the object
value_t
ype
type
()
const
noexcept
;
value_t
type
()
const
noexcept
;
/// find an element in an object (returns end() iterator otherwise)
/// find an element in an object (returns end() iterator otherwise)
iterator
find
(
const
std
::
string
&
);
iterator
find
(
const
std
::
string
&
);
...
@@ -345,7 +366,7 @@ class json
...
@@ -345,7 +366,7 @@ class json
private:
private:
/// the type of this object
/// the type of this object
value_t
ype
type_
=
value_type
::
null
;
value_t
type_
=
value_t
::
null
;
/// the payload
/// the payload
value
value_
{};
value
value_
{};
...
@@ -475,23 +496,37 @@ class json
...
@@ -475,23 +496,37 @@ class json
/// user-defined literal operator to create JSON objects from strings
/// user-defined literal operator to create JSON objects from strings
nlohmann
::
json
operator
""
_json
(
const
char
*
,
std
::
size_t
);
nlohmann
::
json
operator
""
_json
(
const
char
*
,
std
::
size_t
);
// specialization of std::swap
// specialization of std::swap
, and std::hash
namespace
std
namespace
std
{
{
template
<
>
template
<
>
/// swaps the values of two JSON objects
/// swaps the values of two JSON objects
inline
void
swap
(
nlohmann
::
json
&
j1
,
inline
void
swap
(
nlohmann
::
json
&
j1
,
nlohmann
::
json
&
j2
)
noexcept
(
is_nothrow_move_constructible
<
nlohmann
::
json
>::
value
and
nlohmann
::
json
&
j2
)
noexcept
(
is_nothrow_move_assignable
<
nlohmann
::
json
>::
value
)
is_nothrow_move_constructible
<
nlohmann
::
json
>::
value
and
is_nothrow_move_assignable
<
nlohmann
::
json
>::
value
)
{
{
j1
.
swap
(
j2
);
j1
.
swap
(
j2
);
}
}
template
<
>
/// hash value for JSON objects
struct
hash
<
nlohmann
::
json
>
{
size_t
operator
()(
const
nlohmann
::
json
&
j
)
const
{
// a naive hashing via the string representation
return
hash
<
std
::
string
>
()(
j
.
dump
());
}
};
}
}
/*!
/*!
@file
@file
@copyright The code is licensed under the MIT License
@copyright The code is licensed under the MIT License
<http://opensource.org/licenses/MIT>,
<http://opensource.org/licenses/MIT>,
Copyright (c) 2013-201
4
Niels Lohmann.
Copyright (c) 2013-201
5
Niels Lohmann.
@author Niels Lohmann <http://nlohmann.me>
@author Niels Lohmann <http://nlohmann.me>
...
@@ -531,37 +566,37 @@ Construct an empty JSON given the type.
...
@@ -531,37 +566,37 @@ Construct an empty JSON given the type.
@post Memory for array, object, and string are allocated.
@post Memory for array, object, and string are allocated.
*/
*/
json
::
json
(
const
value_t
ype
t
)
json
::
json
(
const
value_t
t
)
:
type_
(
t
)
:
type_
(
t
)
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
value_
.
array
=
new
array_t
();
value_
.
array
=
new
array_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
value_
.
object
=
new
object_t
();
value_
.
object
=
new
object_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
value_
.
string
=
new
string_t
();
value_
.
string
=
new
string_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
value_
.
boolean
=
boolean_t
();
value_
.
boolean
=
boolean_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
value_
.
number
=
number_t
();
value_
.
number
=
number_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
value_
.
number_float
=
number_float_t
();
value_
.
number_float
=
number_float_t
();
break
;
break
;
...
@@ -585,35 +620,35 @@ Construct a string JSON object.
...
@@ -585,35 +620,35 @@ Construct a string JSON object.
@param s a string to initialize the JSON object with
@param s a string to initialize the JSON object with
*/
*/
json
::
json
(
const
std
::
string
&
s
)
json
::
json
(
const
std
::
string
&
s
)
:
type_
(
value_t
ype
::
string
),
value_
(
new
string_t
(
s
))
:
type_
(
value_t
::
string
),
value_
(
new
string_t
(
s
))
{}
{}
json
::
json
(
std
::
string
&&
s
)
json
::
json
(
std
::
string
&&
s
)
:
type_
(
value_t
ype
::
string
),
value_
(
new
string_t
(
std
::
move
(
s
)))
:
type_
(
value_t
::
string
),
value_
(
new
string_t
(
std
::
move
(
s
)))
{}
{}
json
::
json
(
const
char
*
s
)
json
::
json
(
const
char
*
s
)
:
type_
(
value_t
ype
::
string
),
value_
(
new
string_t
(
s
))
:
type_
(
value_t
::
string
),
value_
(
new
string_t
(
s
))
{}
{}
json
::
json
(
const
bool
b
)
noexcept
json
::
json
(
const
bool
b
)
noexcept
:
type_
(
value_t
ype
::
boolean
),
value_
(
b
)
:
type_
(
value_t
::
boolean
),
value_
(
b
)
{}
{}
json
::
json
(
const
array_t
&
a
)
json
::
json
(
const
array_t
&
a
)
:
type_
(
value_t
ype
::
array
),
value_
(
new
array_t
(
a
))
:
type_
(
value_t
::
array
),
value_
(
new
array_t
(
a
))
{}
{}
json
::
json
(
array_t
&&
a
)
json
::
json
(
array_t
&&
a
)
:
type_
(
value_t
ype
::
array
),
value_
(
new
array_t
(
std
::
move
(
a
)))
:
type_
(
value_t
::
array
),
value_
(
new
array_t
(
std
::
move
(
a
)))
{}
{}
json
::
json
(
const
object_t
&
o
)
json
::
json
(
const
object_t
&
o
)
:
type_
(
value_t
ype
::
object
),
value_
(
new
object_t
(
o
))
:
type_
(
value_t
::
object
),
value_
(
new
object_t
(
o
))
{}
{}
json
::
json
(
object_t
&&
o
)
json
::
json
(
object_t
&&
o
)
:
type_
(
value_t
ype
::
object
),
value_
(
new
object_t
(
std
::
move
(
o
)))
:
type_
(
value_t
::
object
),
value_
(
new
object_t
(
std
::
move
(
o
)))
{}
{}
/*!
/*!
...
@@ -637,20 +672,20 @@ json::json(list_init_t a)
...
@@ -637,20 +672,20 @@ json::json(list_init_t a)
// is a string
// is a string
for
(
const
auto
&
element
:
a
)
for
(
const
auto
&
element
:
a
)
{
{
if
(
element
.
type_
!=
value_t
ype
::
array
or
if
(
element
.
type_
!=
value_t
::
array
or
element
.
size
()
!=
2
or
element
.
size
()
!=
2
or
element
[
0
].
type_
!=
value_t
ype
::
string
)
element
[
0
].
type_
!=
value_t
::
string
)
{
{
// the initializer list describes an array
// the initializer list describes an array
type_
=
value_t
ype
::
array
;
type_
=
value_t
::
array
;
value_
=
new
array_t
(
a
);
value_
=
new
array_t
(
a
);
return
;
return
;
}
}
}
}
// the initializer list is a list of pairs
// the initializer list is a list of pairs
type_
=
value_t
ype
::
object
;
type_
=
value_t
::
object
;
value_
=
new
object_t
();
value_
=
new
object_t
();
for
(
const
json
&
element
:
a
)
for
(
const
json
&
element
:
a
)
{
{
...
@@ -670,32 +705,32 @@ json::json(const json& o)
...
@@ -670,32 +705,32 @@ json::json(const json& o)
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
value_
.
array
=
new
array_t
(
*
o
.
value_
.
array
);
value_
.
array
=
new
array_t
(
*
o
.
value_
.
array
);
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
value_
.
object
=
new
object_t
(
*
o
.
value_
.
object
);
value_
.
object
=
new
object_t
(
*
o
.
value_
.
object
);
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
value_
.
string
=
new
string_t
(
*
o
.
value_
.
string
);
value_
.
string
=
new
string_t
(
*
o
.
value_
.
string
);
break
;
break
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
value_
.
boolean
=
o
.
value_
.
boolean
;
value_
.
boolean
=
o
.
value_
.
boolean
;
break
;
break
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
value_
.
number
=
o
.
value_
.
number
;
value_
.
number
=
o
.
value_
.
number
;
break
;
break
;
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
value_
.
number_float
=
o
.
value_
.
number_float
;
value_
.
number_float
=
o
.
value_
.
number_float
;
break
;
break
;
...
@@ -718,7 +753,7 @@ json::json(json&& o) noexcept
...
@@ -718,7 +753,7 @@ json::json(json&& o) noexcept
:
type_
(
std
::
move
(
o
.
type_
)),
value_
(
std
::
move
(
o
.
value_
))
:
type_
(
std
::
move
(
o
.
type_
)),
value_
(
std
::
move
(
o
.
value_
))
{
{
// invalidate payload
// invalidate payload
o
.
type_
=
value_t
ype
::
null
;
o
.
type_
=
value_t
::
null
;
o
.
value_
=
{};
o
.
value_
=
{};
}
}
...
@@ -739,17 +774,17 @@ json::~json() noexcept
...
@@ -739,17 +774,17 @@ json::~json() noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
delete
value_
.
array
;
delete
value_
.
array
;
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
delete
value_
.
object
;
delete
value_
.
object
;
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
delete
value_
.
string
;
delete
value_
.
string
;
break
;
break
;
...
@@ -785,23 +820,23 @@ std::string json::type_name() const noexcept
...
@@ -785,23 +820,23 @@ std::string json::type_name() const noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
return
"array"
;
return
"array"
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
return
"object"
;
return
"object"
;
}
}
case
(
value_t
ype
:
:
null
)
:
case
(
value_t
:
:
null
)
:
{
{
return
"null"
;
return
"null"
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
return
"string"
;
return
"string"
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
return
"boolean"
;
return
"boolean"
;
}
}
...
@@ -826,7 +861,7 @@ std::string json::get() const
...
@@ -826,7 +861,7 @@ std::string json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
return
*
value_
.
string
;
return
*
value_
.
string
;
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON string"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON string"
);
...
@@ -842,9 +877,9 @@ int json::get() const
...
@@ -842,9 +877,9 @@ int json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
return
value_
.
number
;
return
value_
.
number
;
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
return
static_cast
<
int
>
(
value_
.
number_float
);
return
static_cast
<
int
>
(
value_
.
number_float
);
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
...
@@ -860,9 +895,9 @@ int64_t json::get() const
...
@@ -860,9 +895,9 @@ int64_t json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
return
value_
.
number
;
return
value_
.
number
;
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
return
static_cast
<
number_t
>
(
value_
.
number_float
);
return
static_cast
<
number_t
>
(
value_
.
number_float
);
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
...
@@ -878,9 +913,9 @@ double json::get() const
...
@@ -878,9 +913,9 @@ double json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
return
static_cast
<
number_float_t
>
(
value_
.
number
);
return
static_cast
<
number_float_t
>
(
value_
.
number
);
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
return
value_
.
number_float
;
return
value_
.
number_float
;
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
...
@@ -896,7 +931,7 @@ bool json::get() const
...
@@ -896,7 +931,7 @@ bool json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
return
value_
.
boolean
;
return
value_
.
boolean
;
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON Boolean"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON Boolean"
);
...
@@ -910,11 +945,11 @@ bool json::get() const
...
@@ -910,11 +945,11 @@ bool json::get() const
template
<
>
template
<
>
json
::
array_t
json
::
get
()
const
json
::
array_t
json
::
get
()
const
{
{
if
(
type_
==
value_t
ype
::
array
)
if
(
type_
==
value_t
::
array
)
{
{
return
*
value_
.
array
;
return
*
value_
.
array
;
}
}
if
(
type_
==
value_t
ype
::
object
)
if
(
type_
==
value_t
::
object
)
{
{
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON array"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON array"
);
}
}
...
@@ -931,7 +966,7 @@ json::array_t json::get() const
...
@@ -931,7 +966,7 @@ json::array_t json::get() const
template
<
>
template
<
>
json
::
object_t
json
::
get
()
const
json
::
object_t
json
::
get
()
const
{
{
if
(
type_
==
value_t
ype
::
object
)
if
(
type_
==
value_t
::
object
)
{
{
return
*
value_
.
object
;
return
*
value_
.
object
;
}
}
...
@@ -994,27 +1029,27 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
...
@@ -994,27 +1029,27 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
return
std
::
string
(
"
\"
"
)
+
escapeString
(
*
value_
.
string
)
+
"
\"
"
;
return
std
::
string
(
"
\"
"
)
+
escapeString
(
*
value_
.
string
)
+
"
\"
"
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
return
value_
.
boolean
?
"true"
:
"false"
;
return
value_
.
boolean
?
"true"
:
"false"
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
return
std
::
to_string
(
value_
.
number
);
return
std
::
to_string
(
value_
.
number
);
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
return
std
::
to_string
(
value_
.
number_float
);
return
std
::
to_string
(
value_
.
number_float
);
}
}
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
if
(
value_
.
array
->
empty
())
if
(
value_
.
array
->
empty
())
{
{
...
@@ -1049,7 +1084,7 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
...
@@ -1049,7 +1084,7 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
return
result
+
indent
()
+
"]"
;
return
result
+
indent
()
+
"]"
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
if
(
value_
.
object
->
empty
())
if
(
value_
.
object
->
empty
())
{
{
...
@@ -1086,7 +1121,7 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
...
@@ -1086,7 +1121,7 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
return
result
+
indent
()
+
"}"
;
return
result
+
indent
()
+
"}"
;
}
}
// actually only value_t
ype
::null - but making the compiler happy
// actually only value_t::null - but making the compiler happy
default:
default:
{
{
return
"null"
;
return
"null"
;
...
@@ -1206,15 +1241,15 @@ an array, the passed element is added to the array.
...
@@ -1206,15 +1241,15 @@ an array, the passed element is added to the array.
void
json
::
push_back
(
const
json
&
o
)
void
json
::
push_back
(
const
json
&
o
)
{
{
// push_back only works for null objects or arrays
// push_back only works for null objects or arrays
if
(
not
(
type_
==
value_t
ype
::
null
or
type_
==
value_type
::
array
))
if
(
not
(
type_
==
value_t
::
null
or
type_
==
value_t
::
array
))
{
{
throw
std
::
runtime_error
(
"cannot add element to "
+
type_name
());
throw
std
::
runtime_error
(
"cannot add element to "
+
type_name
());
}
}
// transform null object into an array
// transform null object into an array
if
(
type_
==
value_t
ype
::
null
)
if
(
type_
==
value_t
::
null
)
{
{
type_
=
value_t
ype
::
array
;
type_
=
value_t
::
array
;
value_
.
array
=
new
array_t
;
value_
.
array
=
new
array_t
;
}
}
...
@@ -1241,22 +1276,22 @@ an array, the passed element is added to the array using move semantics.
...
@@ -1241,22 +1276,22 @@ an array, the passed element is added to the array using move semantics.
void
json
::
push_back
(
json
&&
o
)
void
json
::
push_back
(
json
&&
o
)
{
{
// push_back only works for null objects or arrays
// push_back only works for null objects or arrays
if
(
not
(
type_
==
value_t
ype
::
null
or
type_
==
value_type
::
array
))
if
(
not
(
type_
==
value_t
::
null
or
type_
==
value_t
::
array
))
{
{
throw
std
::
runtime_error
(
"cannot add element to "
+
type_name
());
throw
std
::
runtime_error
(
"cannot add element to "
+
type_name
());
}
}
// transform null object into an array
// transform null object into an array
if
(
type_
==
value_t
ype
::
null
)
if
(
type_
==
value_t
::
null
)
{
{
type_
=
value_t
ype
::
array
;
type_
=
value_t
::
array
;
value_
.
array
=
new
array_t
;
value_
.
array
=
new
array_t
;
}
}
// add element to array (move semantics)
// add element to array (move semantics)
value_
.
array
->
emplace_back
(
std
::
move
(
o
));
value_
.
array
->
emplace_back
(
std
::
move
(
o
));
// invalidate object
// invalidate object
o
.
type_
=
value_t
ype
::
null
;
o
.
type_
=
value_t
::
null
;
}
}
/*!
/*!
...
@@ -1278,9 +1313,9 @@ void json::push_back(list_init_t a)
...
@@ -1278,9 +1313,9 @@ void json::push_back(list_init_t a)
// is a string
// is a string
for
(
const
auto
&
element
:
a
)
for
(
const
auto
&
element
:
a
)
{
{
if
(
element
.
type_
!=
value_t
ype
::
array
or
if
(
element
.
type_
!=
value_t
::
array
or
element
.
size
()
!=
2
or
element
.
size
()
!=
2
or
element
[
0
].
type_
!=
value_t
ype
::
string
)
element
[
0
].
type_
!=
value_t
::
string
)
{
{
// the initializer list describes an array
// the initializer list describes an array
is_array
=
true
;
is_array
=
true
;
...
@@ -1321,10 +1356,10 @@ index. Bounds will not be checked.
...
@@ -1321,10 +1356,10 @@ index. Bounds will not be checked.
@pre Object is an array.
@pre Object is an array.
@exception std::domain_error if object is not an array
@exception std::domain_error if object is not an array
*/
*/
json
&
json
::
operator
[](
const
int
index
)
json
::
reference
json
::
operator
[](
const
int
index
)
{
{
// this [] operator only works for arrays
// this [] operator only works for arrays
if
(
type_
!=
value_t
ype
::
array
)
if
(
type_
!=
value_t
::
array
)
{
{
throw
std
::
domain_error
(
"cannot add entry with index "
+
throw
std
::
domain_error
(
"cannot add entry with index "
+
std
::
to_string
(
index
)
+
" to "
+
type_name
());
std
::
to_string
(
index
)
+
" to "
+
type_name
());
...
@@ -1350,10 +1385,10 @@ index. Bounds will not be checked.
...
@@ -1350,10 +1385,10 @@ index. Bounds will not be checked.
@pre Object is an array.
@pre Object is an array.
@exception std::domain_error if object is not an array
@exception std::domain_error if object is not an array
*/
*/
const
json
&
json
::
operator
[](
const
int
index
)
const
json
::
const_reference
json
::
operator
[](
const
int
index
)
const
{
{
// this [] operator only works for arrays
// this [] operator only works for arrays
if
(
type_
!=
value_t
ype
::
array
)
if
(
type_
!=
value_t
::
array
)
{
{
throw
std
::
domain_error
(
"cannot get entry with index "
+
throw
std
::
domain_error
(
"cannot get entry with index "
+
std
::
to_string
(
index
)
+
" from "
+
type_name
());
std
::
to_string
(
index
)
+
" from "
+
type_name
());
...
@@ -1380,10 +1415,10 @@ index. Bounds will be checked.
...
@@ -1380,10 +1415,10 @@ index. Bounds will be checked.
@exception std::domain_error if object is not an array
@exception std::domain_error if object is not an array
@exception std::out_of_range if index is out of range (via std::vector::at)
@exception std::out_of_range if index is out of range (via std::vector::at)
*/
*/
json
&
json
::
at
(
const
int
index
)
json
::
reference
json
::
at
(
const
int
index
)
{
{
// this function only works for arrays
// this function only works for arrays
if
(
type_
!=
value_t
ype
::
array
)
if
(
type_
!=
value_t
::
array
)
{
{
throw
std
::
domain_error
(
"cannot add entry with index "
+
throw
std
::
domain_error
(
"cannot add entry with index "
+
std
::
to_string
(
index
)
+
" to "
+
type_name
());
std
::
to_string
(
index
)
+
" to "
+
type_name
());
...
@@ -1410,10 +1445,10 @@ index. Bounds will be checked.
...
@@ -1410,10 +1445,10 @@ index. Bounds will be checked.
@exception std::domain_error if object is not an array
@exception std::domain_error if object is not an array
@exception std::out_of_range if index is out of range (via std::vector::at)
@exception std::out_of_range if index is out of range (via std::vector::at)
*/
*/
const
json
&
json
::
at
(
const
int
index
)
const
json
::
const_reference
json
::
at
(
const
int
index
)
const
{
{
// this function only works for arrays
// this function only works for arrays
if
(
type_
!=
value_t
ype
::
array
)
if
(
type_
!=
value_t
::
array
)
{
{
throw
std
::
domain_error
(
"cannot get entry with index "
+
throw
std
::
domain_error
(
"cannot get entry with index "
+
std
::
to_string
(
index
)
+
" from "
+
type_name
());
std
::
to_string
(
index
)
+
" from "
+
type_name
());
...
@@ -1426,7 +1461,7 @@ const json& json::at(const int index) const
...
@@ -1426,7 +1461,7 @@ const json& json::at(const int index) const
/*!
/*!
@copydoc json::operator[](const char* key)
@copydoc json::operator[](const char* key)
*/
*/
json
&
json
::
operator
[](
const
std
::
string
&
key
)
json
::
reference
json
::
operator
[](
const
std
::
string
&
key
)
{
{
return
operator
[](
key
.
c_str
());
return
operator
[](
key
.
c_str
());
}
}
...
@@ -1444,17 +1479,17 @@ key.
...
@@ -1444,17 +1479,17 @@ key.
@exception std::domain_error if object is not an object (or null)
@exception std::domain_error if object is not an object (or null)
*/
*/
json
&
json
::
operator
[](
const
char
*
key
)
json
::
reference
json
::
operator
[](
const
char
*
key
)
{
{
// implicitly convert null to object
// implicitly convert null to object
if
(
type_
==
value_t
ype
::
null
)
if
(
type_
==
value_t
::
null
)
{
{
type_
=
value_t
ype
::
object
;
type_
=
value_t
::
object
;
value_
.
object
=
new
object_t
;
value_
.
object
=
new
object_t
;
}
}
// this [] operator only works for objects
// this [] operator only works for objects
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
throw
std
::
domain_error
(
"cannot add entry with key "
+
throw
std
::
domain_error
(
"cannot add entry with key "
+
std
::
string
(
key
)
+
" to "
+
type_name
());
std
::
string
(
key
)
+
" to "
+
type_name
());
...
@@ -1481,10 +1516,10 @@ key.
...
@@ -1481,10 +1516,10 @@ key.
@exception std::domain_error if object is not an object
@exception std::domain_error if object is not an object
@exception std::out_of_range if key is not found in object
@exception std::out_of_range if key is not found in object
*/
*/
const
json
&
json
::
operator
[](
const
std
::
string
&
key
)
const
json
::
const_reference
json
::
operator
[](
const
std
::
string
&
key
)
const
{
{
// this [] operator only works for objects
// this [] operator only works for objects
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
throw
std
::
domain_error
(
"cannot get entry with key "
+
throw
std
::
domain_error
(
"cannot get entry with key "
+
std
::
string
(
key
)
+
" from "
+
type_name
());
std
::
string
(
key
)
+
" from "
+
type_name
());
...
@@ -1506,7 +1541,7 @@ const json& json::operator[](const std::string& key) const
...
@@ -1506,7 +1541,7 @@ const json& json::operator[](const std::string& key) const
/*!
/*!
@copydoc json::at(const char* key)
@copydoc json::at(const char* key)
*/
*/
json
&
json
::
at
(
const
std
::
string
&
key
)
json
::
reference
json
::
at
(
const
std
::
string
&
key
)
{
{
return
at
(
key
.
c_str
());
return
at
(
key
.
c_str
());
}
}
...
@@ -1524,10 +1559,10 @@ key.
...
@@ -1524,10 +1559,10 @@ key.
@exception std::domain_error if object is not an object
@exception std::domain_error if object is not an object
@exception std::out_of_range if key was not found (via std::map::at)
@exception std::out_of_range if key was not found (via std::map::at)
*/
*/
json
&
json
::
at
(
const
char
*
key
)
json
::
reference
json
::
at
(
const
char
*
key
)
{
{
// this function operator only works for objects
// this function operator only works for objects
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
throw
std
::
domain_error
(
"cannot add entry with key "
+
throw
std
::
domain_error
(
"cannot add entry with key "
+
std
::
string
(
key
)
+
" to "
+
type_name
());
std
::
string
(
key
)
+
" to "
+
type_name
());
...
@@ -1540,7 +1575,7 @@ json& json::at(const char* key)
...
@@ -1540,7 +1575,7 @@ json& json::at(const char* key)
/*!
/*!
@copydoc json::at(const char *key) const
@copydoc json::at(const char *key) const
*/
*/
const
json
&
json
::
at
(
const
std
::
string
&
key
)
const
json
::
const_reference
json
::
at
(
const
std
::
string
&
key
)
const
{
{
return
at
(
key
.
c_str
());
return
at
(
key
.
c_str
());
}
}
...
@@ -1556,10 +1591,10 @@ key.
...
@@ -1556,10 +1591,10 @@ key.
@exception std::domain_error if object is not an object
@exception std::domain_error if object is not an object
@exception std::out_of_range if key is not found (via std::map::at)
@exception std::out_of_range if key is not found (via std::map::at)
*/
*/
const
json
&
json
::
at
(
const
char
*
key
)
const
json
::
const_reference
json
::
at
(
const
char
*
key
)
const
{
{
// this [] operator only works for objects
// this [] operator only works for objects
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
throw
std
::
domain_error
(
"cannot get entry with key "
+
throw
std
::
domain_error
(
"cannot get entry with key "
+
std
::
string
(
key
)
+
" from "
+
type_name
());
std
::
string
(
key
)
+
" from "
+
type_name
());
...
@@ -1569,7 +1604,6 @@ const json& json::at(const char* key) const
...
@@ -1569,7 +1604,6 @@ const json& json::at(const char* key) const
return
value_
.
object
->
at
(
key
);
return
value_
.
object
->
at
(
key
);
}
}
/*!
/*!
Returns the size of the JSON object.
Returns the size of the JSON object.
...
@@ -1579,19 +1613,49 @@ Returns the size of the JSON object.
...
@@ -1579,19 +1613,49 @@ Returns the size of the JSON object.
@invariant The size is reported as 0 if and only if empty() would return true.
@invariant The size is reported as 0 if and only if empty() would return true.
*/
*/
std
::
size_t
json
::
size
()
const
noexcept
json
::
size_type
json
::
size
()
const
noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
return
value_
.
array
->
size
();
return
value_
.
array
->
size
();
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
return
value_
.
object
->
size
();
return
value_
.
object
->
size
();
}
}
case
(
value_type
:
:
null
)
:
case
(
value_t
:
:
null
)
:
{
return
0
;
}
default:
{
return
1
;
}
}
}
/*!
Returns the maximal size of the JSON object.
@return the maximal size of the JSON object; the maximal size is the maximal
number of elements in compounds (array and object), 1 for value types
(true, false, number, string), and 0 for null.
*/
json
::
size_type
json
::
max_size
()
const
noexcept
{
switch
(
type_
)
{
case
(
value_t
:
:
array
)
:
{
return
value_
.
array
->
max_size
();
}
case
(
value_t
:
:
object
)
:
{
return
value_
.
object
->
max_size
();
}
case
(
value_t
:
:
null
)
:
{
{
return
0
;
return
0
;
}
}
...
@@ -1615,15 +1679,15 @@ bool json::empty() const noexcept
...
@@ -1615,15 +1679,15 @@ bool json::empty() const noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
return
value_
.
array
->
empty
();
return
value_
.
array
->
empty
();
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
return
value_
.
object
->
empty
();
return
value_
.
object
->
empty
();
}
}
case
(
value_t
ype
:
:
null
)
:
case
(
value_t
:
:
null
)
:
{
{
return
true
;
return
true
;
}
}
...
@@ -1645,32 +1709,32 @@ void json::clear() noexcept
...
@@ -1645,32 +1709,32 @@ void json::clear() noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
value_
.
array
->
clear
();
value_
.
array
->
clear
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
value_
.
object
->
clear
();
value_
.
object
->
clear
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
value_
.
string
->
clear
();
value_
.
string
->
clear
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
value_
.
boolean
=
{};
value_
.
boolean
=
{};
break
;
break
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
value_
.
number
=
{};
value_
.
number
=
{};
break
;
break
;
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
value_
.
number_float
=
{};
value_
.
number_float
=
{};
break
;
break
;
...
@@ -1688,7 +1752,7 @@ void json::swap(json& o) noexcept
...
@@ -1688,7 +1752,7 @@ void json::swap(json& o) noexcept
std
::
swap
(
value_
,
o
.
value_
);
std
::
swap
(
value_
,
o
.
value_
);
}
}
json
::
value_t
ype
json
::
type
()
const
noexcept
json
::
value_t
json
::
type
()
const
noexcept
{
{
return
type_
;
return
type_
;
}
}
...
@@ -1705,7 +1769,7 @@ json::const_iterator json::find(const std::string& key) const
...
@@ -1705,7 +1769,7 @@ json::const_iterator json::find(const std::string& key) const
json
::
iterator
json
::
find
(
const
char
*
key
)
json
::
iterator
json
::
find
(
const
char
*
key
)
{
{
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
return
end
();
return
end
();
}
}
...
@@ -1729,7 +1793,7 @@ json::iterator json::find(const char* key)
...
@@ -1729,7 +1793,7 @@ json::iterator json::find(const char* key)
json
::
const_iterator
json
::
find
(
const
char
*
key
)
const
json
::
const_iterator
json
::
find
(
const
char
*
key
)
const
{
{
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
return
end
();
return
end
();
}
}
...
@@ -1755,65 +1819,65 @@ bool json::operator==(const json& o) const noexcept
...
@@ -1755,65 +1819,65 @@ bool json::operator==(const json& o) const noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
array
)
if
(
o
.
type_
==
value_t
::
array
)
{
{
return
*
value_
.
array
==
*
o
.
value_
.
array
;
return
*
value_
.
array
==
*
o
.
value_
.
array
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
object
)
if
(
o
.
type_
==
value_t
::
object
)
{
{
return
*
value_
.
object
==
*
o
.
value_
.
object
;
return
*
value_
.
object
==
*
o
.
value_
.
object
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
null
)
:
case
(
value_t
:
:
null
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
null
)
if
(
o
.
type_
==
value_t
::
null
)
{
{
return
true
;
return
true
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
string
)
if
(
o
.
type_
==
value_t
::
string
)
{
{
return
*
value_
.
string
==
*
o
.
value_
.
string
;
return
*
value_
.
string
==
*
o
.
value_
.
string
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
boolean
)
if
(
o
.
type_
==
value_t
::
boolean
)
{
{
return
value_
.
boolean
==
o
.
value_
.
boolean
;
return
value_
.
boolean
==
o
.
value_
.
boolean
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
number
)
if
(
o
.
type_
==
value_t
::
number
)
{
{
return
value_
.
number
==
o
.
value_
.
number
;
return
value_
.
number
==
o
.
value_
.
number
;
}
}
if
(
o
.
type_
==
value_t
ype
::
number_float
)
if
(
o
.
type_
==
value_t
::
number_float
)
{
{
return
value_
.
number
==
static_cast
<
number_t
>
(
o
.
value_
.
number_float
);
return
value_
.
number
==
static_cast
<
number_t
>
(
o
.
value_
.
number_float
);
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
number
)
if
(
o
.
type_
==
value_t
::
number
)
{
{
return
value_
.
number_float
==
static_cast
<
number_float_t
>
(
o
.
value_
.
number
);
return
value_
.
number_float
==
static_cast
<
number_float_t
>
(
o
.
value_
.
number
);
}
}
if
(
o
.
type_
==
value_t
ype
::
number_float
)
if
(
o
.
type_
==
value_t
::
number_float
)
{
{
return
value_
.
number_float
==
o
.
value_
.
number_float
;
return
value_
.
number_float
==
o
.
value_
.
number_float
;
}
}
...
@@ -1865,7 +1929,7 @@ json::iterator::iterator(json* j) : object_(j)
...
@@ -1865,7 +1929,7 @@ json::iterator::iterator(json* j) : object_(j)
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1876,7 +1940,7 @@ json::iterator::iterator(json* j) : object_(j)
...
@@ -1876,7 +1940,7 @@ json::iterator::iterator(json* j) : object_(j)
vi_
=
new
array_t
::
iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1894,7 +1958,7 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
...
@@ -1894,7 +1958,7 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1905,7 +1969,7 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
...
@@ -1905,7 +1969,7 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
vi_
=
new
array_t
::
iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1942,11 +2006,11 @@ bool json::iterator::operator==(const json::iterator& o) const
...
@@ -1942,11 +2006,11 @@ bool json::iterator::operator==(const json::iterator& o) const
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
return
(
vi_
==
o
.
vi_
);
return
(
vi_
==
o
.
vi_
);
}
}
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
return
(
oi_
==
o
.
oi_
);
return
(
oi_
==
o
.
oi_
);
}
}
...
@@ -1970,7 +2034,7 @@ json::iterator& json::iterator::operator++()
...
@@ -1970,7 +2034,7 @@ json::iterator& json::iterator::operator++()
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
if
(
++
(
*
vi_
)
==
object_
->
value_
.
array
->
end
())
if
(
++
(
*
vi_
)
==
object_
->
value_
.
array
->
end
())
{
{
...
@@ -1978,7 +2042,7 @@ json::iterator& json::iterator::operator++()
...
@@ -1978,7 +2042,7 @@ json::iterator& json::iterator::operator++()
}
}
break
;
break
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
if
(
++
(
*
oi_
)
==
object_
->
value_
.
object
->
end
())
if
(
++
(
*
oi_
)
==
object_
->
value_
.
object
->
end
())
{
{
...
@@ -2004,11 +2068,11 @@ json& json::iterator::operator*() const
...
@@ -2004,11 +2068,11 @@ json& json::iterator::operator*() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
**
vi_
;
return
**
vi_
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
(
*
oi_
)
->
second
;
return
(
*
oi_
)
->
second
;
}
}
...
@@ -2029,11 +2093,11 @@ json* json::iterator::operator->() const
...
@@ -2029,11 +2093,11 @@ json* json::iterator::operator->() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
&
(
**
vi_
);
return
&
(
**
vi_
);
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
&
((
*
oi_
)
->
second
);
return
&
((
*
oi_
)
->
second
);
}
}
...
@@ -2046,7 +2110,7 @@ json* json::iterator::operator->() const
...
@@ -2046,7 +2110,7 @@ json* json::iterator::operator->() const
std
::
string
json
::
iterator
::
key
()
const
std
::
string
json
::
iterator
::
key
()
const
{
{
if
(
object_
!=
nullptr
and
object_
->
type_
==
json
::
value_t
ype
::
object
)
if
(
object_
!=
nullptr
and
object_
->
type_
==
json
::
value_t
::
object
)
{
{
return
(
*
oi_
)
->
first
;
return
(
*
oi_
)
->
first
;
}
}
...
@@ -2066,11 +2130,11 @@ json& json::iterator::value() const
...
@@ -2066,11 +2130,11 @@ json& json::iterator::value() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
**
vi_
;
return
**
vi_
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
(
*
oi_
)
->
second
;
return
(
*
oi_
)
->
second
;
}
}
...
@@ -2086,7 +2150,7 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
...
@@ -2086,7 +2150,7 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -2097,7 +2161,7 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
...
@@ -2097,7 +2161,7 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -2115,7 +2179,7 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
...
@@ -2115,7 +2179,7 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -2126,7 +2190,7 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
...
@@ -2126,7 +2190,7 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -2144,7 +2208,7 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
...
@@ -2144,7 +2208,7 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -2155,7 +2219,7 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
...
@@ -2155,7 +2219,7 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -2192,11 +2256,11 @@ bool json::const_iterator::operator==(const json::const_iterator& o) const
...
@@ -2192,11 +2256,11 @@ bool json::const_iterator::operator==(const json::const_iterator& o) const
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
return
(
vi_
==
o
.
vi_
);
return
(
vi_
==
o
.
vi_
);
}
}
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
return
(
oi_
==
o
.
oi_
);
return
(
oi_
==
o
.
oi_
);
}
}
...
@@ -2220,7 +2284,7 @@ json::const_iterator& json::const_iterator::operator++()
...
@@ -2220,7 +2284,7 @@ json::const_iterator& json::const_iterator::operator++()
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
if
(
++
(
*
vi_
)
==
object_
->
value_
.
array
->
end
())
if
(
++
(
*
vi_
)
==
object_
->
value_
.
array
->
end
())
{
{
...
@@ -2228,7 +2292,7 @@ json::const_iterator& json::const_iterator::operator++()
...
@@ -2228,7 +2292,7 @@ json::const_iterator& json::const_iterator::operator++()
}
}
break
;
break
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
if
(
++
(
*
oi_
)
==
object_
->
value_
.
object
->
end
())
if
(
++
(
*
oi_
)
==
object_
->
value_
.
object
->
end
())
{
{
...
@@ -2254,11 +2318,11 @@ const json& json::const_iterator::operator*() const
...
@@ -2254,11 +2318,11 @@ const json& json::const_iterator::operator*() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
**
vi_
;
return
**
vi_
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
(
*
oi_
)
->
second
;
return
(
*
oi_
)
->
second
;
}
}
...
@@ -2279,11 +2343,11 @@ const json* json::const_iterator::operator->() const
...
@@ -2279,11 +2343,11 @@ const json* json::const_iterator::operator->() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
&
(
**
vi_
);
return
&
(
**
vi_
);
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
&
((
*
oi_
)
->
second
);
return
&
((
*
oi_
)
->
second
);
}
}
...
@@ -2296,7 +2360,7 @@ const json* json::const_iterator::operator->() const
...
@@ -2296,7 +2360,7 @@ const json* json::const_iterator::operator->() const
std
::
string
json
::
const_iterator
::
key
()
const
std
::
string
json
::
const_iterator
::
key
()
const
{
{
if
(
object_
!=
nullptr
and
object_
->
type_
==
json
::
value_t
ype
::
object
)
if
(
object_
!=
nullptr
and
object_
->
type_
==
json
::
value_t
::
object
)
{
{
return
(
*
oi_
)
->
first
;
return
(
*
oi_
)
->
first
;
}
}
...
@@ -2316,11 +2380,11 @@ const json& json::const_iterator::value() const
...
@@ -2316,11 +2380,11 @@ const json& json::const_iterator::value() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
**
vi_
;
return
**
vi_
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
(
*
oi_
)
->
second
;
return
(
*
oi_
)
->
second
;
}
}
...
@@ -2390,7 +2454,7 @@ json json::parser::parse()
...
@@ -2390,7 +2454,7 @@ json json::parser::parse()
case
(
'{'
):
case
(
'{'
):
{
{
// explicitly set result to object to cope with {}
// explicitly set result to object to cope with {}
json
result
(
value_t
ype
::
object
);
json
result
(
value_t
::
object
);
next
();
next
();
...
@@ -2421,7 +2485,7 @@ json json::parser::parse()
...
@@ -2421,7 +2485,7 @@ json json::parser::parse()
case
(
'['
):
case
(
'['
):
{
{
// explicitly set result to array to cope with []
// explicitly set result to array to cope with []
json
result
(
value_t
ype
::
array
);
json
result
(
value_t
::
array
);
next
();
next
();
...
...
This diff is collapsed.
Click to expand it.
src/json.cc
View file @
76be1ae1
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
@file
@file
@copyright The code is licensed under the MIT License
@copyright The code is licensed under the MIT License
<http://opensource.org/licenses/MIT>,
<http://opensource.org/licenses/MIT>,
Copyright (c) 2013-201
4
Niels Lohmann.
Copyright (c) 2013-201
5
Niels Lohmann.
@author Niels Lohmann <http://nlohmann.me>
@author Niels Lohmann <http://nlohmann.me>
...
@@ -42,37 +42,37 @@ Construct an empty JSON given the type.
...
@@ -42,37 +42,37 @@ Construct an empty JSON given the type.
@post Memory for array, object, and string are allocated.
@post Memory for array, object, and string are allocated.
*/
*/
json
::
json
(
const
value_t
ype
t
)
json
::
json
(
const
value_t
t
)
:
type_
(
t
)
:
type_
(
t
)
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
value_
.
array
=
new
array_t
();
value_
.
array
=
new
array_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
value_
.
object
=
new
object_t
();
value_
.
object
=
new
object_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
value_
.
string
=
new
string_t
();
value_
.
string
=
new
string_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
value_
.
boolean
=
boolean_t
();
value_
.
boolean
=
boolean_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
value_
.
number
=
number_t
();
value_
.
number
=
number_t
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
value_
.
number_float
=
number_float_t
();
value_
.
number_float
=
number_float_t
();
break
;
break
;
...
@@ -96,35 +96,35 @@ Construct a string JSON object.
...
@@ -96,35 +96,35 @@ Construct a string JSON object.
@param s a string to initialize the JSON object with
@param s a string to initialize the JSON object with
*/
*/
json
::
json
(
const
std
::
string
&
s
)
json
::
json
(
const
std
::
string
&
s
)
:
type_
(
value_t
ype
::
string
),
value_
(
new
string_t
(
s
))
:
type_
(
value_t
::
string
),
value_
(
new
string_t
(
s
))
{}
{}
json
::
json
(
std
::
string
&&
s
)
json
::
json
(
std
::
string
&&
s
)
:
type_
(
value_t
ype
::
string
),
value_
(
new
string_t
(
std
::
move
(
s
)))
:
type_
(
value_t
::
string
),
value_
(
new
string_t
(
std
::
move
(
s
)))
{}
{}
json
::
json
(
const
char
*
s
)
json
::
json
(
const
char
*
s
)
:
type_
(
value_t
ype
::
string
),
value_
(
new
string_t
(
s
))
:
type_
(
value_t
::
string
),
value_
(
new
string_t
(
s
))
{}
{}
json
::
json
(
const
bool
b
)
noexcept
json
::
json
(
const
bool
b
)
noexcept
:
type_
(
value_t
ype
::
boolean
),
value_
(
b
)
:
type_
(
value_t
::
boolean
),
value_
(
b
)
{}
{}
json
::
json
(
const
array_t
&
a
)
json
::
json
(
const
array_t
&
a
)
:
type_
(
value_t
ype
::
array
),
value_
(
new
array_t
(
a
))
:
type_
(
value_t
::
array
),
value_
(
new
array_t
(
a
))
{}
{}
json
::
json
(
array_t
&&
a
)
json
::
json
(
array_t
&&
a
)
:
type_
(
value_t
ype
::
array
),
value_
(
new
array_t
(
std
::
move
(
a
)))
:
type_
(
value_t
::
array
),
value_
(
new
array_t
(
std
::
move
(
a
)))
{}
{}
json
::
json
(
const
object_t
&
o
)
json
::
json
(
const
object_t
&
o
)
:
type_
(
value_t
ype
::
object
),
value_
(
new
object_t
(
o
))
:
type_
(
value_t
::
object
),
value_
(
new
object_t
(
o
))
{}
{}
json
::
json
(
object_t
&&
o
)
json
::
json
(
object_t
&&
o
)
:
type_
(
value_t
ype
::
object
),
value_
(
new
object_t
(
std
::
move
(
o
)))
:
type_
(
value_t
::
object
),
value_
(
new
object_t
(
std
::
move
(
o
)))
{}
{}
/*!
/*!
...
@@ -148,20 +148,20 @@ json::json(list_init_t a)
...
@@ -148,20 +148,20 @@ json::json(list_init_t a)
// is a string
// is a string
for
(
const
auto
&
element
:
a
)
for
(
const
auto
&
element
:
a
)
{
{
if
(
element
.
type_
!=
value_t
ype
::
array
or
if
(
element
.
type_
!=
value_t
::
array
or
element
.
size
()
!=
2
or
element
.
size
()
!=
2
or
element
[
0
].
type_
!=
value_t
ype
::
string
)
element
[
0
].
type_
!=
value_t
::
string
)
{
{
// the initializer list describes an array
// the initializer list describes an array
type_
=
value_t
ype
::
array
;
type_
=
value_t
::
array
;
value_
=
new
array_t
(
a
);
value_
=
new
array_t
(
a
);
return
;
return
;
}
}
}
}
// the initializer list is a list of pairs
// the initializer list is a list of pairs
type_
=
value_t
ype
::
object
;
type_
=
value_t
::
object
;
value_
=
new
object_t
();
value_
=
new
object_t
();
for
(
const
json
&
element
:
a
)
for
(
const
json
&
element
:
a
)
{
{
...
@@ -181,32 +181,32 @@ json::json(const json& o)
...
@@ -181,32 +181,32 @@ json::json(const json& o)
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
value_
.
array
=
new
array_t
(
*
o
.
value_
.
array
);
value_
.
array
=
new
array_t
(
*
o
.
value_
.
array
);
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
value_
.
object
=
new
object_t
(
*
o
.
value_
.
object
);
value_
.
object
=
new
object_t
(
*
o
.
value_
.
object
);
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
value_
.
string
=
new
string_t
(
*
o
.
value_
.
string
);
value_
.
string
=
new
string_t
(
*
o
.
value_
.
string
);
break
;
break
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
value_
.
boolean
=
o
.
value_
.
boolean
;
value_
.
boolean
=
o
.
value_
.
boolean
;
break
;
break
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
value_
.
number
=
o
.
value_
.
number
;
value_
.
number
=
o
.
value_
.
number
;
break
;
break
;
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
value_
.
number_float
=
o
.
value_
.
number_float
;
value_
.
number_float
=
o
.
value_
.
number_float
;
break
;
break
;
...
@@ -229,7 +229,7 @@ json::json(json&& o) noexcept
...
@@ -229,7 +229,7 @@ json::json(json&& o) noexcept
:
type_
(
std
::
move
(
o
.
type_
)),
value_
(
std
::
move
(
o
.
value_
))
:
type_
(
std
::
move
(
o
.
type_
)),
value_
(
std
::
move
(
o
.
value_
))
{
{
// invalidate payload
// invalidate payload
o
.
type_
=
value_t
ype
::
null
;
o
.
type_
=
value_t
::
null
;
o
.
value_
=
{};
o
.
value_
=
{};
}
}
...
@@ -250,17 +250,17 @@ json::~json() noexcept
...
@@ -250,17 +250,17 @@ json::~json() noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
delete
value_
.
array
;
delete
value_
.
array
;
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
delete
value_
.
object
;
delete
value_
.
object
;
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
delete
value_
.
string
;
delete
value_
.
string
;
break
;
break
;
...
@@ -296,23 +296,23 @@ std::string json::type_name() const noexcept
...
@@ -296,23 +296,23 @@ std::string json::type_name() const noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
return
"array"
;
return
"array"
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
return
"object"
;
return
"object"
;
}
}
case
(
value_t
ype
:
:
null
)
:
case
(
value_t
:
:
null
)
:
{
{
return
"null"
;
return
"null"
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
return
"string"
;
return
"string"
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
return
"boolean"
;
return
"boolean"
;
}
}
...
@@ -337,7 +337,7 @@ std::string json::get() const
...
@@ -337,7 +337,7 @@ std::string json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
return
*
value_
.
string
;
return
*
value_
.
string
;
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON string"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON string"
);
...
@@ -353,9 +353,9 @@ int json::get() const
...
@@ -353,9 +353,9 @@ int json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
return
value_
.
number
;
return
value_
.
number
;
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
return
static_cast
<
int
>
(
value_
.
number_float
);
return
static_cast
<
int
>
(
value_
.
number_float
);
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
...
@@ -371,9 +371,9 @@ int64_t json::get() const
...
@@ -371,9 +371,9 @@ int64_t json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
return
value_
.
number
;
return
value_
.
number
;
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
return
static_cast
<
number_t
>
(
value_
.
number_float
);
return
static_cast
<
number_t
>
(
value_
.
number_float
);
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
...
@@ -389,9 +389,9 @@ double json::get() const
...
@@ -389,9 +389,9 @@ double json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
return
static_cast
<
number_float_t
>
(
value_
.
number
);
return
static_cast
<
number_float_t
>
(
value_
.
number
);
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
return
value_
.
number_float
;
return
value_
.
number_float
;
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON number"
);
...
@@ -407,7 +407,7 @@ bool json::get() const
...
@@ -407,7 +407,7 @@ bool json::get() const
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
return
value_
.
boolean
;
return
value_
.
boolean
;
default:
default:
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON Boolean"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON Boolean"
);
...
@@ -421,11 +421,11 @@ bool json::get() const
...
@@ -421,11 +421,11 @@ bool json::get() const
template
<
>
template
<
>
json
::
array_t
json
::
get
()
const
json
::
array_t
json
::
get
()
const
{
{
if
(
type_
==
value_t
ype
::
array
)
if
(
type_
==
value_t
::
array
)
{
{
return
*
value_
.
array
;
return
*
value_
.
array
;
}
}
if
(
type_
==
value_t
ype
::
object
)
if
(
type_
==
value_t
::
object
)
{
{
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON array"
);
throw
std
::
logic_error
(
"cannot cast "
+
type_name
()
+
" to JSON array"
);
}
}
...
@@ -442,7 +442,7 @@ json::array_t json::get() const
...
@@ -442,7 +442,7 @@ json::array_t json::get() const
template
<
>
template
<
>
json
::
object_t
json
::
get
()
const
json
::
object_t
json
::
get
()
const
{
{
if
(
type_
==
value_t
ype
::
object
)
if
(
type_
==
value_t
::
object
)
{
{
return
*
value_
.
object
;
return
*
value_
.
object
;
}
}
...
@@ -505,27 +505,27 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
...
@@ -505,27 +505,27 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
return
std
::
string
(
"
\"
"
)
+
escapeString
(
*
value_
.
string
)
+
"
\"
"
;
return
std
::
string
(
"
\"
"
)
+
escapeString
(
*
value_
.
string
)
+
"
\"
"
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
return
value_
.
boolean
?
"true"
:
"false"
;
return
value_
.
boolean
?
"true"
:
"false"
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
return
std
::
to_string
(
value_
.
number
);
return
std
::
to_string
(
value_
.
number
);
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
return
std
::
to_string
(
value_
.
number_float
);
return
std
::
to_string
(
value_
.
number_float
);
}
}
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
if
(
value_
.
array
->
empty
())
if
(
value_
.
array
->
empty
())
{
{
...
@@ -560,7 +560,7 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
...
@@ -560,7 +560,7 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
return
result
+
indent
()
+
"]"
;
return
result
+
indent
()
+
"]"
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
if
(
value_
.
object
->
empty
())
if
(
value_
.
object
->
empty
())
{
{
...
@@ -597,7 +597,7 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
...
@@ -597,7 +597,7 @@ std::string json::dump(const bool prettyPrint, const unsigned int indentStep,
return
result
+
indent
()
+
"}"
;
return
result
+
indent
()
+
"}"
;
}
}
// actually only value_t
ype
::null - but making the compiler happy
// actually only value_t::null - but making the compiler happy
default:
default:
{
{
return
"null"
;
return
"null"
;
...
@@ -717,15 +717,15 @@ an array, the passed element is added to the array.
...
@@ -717,15 +717,15 @@ an array, the passed element is added to the array.
void
json
::
push_back
(
const
json
&
o
)
void
json
::
push_back
(
const
json
&
o
)
{
{
// push_back only works for null objects or arrays
// push_back only works for null objects or arrays
if
(
not
(
type_
==
value_t
ype
::
null
or
type_
==
value_type
::
array
))
if
(
not
(
type_
==
value_t
::
null
or
type_
==
value_t
::
array
))
{
{
throw
std
::
runtime_error
(
"cannot add element to "
+
type_name
());
throw
std
::
runtime_error
(
"cannot add element to "
+
type_name
());
}
}
// transform null object into an array
// transform null object into an array
if
(
type_
==
value_t
ype
::
null
)
if
(
type_
==
value_t
::
null
)
{
{
type_
=
value_t
ype
::
array
;
type_
=
value_t
::
array
;
value_
.
array
=
new
array_t
;
value_
.
array
=
new
array_t
;
}
}
...
@@ -752,22 +752,22 @@ an array, the passed element is added to the array using move semantics.
...
@@ -752,22 +752,22 @@ an array, the passed element is added to the array using move semantics.
void
json
::
push_back
(
json
&&
o
)
void
json
::
push_back
(
json
&&
o
)
{
{
// push_back only works for null objects or arrays
// push_back only works for null objects or arrays
if
(
not
(
type_
==
value_t
ype
::
null
or
type_
==
value_type
::
array
))
if
(
not
(
type_
==
value_t
::
null
or
type_
==
value_t
::
array
))
{
{
throw
std
::
runtime_error
(
"cannot add element to "
+
type_name
());
throw
std
::
runtime_error
(
"cannot add element to "
+
type_name
());
}
}
// transform null object into an array
// transform null object into an array
if
(
type_
==
value_t
ype
::
null
)
if
(
type_
==
value_t
::
null
)
{
{
type_
=
value_t
ype
::
array
;
type_
=
value_t
::
array
;
value_
.
array
=
new
array_t
;
value_
.
array
=
new
array_t
;
}
}
// add element to array (move semantics)
// add element to array (move semantics)
value_
.
array
->
emplace_back
(
std
::
move
(
o
));
value_
.
array
->
emplace_back
(
std
::
move
(
o
));
// invalidate object
// invalidate object
o
.
type_
=
value_t
ype
::
null
;
o
.
type_
=
value_t
::
null
;
}
}
/*!
/*!
...
@@ -789,9 +789,9 @@ void json::push_back(list_init_t a)
...
@@ -789,9 +789,9 @@ void json::push_back(list_init_t a)
// is a string
// is a string
for
(
const
auto
&
element
:
a
)
for
(
const
auto
&
element
:
a
)
{
{
if
(
element
.
type_
!=
value_t
ype
::
array
or
if
(
element
.
type_
!=
value_t
::
array
or
element
.
size
()
!=
2
or
element
.
size
()
!=
2
or
element
[
0
].
type_
!=
value_t
ype
::
string
)
element
[
0
].
type_
!=
value_t
::
string
)
{
{
// the initializer list describes an array
// the initializer list describes an array
is_array
=
true
;
is_array
=
true
;
...
@@ -832,10 +832,10 @@ index. Bounds will not be checked.
...
@@ -832,10 +832,10 @@ index. Bounds will not be checked.
@pre Object is an array.
@pre Object is an array.
@exception std::domain_error if object is not an array
@exception std::domain_error if object is not an array
*/
*/
json
&
json
::
operator
[](
const
int
index
)
json
::
reference
json
::
operator
[](
const
int
index
)
{
{
// this [] operator only works for arrays
// this [] operator only works for arrays
if
(
type_
!=
value_t
ype
::
array
)
if
(
type_
!=
value_t
::
array
)
{
{
throw
std
::
domain_error
(
"cannot add entry with index "
+
throw
std
::
domain_error
(
"cannot add entry with index "
+
std
::
to_string
(
index
)
+
" to "
+
type_name
());
std
::
to_string
(
index
)
+
" to "
+
type_name
());
...
@@ -861,10 +861,10 @@ index. Bounds will not be checked.
...
@@ -861,10 +861,10 @@ index. Bounds will not be checked.
@pre Object is an array.
@pre Object is an array.
@exception std::domain_error if object is not an array
@exception std::domain_error if object is not an array
*/
*/
const
json
&
json
::
operator
[](
const
int
index
)
const
json
::
const_reference
json
::
operator
[](
const
int
index
)
const
{
{
// this [] operator only works for arrays
// this [] operator only works for arrays
if
(
type_
!=
value_t
ype
::
array
)
if
(
type_
!=
value_t
::
array
)
{
{
throw
std
::
domain_error
(
"cannot get entry with index "
+
throw
std
::
domain_error
(
"cannot get entry with index "
+
std
::
to_string
(
index
)
+
" from "
+
type_name
());
std
::
to_string
(
index
)
+
" from "
+
type_name
());
...
@@ -891,10 +891,10 @@ index. Bounds will be checked.
...
@@ -891,10 +891,10 @@ index. Bounds will be checked.
@exception std::domain_error if object is not an array
@exception std::domain_error if object is not an array
@exception std::out_of_range if index is out of range (via std::vector::at)
@exception std::out_of_range if index is out of range (via std::vector::at)
*/
*/
json
&
json
::
at
(
const
int
index
)
json
::
reference
json
::
at
(
const
int
index
)
{
{
// this function only works for arrays
// this function only works for arrays
if
(
type_
!=
value_t
ype
::
array
)
if
(
type_
!=
value_t
::
array
)
{
{
throw
std
::
domain_error
(
"cannot add entry with index "
+
throw
std
::
domain_error
(
"cannot add entry with index "
+
std
::
to_string
(
index
)
+
" to "
+
type_name
());
std
::
to_string
(
index
)
+
" to "
+
type_name
());
...
@@ -921,10 +921,10 @@ index. Bounds will be checked.
...
@@ -921,10 +921,10 @@ index. Bounds will be checked.
@exception std::domain_error if object is not an array
@exception std::domain_error if object is not an array
@exception std::out_of_range if index is out of range (via std::vector::at)
@exception std::out_of_range if index is out of range (via std::vector::at)
*/
*/
const
json
&
json
::
at
(
const
int
index
)
const
json
::
const_reference
json
::
at
(
const
int
index
)
const
{
{
// this function only works for arrays
// this function only works for arrays
if
(
type_
!=
value_t
ype
::
array
)
if
(
type_
!=
value_t
::
array
)
{
{
throw
std
::
domain_error
(
"cannot get entry with index "
+
throw
std
::
domain_error
(
"cannot get entry with index "
+
std
::
to_string
(
index
)
+
" from "
+
type_name
());
std
::
to_string
(
index
)
+
" from "
+
type_name
());
...
@@ -937,7 +937,7 @@ const json& json::at(const int index) const
...
@@ -937,7 +937,7 @@ const json& json::at(const int index) const
/*!
/*!
@copydoc json::operator[](const char* key)
@copydoc json::operator[](const char* key)
*/
*/
json
&
json
::
operator
[](
const
std
::
string
&
key
)
json
::
reference
json
::
operator
[](
const
std
::
string
&
key
)
{
{
return
operator
[](
key
.
c_str
());
return
operator
[](
key
.
c_str
());
}
}
...
@@ -955,17 +955,17 @@ key.
...
@@ -955,17 +955,17 @@ key.
@exception std::domain_error if object is not an object (or null)
@exception std::domain_error if object is not an object (or null)
*/
*/
json
&
json
::
operator
[](
const
char
*
key
)
json
::
reference
json
::
operator
[](
const
char
*
key
)
{
{
// implicitly convert null to object
// implicitly convert null to object
if
(
type_
==
value_t
ype
::
null
)
if
(
type_
==
value_t
::
null
)
{
{
type_
=
value_t
ype
::
object
;
type_
=
value_t
::
object
;
value_
.
object
=
new
object_t
;
value_
.
object
=
new
object_t
;
}
}
// this [] operator only works for objects
// this [] operator only works for objects
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
throw
std
::
domain_error
(
"cannot add entry with key "
+
throw
std
::
domain_error
(
"cannot add entry with key "
+
std
::
string
(
key
)
+
" to "
+
type_name
());
std
::
string
(
key
)
+
" to "
+
type_name
());
...
@@ -992,10 +992,10 @@ key.
...
@@ -992,10 +992,10 @@ key.
@exception std::domain_error if object is not an object
@exception std::domain_error if object is not an object
@exception std::out_of_range if key is not found in object
@exception std::out_of_range if key is not found in object
*/
*/
const
json
&
json
::
operator
[](
const
std
::
string
&
key
)
const
json
::
const_reference
json
::
operator
[](
const
std
::
string
&
key
)
const
{
{
// this [] operator only works for objects
// this [] operator only works for objects
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
throw
std
::
domain_error
(
"cannot get entry with key "
+
throw
std
::
domain_error
(
"cannot get entry with key "
+
std
::
string
(
key
)
+
" from "
+
type_name
());
std
::
string
(
key
)
+
" from "
+
type_name
());
...
@@ -1017,7 +1017,7 @@ const json& json::operator[](const std::string& key) const
...
@@ -1017,7 +1017,7 @@ const json& json::operator[](const std::string& key) const
/*!
/*!
@copydoc json::at(const char* key)
@copydoc json::at(const char* key)
*/
*/
json
&
json
::
at
(
const
std
::
string
&
key
)
json
::
reference
json
::
at
(
const
std
::
string
&
key
)
{
{
return
at
(
key
.
c_str
());
return
at
(
key
.
c_str
());
}
}
...
@@ -1035,10 +1035,10 @@ key.
...
@@ -1035,10 +1035,10 @@ key.
@exception std::domain_error if object is not an object
@exception std::domain_error if object is not an object
@exception std::out_of_range if key was not found (via std::map::at)
@exception std::out_of_range if key was not found (via std::map::at)
*/
*/
json
&
json
::
at
(
const
char
*
key
)
json
::
reference
json
::
at
(
const
char
*
key
)
{
{
// this function operator only works for objects
// this function operator only works for objects
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
throw
std
::
domain_error
(
"cannot add entry with key "
+
throw
std
::
domain_error
(
"cannot add entry with key "
+
std
::
string
(
key
)
+
" to "
+
type_name
());
std
::
string
(
key
)
+
" to "
+
type_name
());
...
@@ -1051,7 +1051,7 @@ json& json::at(const char* key)
...
@@ -1051,7 +1051,7 @@ json& json::at(const char* key)
/*!
/*!
@copydoc json::at(const char *key) const
@copydoc json::at(const char *key) const
*/
*/
const
json
&
json
::
at
(
const
std
::
string
&
key
)
const
json
::
const_reference
json
::
at
(
const
std
::
string
&
key
)
const
{
{
return
at
(
key
.
c_str
());
return
at
(
key
.
c_str
());
}
}
...
@@ -1067,10 +1067,10 @@ key.
...
@@ -1067,10 +1067,10 @@ key.
@exception std::domain_error if object is not an object
@exception std::domain_error if object is not an object
@exception std::out_of_range if key is not found (via std::map::at)
@exception std::out_of_range if key is not found (via std::map::at)
*/
*/
const
json
&
json
::
at
(
const
char
*
key
)
const
json
::
const_reference
json
::
at
(
const
char
*
key
)
const
{
{
// this [] operator only works for objects
// this [] operator only works for objects
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
throw
std
::
domain_error
(
"cannot get entry with key "
+
throw
std
::
domain_error
(
"cannot get entry with key "
+
std
::
string
(
key
)
+
" from "
+
type_name
());
std
::
string
(
key
)
+
" from "
+
type_name
());
...
@@ -1080,7 +1080,6 @@ const json& json::at(const char* key) const
...
@@ -1080,7 +1080,6 @@ const json& json::at(const char* key) const
return
value_
.
object
->
at
(
key
);
return
value_
.
object
->
at
(
key
);
}
}
/*!
/*!
Returns the size of the JSON object.
Returns the size of the JSON object.
...
@@ -1090,19 +1089,49 @@ Returns the size of the JSON object.
...
@@ -1090,19 +1089,49 @@ Returns the size of the JSON object.
@invariant The size is reported as 0 if and only if empty() would return true.
@invariant The size is reported as 0 if and only if empty() would return true.
*/
*/
std
::
size_t
json
::
size
()
const
noexcept
json
::
size_type
json
::
size
()
const
noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
return
value_
.
array
->
size
();
return
value_
.
array
->
size
();
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
return
value_
.
object
->
size
();
return
value_
.
object
->
size
();
}
}
case
(
value_type
:
:
null
)
:
case
(
value_t
:
:
null
)
:
{
return
0
;
}
default:
{
return
1
;
}
}
}
/*!
Returns the maximal size of the JSON object.
@return the maximal size of the JSON object; the maximal size is the maximal
number of elements in compounds (array and object), 1 for value types
(true, false, number, string), and 0 for null.
*/
json
::
size_type
json
::
max_size
()
const
noexcept
{
switch
(
type_
)
{
case
(
value_t
:
:
array
)
:
{
return
value_
.
array
->
max_size
();
}
case
(
value_t
:
:
object
)
:
{
return
value_
.
object
->
max_size
();
}
case
(
value_t
:
:
null
)
:
{
{
return
0
;
return
0
;
}
}
...
@@ -1126,15 +1155,15 @@ bool json::empty() const noexcept
...
@@ -1126,15 +1155,15 @@ bool json::empty() const noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
return
value_
.
array
->
empty
();
return
value_
.
array
->
empty
();
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
return
value_
.
object
->
empty
();
return
value_
.
object
->
empty
();
}
}
case
(
value_t
ype
:
:
null
)
:
case
(
value_t
:
:
null
)
:
{
{
return
true
;
return
true
;
}
}
...
@@ -1156,32 +1185,32 @@ void json::clear() noexcept
...
@@ -1156,32 +1185,32 @@ void json::clear() noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
value_
.
array
->
clear
();
value_
.
array
->
clear
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
value_
.
object
->
clear
();
value_
.
object
->
clear
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
value_
.
string
->
clear
();
value_
.
string
->
clear
();
break
;
break
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
value_
.
boolean
=
{};
value_
.
boolean
=
{};
break
;
break
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
value_
.
number
=
{};
value_
.
number
=
{};
break
;
break
;
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
value_
.
number_float
=
{};
value_
.
number_float
=
{};
break
;
break
;
...
@@ -1199,7 +1228,7 @@ void json::swap(json& o) noexcept
...
@@ -1199,7 +1228,7 @@ void json::swap(json& o) noexcept
std
::
swap
(
value_
,
o
.
value_
);
std
::
swap
(
value_
,
o
.
value_
);
}
}
json
::
value_t
ype
json
::
type
()
const
noexcept
json
::
value_t
json
::
type
()
const
noexcept
{
{
return
type_
;
return
type_
;
}
}
...
@@ -1216,7 +1245,7 @@ json::const_iterator json::find(const std::string& key) const
...
@@ -1216,7 +1245,7 @@ json::const_iterator json::find(const std::string& key) const
json
::
iterator
json
::
find
(
const
char
*
key
)
json
::
iterator
json
::
find
(
const
char
*
key
)
{
{
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
return
end
();
return
end
();
}
}
...
@@ -1240,7 +1269,7 @@ json::iterator json::find(const char* key)
...
@@ -1240,7 +1269,7 @@ json::iterator json::find(const char* key)
json
::
const_iterator
json
::
find
(
const
char
*
key
)
const
json
::
const_iterator
json
::
find
(
const
char
*
key
)
const
{
{
if
(
type_
!=
value_t
ype
::
object
)
if
(
type_
!=
value_t
::
object
)
{
{
return
end
();
return
end
();
}
}
...
@@ -1266,65 +1295,65 @@ bool json::operator==(const json& o) const noexcept
...
@@ -1266,65 +1295,65 @@ bool json::operator==(const json& o) const noexcept
{
{
switch
(
type_
)
switch
(
type_
)
{
{
case
(
value_t
ype
:
:
array
)
:
case
(
value_t
:
:
array
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
array
)
if
(
o
.
type_
==
value_t
::
array
)
{
{
return
*
value_
.
array
==
*
o
.
value_
.
array
;
return
*
value_
.
array
==
*
o
.
value_
.
array
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
object
)
:
case
(
value_t
:
:
object
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
object
)
if
(
o
.
type_
==
value_t
::
object
)
{
{
return
*
value_
.
object
==
*
o
.
value_
.
object
;
return
*
value_
.
object
==
*
o
.
value_
.
object
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
null
)
:
case
(
value_t
:
:
null
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
null
)
if
(
o
.
type_
==
value_t
::
null
)
{
{
return
true
;
return
true
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
string
)
:
case
(
value_t
:
:
string
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
string
)
if
(
o
.
type_
==
value_t
::
string
)
{
{
return
*
value_
.
string
==
*
o
.
value_
.
string
;
return
*
value_
.
string
==
*
o
.
value_
.
string
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
boolean
)
:
case
(
value_t
:
:
boolean
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
boolean
)
if
(
o
.
type_
==
value_t
::
boolean
)
{
{
return
value_
.
boolean
==
o
.
value_
.
boolean
;
return
value_
.
boolean
==
o
.
value_
.
boolean
;
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
number
)
:
case
(
value_t
:
:
number
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
number
)
if
(
o
.
type_
==
value_t
::
number
)
{
{
return
value_
.
number
==
o
.
value_
.
number
;
return
value_
.
number
==
o
.
value_
.
number
;
}
}
if
(
o
.
type_
==
value_t
ype
::
number_float
)
if
(
o
.
type_
==
value_t
::
number_float
)
{
{
return
value_
.
number
==
static_cast
<
number_t
>
(
o
.
value_
.
number_float
);
return
value_
.
number
==
static_cast
<
number_t
>
(
o
.
value_
.
number_float
);
}
}
break
;
break
;
}
}
case
(
value_t
ype
:
:
number_float
)
:
case
(
value_t
:
:
number_float
)
:
{
{
if
(
o
.
type_
==
value_t
ype
::
number
)
if
(
o
.
type_
==
value_t
::
number
)
{
{
return
value_
.
number_float
==
static_cast
<
number_float_t
>
(
o
.
value_
.
number
);
return
value_
.
number_float
==
static_cast
<
number_float_t
>
(
o
.
value_
.
number
);
}
}
if
(
o
.
type_
==
value_t
ype
::
number_float
)
if
(
o
.
type_
==
value_t
::
number_float
)
{
{
return
value_
.
number_float
==
o
.
value_
.
number_float
;
return
value_
.
number_float
==
o
.
value_
.
number_float
;
}
}
...
@@ -1376,7 +1405,7 @@ json::iterator::iterator(json* j) : object_(j)
...
@@ -1376,7 +1405,7 @@ json::iterator::iterator(json* j) : object_(j)
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1387,7 +1416,7 @@ json::iterator::iterator(json* j) : object_(j)
...
@@ -1387,7 +1416,7 @@ json::iterator::iterator(json* j) : object_(j)
vi_
=
new
array_t
::
iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1405,7 +1434,7 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
...
@@ -1405,7 +1434,7 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1416,7 +1445,7 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
...
@@ -1416,7 +1445,7 @@ json::iterator::iterator(const json::iterator& o) : object_(o.object_)
vi_
=
new
array_t
::
iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1453,11 +1482,11 @@ bool json::iterator::operator==(const json::iterator& o) const
...
@@ -1453,11 +1482,11 @@ bool json::iterator::operator==(const json::iterator& o) const
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
return
(
vi_
==
o
.
vi_
);
return
(
vi_
==
o
.
vi_
);
}
}
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
return
(
oi_
==
o
.
oi_
);
return
(
oi_
==
o
.
oi_
);
}
}
...
@@ -1481,7 +1510,7 @@ json::iterator& json::iterator::operator++()
...
@@ -1481,7 +1510,7 @@ json::iterator& json::iterator::operator++()
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
if
(
++
(
*
vi_
)
==
object_
->
value_
.
array
->
end
())
if
(
++
(
*
vi_
)
==
object_
->
value_
.
array
->
end
())
{
{
...
@@ -1489,7 +1518,7 @@ json::iterator& json::iterator::operator++()
...
@@ -1489,7 +1518,7 @@ json::iterator& json::iterator::operator++()
}
}
break
;
break
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
if
(
++
(
*
oi_
)
==
object_
->
value_
.
object
->
end
())
if
(
++
(
*
oi_
)
==
object_
->
value_
.
object
->
end
())
{
{
...
@@ -1515,11 +1544,11 @@ json& json::iterator::operator*() const
...
@@ -1515,11 +1544,11 @@ json& json::iterator::operator*() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
**
vi_
;
return
**
vi_
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
(
*
oi_
)
->
second
;
return
(
*
oi_
)
->
second
;
}
}
...
@@ -1540,11 +1569,11 @@ json* json::iterator::operator->() const
...
@@ -1540,11 +1569,11 @@ json* json::iterator::operator->() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
&
(
**
vi_
);
return
&
(
**
vi_
);
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
&
((
*
oi_
)
->
second
);
return
&
((
*
oi_
)
->
second
);
}
}
...
@@ -1557,7 +1586,7 @@ json* json::iterator::operator->() const
...
@@ -1557,7 +1586,7 @@ json* json::iterator::operator->() const
std
::
string
json
::
iterator
::
key
()
const
std
::
string
json
::
iterator
::
key
()
const
{
{
if
(
object_
!=
nullptr
and
object_
->
type_
==
json
::
value_t
ype
::
object
)
if
(
object_
!=
nullptr
and
object_
->
type_
==
json
::
value_t
::
object
)
{
{
return
(
*
oi_
)
->
first
;
return
(
*
oi_
)
->
first
;
}
}
...
@@ -1577,11 +1606,11 @@ json& json::iterator::value() const
...
@@ -1577,11 +1606,11 @@ json& json::iterator::value() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
**
vi_
;
return
**
vi_
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
(
*
oi_
)
->
second
;
return
(
*
oi_
)
->
second
;
}
}
...
@@ -1597,7 +1626,7 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
...
@@ -1597,7 +1626,7 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1608,7 +1637,7 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
...
@@ -1608,7 +1637,7 @@ json::const_iterator::const_iterator(const json* j) : object_(j)
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1626,7 +1655,7 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
...
@@ -1626,7 +1655,7 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1637,7 +1666,7 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
...
@@ -1637,7 +1666,7 @@ json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1655,7 +1684,7 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
...
@@ -1655,7 +1684,7 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
{
{
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1666,7 +1695,7 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
...
@@ -1666,7 +1695,7 @@ json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
vi_
=
new
array_t
::
const_iterator
(
object_
->
value_
.
array
->
begin
());
}
}
}
}
else
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
else
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
if
(
object_
->
empty
())
if
(
object_
->
empty
())
{
{
...
@@ -1703,11 +1732,11 @@ bool json::const_iterator::operator==(const json::const_iterator& o) const
...
@@ -1703,11 +1732,11 @@ bool json::const_iterator::operator==(const json::const_iterator& o) const
if
(
object_
!=
nullptr
)
if
(
object_
!=
nullptr
)
{
{
if
(
object_
->
type_
==
json
::
value_t
ype
::
array
)
if
(
object_
->
type_
==
json
::
value_t
::
array
)
{
{
return
(
vi_
==
o
.
vi_
);
return
(
vi_
==
o
.
vi_
);
}
}
if
(
object_
->
type_
==
json
::
value_t
ype
::
object
)
if
(
object_
->
type_
==
json
::
value_t
::
object
)
{
{
return
(
oi_
==
o
.
oi_
);
return
(
oi_
==
o
.
oi_
);
}
}
...
@@ -1731,7 +1760,7 @@ json::const_iterator& json::const_iterator::operator++()
...
@@ -1731,7 +1760,7 @@ json::const_iterator& json::const_iterator::operator++()
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
if
(
++
(
*
vi_
)
==
object_
->
value_
.
array
->
end
())
if
(
++
(
*
vi_
)
==
object_
->
value_
.
array
->
end
())
{
{
...
@@ -1739,7 +1768,7 @@ json::const_iterator& json::const_iterator::operator++()
...
@@ -1739,7 +1768,7 @@ json::const_iterator& json::const_iterator::operator++()
}
}
break
;
break
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
if
(
++
(
*
oi_
)
==
object_
->
value_
.
object
->
end
())
if
(
++
(
*
oi_
)
==
object_
->
value_
.
object
->
end
())
{
{
...
@@ -1765,11 +1794,11 @@ const json& json::const_iterator::operator*() const
...
@@ -1765,11 +1794,11 @@ const json& json::const_iterator::operator*() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
**
vi_
;
return
**
vi_
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
(
*
oi_
)
->
second
;
return
(
*
oi_
)
->
second
;
}
}
...
@@ -1790,11 +1819,11 @@ const json* json::const_iterator::operator->() const
...
@@ -1790,11 +1819,11 @@ const json* json::const_iterator::operator->() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
&
(
**
vi_
);
return
&
(
**
vi_
);
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
&
((
*
oi_
)
->
second
);
return
&
((
*
oi_
)
->
second
);
}
}
...
@@ -1807,7 +1836,7 @@ const json* json::const_iterator::operator->() const
...
@@ -1807,7 +1836,7 @@ const json* json::const_iterator::operator->() const
std
::
string
json
::
const_iterator
::
key
()
const
std
::
string
json
::
const_iterator
::
key
()
const
{
{
if
(
object_
!=
nullptr
and
object_
->
type_
==
json
::
value_t
ype
::
object
)
if
(
object_
!=
nullptr
and
object_
->
type_
==
json
::
value_t
::
object
)
{
{
return
(
*
oi_
)
->
first
;
return
(
*
oi_
)
->
first
;
}
}
...
@@ -1827,11 +1856,11 @@ const json& json::const_iterator::value() const
...
@@ -1827,11 +1856,11 @@ const json& json::const_iterator::value() const
switch
(
object_
->
type_
)
switch
(
object_
->
type_
)
{
{
case
(
json
:
:
value_t
ype
::
array
)
:
case
(
json
:
:
value_t
::
array
)
:
{
{
return
**
vi_
;
return
**
vi_
;
}
}
case
(
json
:
:
value_t
ype
::
object
)
:
case
(
json
:
:
value_t
::
object
)
:
{
{
return
(
*
oi_
)
->
second
;
return
(
*
oi_
)
->
second
;
}
}
...
@@ -1901,7 +1930,7 @@ json json::parser::parse()
...
@@ -1901,7 +1930,7 @@ json json::parser::parse()
case
(
'{'
):
case
(
'{'
):
{
{
// explicitly set result to object to cope with {}
// explicitly set result to object to cope with {}
json
result
(
value_t
ype
::
object
);
json
result
(
value_t
::
object
);
next
();
next
();
...
@@ -1932,7 +1961,7 @@ json json::parser::parse()
...
@@ -1932,7 +1961,7 @@ json json::parser::parse()
case
(
'['
):
case
(
'['
):
{
{
// explicitly set result to array to cope with []
// explicitly set result to array to cope with []
json
result
(
value_t
ype
::
array
);
json
result
(
value_t
::
array
);
next
();
next
();
...
...
This diff is collapsed.
Click to expand it.
src/json.h
View file @
76be1ae1
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
@file
@file
@copyright The code is licensed under the MIT License
@copyright The code is licensed under the MIT License
<http://opensource.org/licenses/MIT>,
<http://opensource.org/licenses/MIT>,
Copyright (c) 2013-201
4
Niels Lohmann.
Copyright (c) 2013-201
5
Niels Lohmann.
@author Niels Lohmann <http://nlohmann.me>
@author Niels Lohmann <http://nlohmann.me>
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
#include <vector> // std::vector
#include <vector> // std::vector
#include <iterator> // std::iterator
#include <iterator> // std::iterator
#include <limits> // std::numeric_limits
#include <limits> // std::numeric_limits
#include <functional> // std::hash
namespace
nlohmann
namespace
nlohmann
{
{
...
@@ -41,30 +42,21 @@ due to alignment.
...
@@ -41,30 +42,21 @@ due to alignment.
*/
*/
class
json
class
json
{
{
// forward declaration to friend this class
public:
public:
// forward declaration to friend this class
class
iterator
;
class
iterator
;
class
const_iterator
;
class
const_iterator
;
public:
// container types
/// possible types of a JSON object
using
value_type
=
json
;
enum
class
value_type
:
uint8_t
using
reference
=
json
&
;
{
using
const_reference
=
const
json
&
;
/// ordered collection of values
using
pointer
=
json
*
;
array
=
0
,
using
const_pointer
=
const
json
*
;
/// unordered set of name/value pairs
using
iterator
=
json
::
iterator
;
object
,
using
const_iterator
=
json
::
const_iterator
;
/// null value
using
difference_type
=
std
::
ptrdiff_t
;
null
,
using
size_type
=
std
::
size_t
;
/// string value
string
,
/// Boolean value
boolean
,
/// number value (integer)
number
,
/// number value (float)
number_float
};
/// a type for an object
/// a type for an object
using
object_t
=
std
::
map
<
std
::
string
,
json
>
;
using
object_t
=
std
::
map
<
std
::
string
,
json
>
;
...
@@ -113,9 +105,28 @@ class json
...
@@ -113,9 +105,28 @@ class json
value
(
number_float_t
);
value
(
number_float_t
);
};
};
/// possible types of a JSON object
enum
class
value_t
:
uint8_t
{
/// ordered collection of values
array
=
0
,
/// unordered set of name/value pairs
object
,
/// null value
null
,
/// string value
string
,
/// Boolean value
boolean
,
/// number value (integer)
number
,
/// number value (float)
number_float
};
public:
public:
/// create an object according to given type
/// create an object according to given type
json
(
const
value_t
ype
);
json
(
const
value_t
);
/// create a null object
/// create a null object
json
()
=
default
;
json
()
=
default
;
/// create a null object
/// create a null object
...
@@ -140,15 +151,23 @@ class json
...
@@ -140,15 +151,23 @@ class json
json
(
list_init_t
);
json
(
list_init_t
);
/// create a number object (integer)
/// create a number object (integer)
template
<
typename
T
,
typename
std
::
enable_if
<
std
::
numeric_limits
<
T
>
::
is_integer
,
T
>::
type
=
0
>
template
<
typename
T
,
typename
std
::
enable_if
<
std
::
numeric_limits
<
T
>
::
is_integer
,
T
>::
type
=
0
>
json
(
const
T
n
)
noexcept
json
(
const
T
n
)
noexcept
:
type_
(
value_type
::
number
),
value_
(
static_cast
<
number_t
>
(
n
))
:
type_
(
value_t
::
number
),
value_
(
static_cast
<
number_t
>
(
n
))
{}
{}
/// create a number object (float)
/// create a number object (float)
template
<
typename
T
,
typename
=
typename
std
::
enable_if
<
std
::
is_floating_point
<
T
>
::
value
>::
type
>
template
<
typename
T
,
typename
=
typename
std
::
enable_if
<
std
::
is_floating_point
<
T
>
::
value
>::
type
>
json
(
const
T
n
)
noexcept
json
(
const
T
n
)
noexcept
:
type_
(
value_type
::
number_float
),
value_
(
static_cast
<
number_float_t
>
(
n
))
:
type_
(
value_t
::
number_float
),
value_
(
static_cast
<
number_float_t
>
(
n
))
{}
{}
/// create an array object
/// create an array object
...
@@ -284,27 +303,29 @@ class json
...
@@ -284,27 +303,29 @@ class json
/// operator to get an element in an array
/// operator to get an element in an array
const
json
&
operator
[](
const
int
)
const
;
const
json
&
operator
[](
const
int
)
const
;
/// operator to get an element in an array
/// operator to get an element in an array
json
&
at
(
const
int
);
reference
at
(
const
int
);
/// operator to get an element in an array
/// operator to get an element in an array
const
json
&
at
(
const
int
)
const
;
const
_reference
at
(
const
int
)
const
;
/// operator to set an element in an object
/// operator to set an element in an object
json
&
operator
[](
const
std
::
string
&
);
reference
operator
[](
const
std
::
string
&
);
/// operator to set an element in an object
/// operator to set an element in an object
json
&
operator
[](
const
char
*
);
reference
operator
[](
const
char
*
);
/// operator to get an element in an object
/// operator to get an element in an object
const
json
&
operator
[](
const
std
::
string
&
)
const
;
const
_reference
operator
[](
const
std
::
string
&
)
const
;
/// operator to set an element in an object
/// operator to set an element in an object
json
&
at
(
const
std
::
string
&
);
reference
at
(
const
std
::
string
&
);
/// operator to set an element in an object
/// operator to set an element in an object
json
&
at
(
const
char
*
);
reference
at
(
const
char
*
);
/// operator to get an element in an object
/// operator to get an element in an object
const
json
&
at
(
const
std
::
string
&
)
const
;
const
_reference
at
(
const
std
::
string
&
)
const
;
/// operator to get an element in an object
/// operator to get an element in an object
const
json
&
at
(
const
char
*
)
const
;
const
_reference
at
(
const
char
*
)
const
;
/// return the number of stored values
/// return the number of stored values
std
::
size_t
size
()
const
noexcept
;
size_type
size
()
const
noexcept
;
/// return the maximal number of values that can be stored
size_type
max_size
()
const
noexcept
;
/// checks whether object is empty
/// checks whether object is empty
bool
empty
()
const
noexcept
;
bool
empty
()
const
noexcept
;
/// removes all elements from compounds and resets values to default
/// removes all elements from compounds and resets values to default
...
@@ -314,7 +335,7 @@ class json
...
@@ -314,7 +335,7 @@ class json
void
swap
(
json
&
)
noexcept
;
void
swap
(
json
&
)
noexcept
;
/// return the type of the object
/// return the type of the object
value_t
ype
type
()
const
noexcept
;
value_t
type
()
const
noexcept
;
/// find an element in an object (returns end() iterator otherwise)
/// find an element in an object (returns end() iterator otherwise)
iterator
find
(
const
std
::
string
&
);
iterator
find
(
const
std
::
string
&
);
...
@@ -345,7 +366,7 @@ class json
...
@@ -345,7 +366,7 @@ class json
private:
private:
/// the type of this object
/// the type of this object
value_t
ype
type_
=
value_type
::
null
;
value_t
type_
=
value_t
::
null
;
/// the payload
/// the payload
value
value_
{};
value
value_
{};
...
@@ -475,15 +496,29 @@ class json
...
@@ -475,15 +496,29 @@ class json
/// user-defined literal operator to create JSON objects from strings
/// user-defined literal operator to create JSON objects from strings
nlohmann
::
json
operator
""
_json
(
const
char
*
,
std
::
size_t
);
nlohmann
::
json
operator
""
_json
(
const
char
*
,
std
::
size_t
);
// specialization of std::swap
// specialization of std::swap
, and std::hash
namespace
std
namespace
std
{
{
template
<
>
template
<
>
/// swaps the values of two JSON objects
/// swaps the values of two JSON objects
inline
void
swap
(
nlohmann
::
json
&
j1
,
inline
void
swap
(
nlohmann
::
json
&
j1
,
nlohmann
::
json
&
j2
)
noexcept
(
is_nothrow_move_constructible
<
nlohmann
::
json
>::
value
and
nlohmann
::
json
&
j2
)
noexcept
(
is_nothrow_move_assignable
<
nlohmann
::
json
>::
value
)
is_nothrow_move_constructible
<
nlohmann
::
json
>::
value
and
is_nothrow_move_assignable
<
nlohmann
::
json
>::
value
)
{
{
j1
.
swap
(
j2
);
j1
.
swap
(
j2
);
}
}
template
<
>
/// hash value for JSON objects
struct
hash
<
nlohmann
::
json
>
{
size_t
operator
()(
const
nlohmann
::
json
&
j
)
const
{
// a naive hashing via the string representation
return
hash
<
std
::
string
>
()(
j
.
dump
());
}
};
}
}
This diff is collapsed.
Click to expand it.
test/json_unit.cc
View file @
76be1ae1
...
@@ -19,8 +19,8 @@ TEST_CASE("array")
...
@@ -19,8 +19,8 @@ TEST_CASE("array")
SECTION
(
"Basics"
)
SECTION
(
"Basics"
)
{
{
// construction with given type
// construction with given type
json
j
(
json
::
value_t
ype
::
array
);
json
j
(
json
::
value_t
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
array
);
// const object
// const object
const
json
j_const
(
j
);
const
json
j_const
(
j
);
...
@@ -34,7 +34,9 @@ TEST_CASE("array")
...
@@ -34,7 +34,9 @@ TEST_CASE("array")
// container members
// container members
CHECK
(
j
.
size
()
==
0
);
CHECK
(
j
.
size
()
==
0
);
CHECK
(
j
.
max_size
()
>
0
);
CHECK
(
j
.
empty
()
==
true
);
CHECK
(
j
.
empty
()
==
true
);
CHECK_NOTHROW
(
size_t
h
=
std
::
hash
<
json
>
()(
j
));
// implicit conversions
// implicit conversions
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
...
@@ -88,21 +90,21 @@ TEST_CASE("array")
...
@@ -88,21 +90,21 @@ TEST_CASE("array")
// case 1: there is an element that is not an array
// case 1: there is an element that is not an array
json
j3
=
{
{
"foo"
,
"bar"
},
3
};
json
j3
=
{
{
"foo"
,
"bar"
},
3
};
CHECK
(
j3
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j3
.
type
()
==
json
::
value_t
::
array
);
// case 2: there is an element with more than two elements
// case 2: there is an element with more than two elements
json
j4
=
{
{
"foo"
,
"bar"
},
{
"one"
,
"two"
,
"three"
}
};
json
j4
=
{
{
"foo"
,
"bar"
},
{
"one"
,
"two"
,
"three"
}
};
CHECK
(
j4
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j4
.
type
()
==
json
::
value_t
::
array
);
// case 3: there is an element whose first element is not a string
// case 3: there is an element whose first element is not a string
json
j5
=
{
{
"foo"
,
"bar"
},
{
true
,
"baz"
}
};
json
j5
=
{
{
"foo"
,
"bar"
},
{
true
,
"baz"
}
};
CHECK
(
j5
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j5
.
type
()
==
json
::
value_t
::
array
);
// check if nested arrays work and are recognized as arrays
// check if nested arrays work and are recognized as arrays
json
j6
=
{
{{
"foo"
,
"bar"
}}
};
json
j6
=
{
{{
"foo"
,
"bar"
}}
};
CHECK
(
j6
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j6
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j6
.
size
()
==
1
);
CHECK
(
j6
.
size
()
==
1
);
CHECK
(
j6
[
0
].
type
()
==
json
::
value_t
ype
::
object
);
CHECK
(
j6
[
0
].
type
()
==
json
::
value_t
::
object
);
// move constructor
// move constructor
json
j7
(
std
::
move
(
v1
));
json
j7
(
std
::
move
(
v1
));
...
@@ -152,8 +154,8 @@ TEST_CASE("array")
...
@@ -152,8 +154,8 @@ TEST_CASE("array")
json
empty1
,
empty2
;
json
empty1
,
empty2
;
empty1
+=
"foo"
;
empty1
+=
"foo"
;
empty2
.
push_back
(
"foo"
);
empty2
.
push_back
(
"foo"
);
CHECK
(
empty1
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
empty1
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
empty2
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
empty2
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
empty1
==
empty2
);
CHECK
(
empty1
==
empty2
);
// exceptions
// exceptions
...
@@ -182,7 +184,7 @@ TEST_CASE("array")
...
@@ -182,7 +184,7 @@ TEST_CASE("array")
CHECK_THROWS_AS
(
nonarray2
.
push_back
(
nonarray3
),
std
::
runtime_error
);
CHECK_THROWS_AS
(
nonarray2
.
push_back
(
nonarray3
),
std
::
runtime_error
);
CHECK_THROWS_AS
(
nonarray2
.
push_back
(
3
),
std
::
runtime_error
);
CHECK_THROWS_AS
(
nonarray2
.
push_back
(
3
),
std
::
runtime_error
);
CHECK_NOTHROW
(
empty3
.
push_back
(
nonarray3
));
CHECK_NOTHROW
(
empty3
.
push_back
(
nonarray3
));
CHECK
(
empty3
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
empty3
.
type
()
==
json
::
value_t
::
array
);
}
}
const
json
k
=
j
;
const
json
k
=
j
;
...
@@ -300,12 +302,12 @@ TEST_CASE("array")
...
@@ -300,12 +302,12 @@ TEST_CASE("array")
// turn arrays with two strings. However, this is treated like the
// turn arrays with two strings. However, this is treated like the
// initializer list of an object.
// initializer list of an object.
json
j_should_be_an_array
=
{
{
"foo"
,
"bar"
},
{
"baz"
,
"bat"
}
};
json
j_should_be_an_array
=
{
{
"foo"
,
"bar"
},
{
"baz"
,
"bat"
}
};
CHECK
(
j_should_be_an_array
.
type
()
==
json
::
value_t
ype
::
object
);
CHECK
(
j_should_be_an_array
.
type
()
==
json
::
value_t
::
object
);
}
}
SECTION
(
"Iterators and empty arrays"
)
SECTION
(
"Iterators and empty arrays"
)
{
{
json
empty_array
(
json
::
value_t
ype
::
array
);
json
empty_array
(
json
::
value_t
::
array
);
for
(
json
::
iterator
it
=
empty_array
.
begin
();
it
!=
empty_array
.
end
();
++
it
)
{}
for
(
json
::
iterator
it
=
empty_array
.
begin
();
it
!=
empty_array
.
end
();
++
it
)
{}
for
(
json
::
const_iterator
it
=
empty_array
.
begin
();
it
!=
empty_array
.
end
();
++
it
)
{}
for
(
json
::
const_iterator
it
=
empty_array
.
begin
();
it
!=
empty_array
.
end
();
++
it
)
{}
for
(
json
::
const_iterator
it
=
empty_array
.
cbegin
();
it
!=
empty_array
.
cend
();
++
it
)
{}
for
(
json
::
const_iterator
it
=
empty_array
.
cbegin
();
it
!=
empty_array
.
cend
();
++
it
)
{}
...
@@ -338,47 +340,47 @@ TEST_CASE("array")
...
@@ -338,47 +340,47 @@ TEST_CASE("array")
{
{
std
::
vector
<
int
>
c_vector
{
1
,
2
,
3
,
4
};
std
::
vector
<
int
>
c_vector
{
1
,
2
,
3
,
4
};
json
j_vec
(
c_vector
);
json
j_vec
(
c_vector
);
CHECK
(
j_vec
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_vec
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_vec
.
size
()
==
4
);
CHECK
(
j_vec
.
size
()
==
4
);
std
::
set
<
std
::
string
>
c_set
{
"one"
,
"two"
,
"three"
,
"four"
,
"one"
};
std
::
set
<
std
::
string
>
c_set
{
"one"
,
"two"
,
"three"
,
"four"
,
"one"
};
json
j_set
(
c_set
);
json
j_set
(
c_set
);
CHECK
(
j_set
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_set
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_set
.
size
()
==
4
);
CHECK
(
j_set
.
size
()
==
4
);
std
::
unordered_set
<
std
::
string
>
c_uset
{
"one"
,
"two"
,
"three"
,
"four"
,
"one"
};
std
::
unordered_set
<
std
::
string
>
c_uset
{
"one"
,
"two"
,
"three"
,
"four"
,
"one"
};
json
j_uset
(
c_uset
);
json
j_uset
(
c_uset
);
CHECK
(
j_uset
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_uset
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_uset
.
size
()
==
4
);
CHECK
(
j_uset
.
size
()
==
4
);
std
::
multiset
<
std
::
string
>
c_mset
{
"one"
,
"two"
,
"one"
,
"four"
};
std
::
multiset
<
std
::
string
>
c_mset
{
"one"
,
"two"
,
"one"
,
"four"
};
json
j_mset
(
c_mset
);
json
j_mset
(
c_mset
);
CHECK
(
j_mset
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_mset
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_mset
.
size
()
==
4
);
CHECK
(
j_mset
.
size
()
==
4
);
std
::
unordered_multiset
<
std
::
string
>
c_umset
{
"one"
,
"two"
,
"one"
,
"four"
};
std
::
unordered_multiset
<
std
::
string
>
c_umset
{
"one"
,
"two"
,
"one"
,
"four"
};
json
j_umset
(
c_umset
);
json
j_umset
(
c_umset
);
CHECK
(
j_umset
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_umset
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_umset
.
size
()
==
4
);
CHECK
(
j_umset
.
size
()
==
4
);
std
::
deque
<
float
>
c_deque
{
1.2
,
2.3
,
3.4
,
5.6
};
std
::
deque
<
float
>
c_deque
{
1.2
,
2.3
,
3.4
,
5.6
};
json
j_deque
(
c_deque
);
json
j_deque
(
c_deque
);
CHECK
(
j_deque
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_deque
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_deque
.
size
()
==
4
);
CHECK
(
j_deque
.
size
()
==
4
);
std
::
list
<
bool
>
c_list
{
true
,
true
,
false
,
true
};
std
::
list
<
bool
>
c_list
{
true
,
true
,
false
,
true
};
json
j_list
(
c_list
);
json
j_list
(
c_list
);
CHECK
(
j_list
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_list
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_list
.
size
()
==
4
);
CHECK
(
j_list
.
size
()
==
4
);
std
::
forward_list
<
int64_t
>
c_flist
{
12345678909876
,
23456789098765
,
34567890987654
,
45678909876543
};
std
::
forward_list
<
int64_t
>
c_flist
{
12345678909876
,
23456789098765
,
34567890987654
,
45678909876543
};
json
j_flist
(
c_flist
);
json
j_flist
(
c_flist
);
CHECK
(
j_flist
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_flist
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_flist
.
size
()
==
4
);
CHECK
(
j_flist
.
size
()
==
4
);
std
::
array
<
unsigned
long
,
4
>
c_array
{{
1
,
2
,
3
,
4
}};
std
::
array
<
unsigned
long
,
4
>
c_array
{{
1
,
2
,
3
,
4
}};
json
j_array
(
c_array
);
json
j_array
(
c_array
);
CHECK
(
j_array
.
type
()
==
json
::
value_t
ype
::
array
);
CHECK
(
j_array
.
type
()
==
json
::
value_t
::
array
);
CHECK
(
j_array
.
size
()
==
4
);
CHECK
(
j_array
.
size
()
==
4
);
}
}
}
}
...
@@ -388,8 +390,8 @@ TEST_CASE("object")
...
@@ -388,8 +390,8 @@ TEST_CASE("object")
SECTION
(
"Basics"
)
SECTION
(
"Basics"
)
{
{
// construction with given type
// construction with given type
json
j
(
json
::
value_t
ype
::
object
);
json
j
(
json
::
value_t
::
object
);
CHECK
(
j
.
type
()
==
json
::
value_t
ype
::
object
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
object
);
// const object
// const object
const
json
j_const
=
j
;
const
json
j_const
=
j
;
...
@@ -403,7 +405,9 @@ TEST_CASE("object")
...
@@ -403,7 +405,9 @@ TEST_CASE("object")
// container members
// container members
CHECK
(
j
.
size
()
==
0
);
CHECK
(
j
.
size
()
==
0
);
CHECK
(
j
.
max_size
()
>
0
);
CHECK
(
j
.
empty
()
==
true
);
CHECK
(
j
.
empty
()
==
true
);
CHECK_NOTHROW
(
size_t
h
=
std
::
hash
<
json
>
()(
j
));
// implicit conversions
// implicit conversions
CHECK_THROWS_AS
(
json
::
array_t
v
=
j
,
std
::
logic_error
);
CHECK_THROWS_AS
(
json
::
array_t
v
=
j
,
std
::
logic_error
);
...
@@ -604,7 +608,7 @@ TEST_CASE("object")
...
@@ -604,7 +608,7 @@ TEST_CASE("object")
// implicit transformation into an object
// implicit transformation into an object
json
empty
;
json
empty
;
empty
[
"foo"
]
=
"bar"
;
empty
[
"foo"
]
=
"bar"
;
CHECK
(
empty
.
type
()
==
json
::
value_t
ype
::
object
);
CHECK
(
empty
.
type
()
==
json
::
value_t
::
object
);
CHECK
(
empty
[
"foo"
]
==
"bar"
);
CHECK
(
empty
[
"foo"
]
==
"bar"
);
// exceptions
// exceptions
...
@@ -649,8 +653,8 @@ TEST_CASE("object")
...
@@ -649,8 +653,8 @@ TEST_CASE("object")
CHECK
(
false
);
CHECK
(
false
);
}
}
CHECK
((
*
it
).
type
()
==
json
::
value_t
ype
::
number
);
CHECK
((
*
it
).
type
()
==
json
::
value_t
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
::
number
);
}
}
// range-based for
// range-based for
...
@@ -680,8 +684,8 @@ TEST_CASE("object")
...
@@ -680,8 +684,8 @@ TEST_CASE("object")
CHECK
(
false
);
CHECK
(
false
);
}
}
CHECK
((
*
it
).
type
()
==
json
::
value_t
ype
::
number
);
CHECK
((
*
it
).
type
()
==
json
::
value_t
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
::
number
);
}
}
// const_iterator using cbegin/cend
// const_iterator using cbegin/cend
...
@@ -705,8 +709,8 @@ TEST_CASE("object")
...
@@ -705,8 +709,8 @@ TEST_CASE("object")
CHECK
(
false
);
CHECK
(
false
);
}
}
CHECK
((
*
it
).
type
()
==
json
::
value_t
ype
::
number
);
CHECK
((
*
it
).
type
()
==
json
::
value_t
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
::
number
);
}
}
// const_iterator (on const object)
// const_iterator (on const object)
...
@@ -730,8 +734,8 @@ TEST_CASE("object")
...
@@ -730,8 +734,8 @@ TEST_CASE("object")
CHECK
(
false
);
CHECK
(
false
);
}
}
CHECK
((
*
it
).
type
()
==
json
::
value_t
ype
::
number
);
CHECK
((
*
it
).
type
()
==
json
::
value_t
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
::
number
);
}
}
// const_iterator using cbegin/cend (on const object)
// const_iterator using cbegin/cend (on const object)
...
@@ -755,8 +759,8 @@ TEST_CASE("object")
...
@@ -755,8 +759,8 @@ TEST_CASE("object")
CHECK
(
false
);
CHECK
(
false
);
}
}
CHECK
((
*
it
).
type
()
==
json
::
value_t
ype
::
number
);
CHECK
((
*
it
).
type
()
==
json
::
value_t
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
it
->
type
()
==
json
::
value_t
::
number
);
}
}
// range-based for (on const object)
// range-based for (on const object)
...
@@ -768,7 +772,7 @@ TEST_CASE("object")
...
@@ -768,7 +772,7 @@ TEST_CASE("object")
SECTION
(
"Iterators and empty objects"
)
SECTION
(
"Iterators and empty objects"
)
{
{
json
empty_object
(
json
::
value_t
ype
::
object
);
json
empty_object
(
json
::
value_t
::
object
);
for
(
json
::
iterator
it
=
empty_object
.
begin
();
it
!=
empty_object
.
end
();
++
it
)
{}
for
(
json
::
iterator
it
=
empty_object
.
begin
();
it
!=
empty_object
.
end
();
++
it
)
{}
for
(
json
::
const_iterator
it
=
empty_object
.
begin
();
it
!=
empty_object
.
end
();
++
it
)
{}
for
(
json
::
const_iterator
it
=
empty_object
.
begin
();
it
!=
empty_object
.
end
();
++
it
)
{}
for
(
json
::
const_iterator
it
=
empty_object
.
cbegin
();
it
!=
empty_object
.
cend
();
++
it
)
{}
for
(
json
::
const_iterator
it
=
empty_object
.
cbegin
();
it
!=
empty_object
.
cend
();
++
it
)
{}
...
@@ -806,22 +810,22 @@ TEST_CASE("object")
...
@@ -806,22 +810,22 @@ TEST_CASE("object")
{
{
std
::
map
<
std
::
string
,
int
>
c_map
{
{
"one"
,
1
},
{
"two"
,
2
},
{
"three"
,
3
}
};
std
::
map
<
std
::
string
,
int
>
c_map
{
{
"one"
,
1
},
{
"two"
,
2
},
{
"three"
,
3
}
};
json
j_map
(
c_map
);
json
j_map
(
c_map
);
CHECK
(
j_map
.
type
()
==
json
::
value_t
ype
::
object
);
CHECK
(
j_map
.
type
()
==
json
::
value_t
::
object
);
CHECK
(
j_map
.
size
()
==
3
);
CHECK
(
j_map
.
size
()
==
3
);
std
::
unordered_map
<
const
char
*
,
float
>
c_umap
{
{
"one"
,
1.2
},
{
"two"
,
2.3
},
{
"three"
,
3.4
}
};
std
::
unordered_map
<
const
char
*
,
float
>
c_umap
{
{
"one"
,
1.2
},
{
"two"
,
2.3
},
{
"three"
,
3.4
}
};
json
j_umap
(
c_umap
);
json
j_umap
(
c_umap
);
CHECK
(
j_umap
.
type
()
==
json
::
value_t
ype
::
object
);
CHECK
(
j_umap
.
type
()
==
json
::
value_t
::
object
);
CHECK
(
j_umap
.
size
()
==
3
);
CHECK
(
j_umap
.
size
()
==
3
);
std
::
multimap
<
std
::
string
,
bool
>
c_mmap
{
{
"one"
,
true
},
{
"two"
,
true
},
{
"three"
,
false
},
{
"three"
,
true
}
};
std
::
multimap
<
std
::
string
,
bool
>
c_mmap
{
{
"one"
,
true
},
{
"two"
,
true
},
{
"three"
,
false
},
{
"three"
,
true
}
};
json
j_mmap
(
c_mmap
);
json
j_mmap
(
c_mmap
);
CHECK
(
j_mmap
.
type
()
==
json
::
value_t
ype
::
object
);
CHECK
(
j_mmap
.
type
()
==
json
::
value_t
::
object
);
CHECK
(
j_mmap
.
size
()
==
3
);
CHECK
(
j_mmap
.
size
()
==
3
);
std
::
unordered_multimap
<
std
::
string
,
bool
>
c_ummap
{
{
"one"
,
true
},
{
"two"
,
true
},
{
"three"
,
false
},
{
"three"
,
true
}
};
std
::
unordered_multimap
<
std
::
string
,
bool
>
c_ummap
{
{
"one"
,
true
},
{
"two"
,
true
},
{
"three"
,
false
},
{
"three"
,
true
}
};
json
j_ummap
(
c_ummap
);
json
j_ummap
(
c_ummap
);
CHECK
(
j_ummap
.
type
()
==
json
::
value_t
ype
::
object
);
CHECK
(
j_ummap
.
type
()
==
json
::
value_t
::
object
);
CHECK
(
j_ummap
.
size
()
==
3
);
CHECK
(
j_ummap
.
size
()
==
3
);
}
}
}
}
...
@@ -832,7 +836,7 @@ TEST_CASE("null")
...
@@ -832,7 +836,7 @@ TEST_CASE("null")
{
{
// construction with given type
// construction with given type
json
j
;
json
j
;
CHECK
(
j
.
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
null
);
// string representation of default value
// string representation of default value
CHECK
(
j
.
dump
()
==
"null"
);
CHECK
(
j
.
dump
()
==
"null"
);
...
@@ -843,7 +847,9 @@ TEST_CASE("null")
...
@@ -843,7 +847,9 @@ TEST_CASE("null")
// container members
// container members
CHECK
(
j
.
size
()
==
0
);
CHECK
(
j
.
size
()
==
0
);
CHECK
(
j
.
max_size
()
==
0
);
CHECK
(
j
.
empty
()
==
true
);
CHECK
(
j
.
empty
()
==
true
);
CHECK_NOTHROW
(
size_t
h
=
std
::
hash
<
json
>
()(
j
));
// implicit conversions
// implicit conversions
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
...
@@ -878,7 +884,7 @@ TEST_CASE("null")
...
@@ -878,7 +884,7 @@ TEST_CASE("null")
SECTION
(
"Create from value"
)
SECTION
(
"Create from value"
)
{
{
json
j1
=
nullptr
;
json
j1
=
nullptr
;
CHECK
(
j1
.
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j1
.
type
()
==
json
::
value_t
::
null
);
}
}
SECTION
(
"Operators"
)
SECTION
(
"Operators"
)
...
@@ -911,8 +917,8 @@ TEST_CASE("string")
...
@@ -911,8 +917,8 @@ TEST_CASE("string")
SECTION
(
"Basics"
)
SECTION
(
"Basics"
)
{
{
// construction with given type
// construction with given type
json
j
(
json
::
value_t
ype
::
string
);
json
j
(
json
::
value_t
::
string
);
CHECK
(
j
.
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
string
);
// const object
// const object
const
json
j_const
=
j
;
const
json
j_const
=
j
;
...
@@ -926,7 +932,9 @@ TEST_CASE("string")
...
@@ -926,7 +932,9 @@ TEST_CASE("string")
// container members
// container members
CHECK
(
j
.
size
()
==
1
);
CHECK
(
j
.
size
()
==
1
);
CHECK
(
j
.
max_size
()
==
1
);
CHECK
(
j
.
empty
()
==
false
);
CHECK
(
j
.
empty
()
==
false
);
CHECK_NOTHROW
(
size_t
h
=
std
::
hash
<
json
>
()(
j
));
// implicit conversions
// implicit conversions
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
...
@@ -1022,8 +1030,8 @@ TEST_CASE("boolean")
...
@@ -1022,8 +1030,8 @@ TEST_CASE("boolean")
SECTION
(
"Basics"
)
SECTION
(
"Basics"
)
{
{
// construction with given type
// construction with given type
json
j
(
json
::
value_t
ype
::
boolean
);
json
j
(
json
::
value_t
::
boolean
);
CHECK
(
j
.
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
boolean
);
// const object
// const object
const
json
j_const
=
j
;
const
json
j_const
=
j
;
...
@@ -1037,7 +1045,9 @@ TEST_CASE("boolean")
...
@@ -1037,7 +1045,9 @@ TEST_CASE("boolean")
// container members
// container members
CHECK
(
j
.
size
()
==
1
);
CHECK
(
j
.
size
()
==
1
);
CHECK
(
j
.
max_size
()
==
1
);
CHECK
(
j
.
empty
()
==
false
);
CHECK
(
j
.
empty
()
==
false
);
CHECK_NOTHROW
(
size_t
h
=
std
::
hash
<
json
>
()(
j
));
// implicit conversions
// implicit conversions
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
...
@@ -1118,8 +1128,8 @@ TEST_CASE("number (int)")
...
@@ -1118,8 +1128,8 @@ TEST_CASE("number (int)")
SECTION
(
"Basics"
)
SECTION
(
"Basics"
)
{
{
// construction with given type
// construction with given type
json
j
(
json
::
value_t
ype
::
number
);
json
j
(
json
::
value_t
::
number
);
CHECK
(
j
.
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
number
);
// const object
// const object
const
json
j_const
=
j
;
const
json
j_const
=
j
;
...
@@ -1133,7 +1143,9 @@ TEST_CASE("number (int)")
...
@@ -1133,7 +1143,9 @@ TEST_CASE("number (int)")
// container members
// container members
CHECK
(
j
.
size
()
==
1
);
CHECK
(
j
.
size
()
==
1
);
CHECK
(
j
.
max_size
()
==
1
);
CHECK
(
j
.
empty
()
==
false
);
CHECK
(
j
.
empty
()
==
false
);
CHECK_NOTHROW
(
size_t
h
=
std
::
hash
<
json
>
()(
j
));
// implicit conversions
// implicit conversions
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
...
@@ -1229,8 +1241,8 @@ TEST_CASE("number (float)")
...
@@ -1229,8 +1241,8 @@ TEST_CASE("number (float)")
SECTION
(
"Basics"
)
SECTION
(
"Basics"
)
{
{
// construction with given type
// construction with given type
json
j
(
json
::
value_t
ype
::
number_float
);
json
j
(
json
::
value_t
::
number_float
);
CHECK
(
j
.
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j
.
type
()
==
json
::
value_t
::
number_float
);
// const object
// const object
const
json
j_const
=
j
;
const
json
j_const
=
j
;
...
@@ -1244,7 +1256,9 @@ TEST_CASE("number (float)")
...
@@ -1244,7 +1256,9 @@ TEST_CASE("number (float)")
// container members
// container members
CHECK
(
j
.
size
()
==
1
);
CHECK
(
j
.
size
()
==
1
);
CHECK
(
j
.
max_size
()
==
1
);
CHECK
(
j
.
empty
()
==
false
);
CHECK
(
j
.
empty
()
==
false
);
CHECK_NOTHROW
(
size_t
h
=
std
::
hash
<
json
>
()(
j
));
// implicit conversions
// implicit conversions
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
CHECK_NOTHROW
(
json
::
array_t
v
=
j
);
...
@@ -1388,35 +1402,35 @@ TEST_CASE("Iterators")
...
@@ -1388,35 +1402,35 @@ TEST_CASE("Iterators")
CHECK_THROWS_AS
(
*
j7_const
.
cend
(),
std
::
runtime_error
);
CHECK_THROWS_AS
(
*
j7_const
.
cend
(),
std
::
runtime_error
);
// operator ->
// operator ->
CHECK
(
j1
.
begin
()
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j1
.
begin
()
->
type
()
==
json
::
value_t
::
number
);
CHECK
(
j1
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j1
.
cbegin
()
->
type
()
==
json
::
value_t
::
number
);
CHECK
(
j2
.
begin
()
->
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j2
.
begin
()
->
type
()
==
json
::
value_t
::
string
);
CHECK
(
j2
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j2
.
cbegin
()
->
type
()
==
json
::
value_t
::
string
);
CHECK
(
j3
.
begin
()
->
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j3
.
begin
()
->
type
()
==
json
::
value_t
::
boolean
);
CHECK
(
j3
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j3
.
cbegin
()
->
type
()
==
json
::
value_t
::
boolean
);
CHECK
(
j4
.
begin
()
->
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j4
.
begin
()
->
type
()
==
json
::
value_t
::
null
);
CHECK
(
j4
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j4
.
cbegin
()
->
type
()
==
json
::
value_t
::
null
);
CHECK
(
j5
.
begin
()
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j5
.
begin
()
->
type
()
==
json
::
value_t
::
number
);
CHECK
(
j5
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j5
.
cbegin
()
->
type
()
==
json
::
value_t
::
number
);
CHECK
(
j6
.
begin
()
->
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j6
.
begin
()
->
type
()
==
json
::
value_t
::
number_float
);
CHECK
(
j6
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j6
.
cbegin
()
->
type
()
==
json
::
value_t
::
number_float
);
CHECK
(
j7
.
begin
()
->
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j7
.
begin
()
->
type
()
==
json
::
value_t
::
string
);
CHECK
(
j7
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j7
.
cbegin
()
->
type
()
==
json
::
value_t
::
string
);
CHECK
(
j1_const
.
begin
()
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j1_const
.
begin
()
->
type
()
==
json
::
value_t
::
number
);
CHECK
(
j1_const
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j1_const
.
cbegin
()
->
type
()
==
json
::
value_t
::
number
);
CHECK
(
j2_const
.
begin
()
->
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j2_const
.
begin
()
->
type
()
==
json
::
value_t
::
string
);
CHECK
(
j2_const
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j2_const
.
cbegin
()
->
type
()
==
json
::
value_t
::
string
);
CHECK
(
j3_const
.
begin
()
->
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j3_const
.
begin
()
->
type
()
==
json
::
value_t
::
boolean
);
CHECK
(
j3_const
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j3_const
.
cbegin
()
->
type
()
==
json
::
value_t
::
boolean
);
CHECK
(
j4_const
.
begin
()
->
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j4_const
.
begin
()
->
type
()
==
json
::
value_t
::
null
);
CHECK
(
j4_const
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j4_const
.
cbegin
()
->
type
()
==
json
::
value_t
::
null
);
CHECK
(
j5_const
.
begin
()
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j5_const
.
begin
()
->
type
()
==
json
::
value_t
::
number
);
CHECK
(
j5_const
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j5_const
.
cbegin
()
->
type
()
==
json
::
value_t
::
number
);
CHECK
(
j6_const
.
begin
()
->
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j6_const
.
begin
()
->
type
()
==
json
::
value_t
::
number_float
);
CHECK
(
j6_const
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j6_const
.
cbegin
()
->
type
()
==
json
::
value_t
::
number_float
);
CHECK
(
j7_const
.
begin
()
->
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j7_const
.
begin
()
->
type
()
==
json
::
value_t
::
string
);
CHECK
(
j7_const
.
cbegin
()
->
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j7_const
.
cbegin
()
->
type
()
==
json
::
value_t
::
string
);
CHECK_THROWS_AS
(
j1
.
end
()
->
type
(),
std
::
runtime_error
);
CHECK_THROWS_AS
(
j1
.
end
()
->
type
(),
std
::
runtime_error
);
CHECK_THROWS_AS
(
j1
.
cend
()
->
type
(),
std
::
runtime_error
);
CHECK_THROWS_AS
(
j1
.
cend
()
->
type
(),
std
::
runtime_error
);
...
@@ -1449,35 +1463,35 @@ TEST_CASE("Iterators")
...
@@ -1449,35 +1463,35 @@ TEST_CASE("Iterators")
CHECK_THROWS_AS
(
j7_const
.
cend
()
->
type
(),
std
::
runtime_error
);
CHECK_THROWS_AS
(
j7_const
.
cend
()
->
type
(),
std
::
runtime_error
);
// value
// value
CHECK
(
j1
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j1
.
begin
().
value
().
type
()
==
json
::
value_t
::
number
);
CHECK
(
j1
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j1
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
number
);
CHECK
(
j2
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j2
.
begin
().
value
().
type
()
==
json
::
value_t
::
string
);
CHECK
(
j2
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j2
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
string
);
CHECK
(
j3
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j3
.
begin
().
value
().
type
()
==
json
::
value_t
::
boolean
);
CHECK
(
j3
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j3
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
boolean
);
CHECK
(
j4
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j4
.
begin
().
value
().
type
()
==
json
::
value_t
::
null
);
CHECK
(
j4
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j4
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
null
);
CHECK
(
j5
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j5
.
begin
().
value
().
type
()
==
json
::
value_t
::
number
);
CHECK
(
j5
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j5
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
number
);
CHECK
(
j6
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j6
.
begin
().
value
().
type
()
==
json
::
value_t
::
number_float
);
CHECK
(
j6
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j6
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
number_float
);
CHECK
(
j7
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j7
.
begin
().
value
().
type
()
==
json
::
value_t
::
string
);
CHECK
(
j7
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j7
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
string
);
CHECK
(
j1_const
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j1_const
.
begin
().
value
().
type
()
==
json
::
value_t
::
number
);
CHECK
(
j1_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j1_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
number
);
CHECK
(
j2_const
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j2_const
.
begin
().
value
().
type
()
==
json
::
value_t
::
string
);
CHECK
(
j2_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j2_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
string
);
CHECK
(
j3_const
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j3_const
.
begin
().
value
().
type
()
==
json
::
value_t
::
boolean
);
CHECK
(
j3_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
boolean
);
CHECK
(
j3_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
boolean
);
CHECK
(
j4_const
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j4_const
.
begin
().
value
().
type
()
==
json
::
value_t
::
null
);
CHECK
(
j4_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
null
);
CHECK
(
j4_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
null
);
CHECK
(
j5_const
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j5_const
.
begin
().
value
().
type
()
==
json
::
value_t
::
number
);
CHECK
(
j5_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
number
);
CHECK
(
j5_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
number
);
CHECK
(
j6_const
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j6_const
.
begin
().
value
().
type
()
==
json
::
value_t
::
number_float
);
CHECK
(
j6_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
number_float
);
CHECK
(
j6_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
number_float
);
CHECK
(
j7_const
.
begin
().
value
().
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j7_const
.
begin
().
value
().
type
()
==
json
::
value_t
::
string
);
CHECK
(
j7_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
ype
::
string
);
CHECK
(
j7_const
.
cbegin
().
value
().
type
()
==
json
::
value_t
::
string
);
CHECK_THROWS_AS
(
j1
.
end
().
value
(),
std
::
out_of_range
);
CHECK_THROWS_AS
(
j1
.
end
().
value
(),
std
::
out_of_range
);
CHECK_THROWS_AS
(
j1
.
cend
().
value
(),
std
::
out_of_range
);
CHECK_THROWS_AS
(
j1
.
cend
().
value
(),
std
::
out_of_range
);
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment