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
Jan 21, 2015
by
Niels
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
+ more adjustments toward a real container
parent
3c780f0f
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
...
...
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
();
...
...
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
();
...
...
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
());
}
};
}
}
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
);
...
...
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