Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
e6aa7003
Unverified
Commit
e6aa7003
authored
Jul 26, 2017
by
Niels Lohmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
🔨
cleanup
parent
4414f94c
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
337 additions
and
426 deletions
+337
-426
json.hpp
src/json.hpp
+337
-426
No files found.
src/json.hpp
View file @
e6aa7003
...
@@ -119,15 +119,15 @@ template<typename = void, typename = void>
...
@@ -119,15 +119,15 @@ template<typename = void, typename = void>
struct
adl_serializer
;
struct
adl_serializer
;
// forward declaration of basic_json (required to split the class)
// forward declaration of basic_json (required to split the class)
template
<
template
<
typename
U
,
typename
V
,
typename
...
Args
>
class
ObjectType
=
template
<
template
<
typename
U
,
typename
V
,
typename
...
Args
>
class
ObjectType
=
std
::
map
,
std
::
map
,
template
<
typename
U
,
typename
...
Args
>
class
ArrayType
=
std
::
vector
,
template
<
typename
U
,
typename
...
Args
>
class
ArrayType
=
std
::
vector
,
class
StringType
=
std
::
string
,
class
BooleanType
=
bool
,
class
StringType
=
std
::
string
,
class
BooleanType
=
bool
,
class
NumberIntegerType
=
std
::
int64_t
,
class
NumberIntegerType
=
std
::
int64_t
,
class
NumberUnsignedType
=
std
::
uint64_t
,
class
NumberUnsignedType
=
std
::
uint64_t
,
class
NumberFloatType
=
double
,
class
NumberFloatType
=
double
,
template
<
typename
U
>
class
AllocatorType
=
std
::
allocator
,
template
<
typename
U
>
class
AllocatorType
=
std
::
allocator
,
template
<
typename
T
,
typename
SFINAE
=
void
>
class
JSONSerializer
=
template
<
typename
T
,
typename
SFINAE
=
void
>
class
JSONSerializer
=
adl_serializer
>
adl_serializer
>
class
basic_json
;
class
basic_json
;
...
@@ -135,12 +135,12 @@ class basic_json;
...
@@ -135,12 +135,12 @@ class basic_json;
// This is only temporary and will be removed in 3.0
// This is only temporary and will be removed in 3.0
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
template
<template
<typename, typename, typename...> class ObjectType, \
template
<template
<typename, typename, typename...> class ObjectType, \
template
<typename, typename...> class ArrayType, \
template
<typename, typename...> class ArrayType, \
class StringType, class BooleanType, class NumberIntegerType, \
class StringType, class BooleanType, class NumberIntegerType, \
class NumberUnsignedType, class NumberFloatType, \
class NumberUnsignedType, class NumberFloatType, \
template
<typename> class AllocatorType, \
template
<typename> class AllocatorType, \
template
<typename, typename = void> class JSONSerializer>
template
<typename, typename = void> class JSONSerializer>
#define NLOHMANN_BASIC_JSON_TPL \
#define NLOHMANN_BASIC_JSON_TPL \
basic_json<ObjectType, ArrayType, StringType, BooleanType, \
basic_json<ObjectType, ArrayType, StringType, BooleanType, \
...
@@ -188,8 +188,7 @@ class exception : public std::exception
...
@@ -188,8 +188,7 @@ class exception : public std::exception
const
int
id
;
const
int
id
;
protected
:
protected
:
exception
(
int
id_
,
const
char
*
what_arg
)
exception
(
int
id_
,
const
char
*
what_arg
)
:
id
(
id_
),
m
(
what_arg
)
{}
:
id
(
id_
),
m
(
what_arg
)
{}
static
std
::
string
name
(
const
std
::
string
&
ename
,
int
id
)
static
std
::
string
name
(
const
std
::
string
&
ename
,
int
id
)
{
{
...
@@ -341,8 +340,7 @@ class type_error : public exception
...
@@ -341,8 +340,7 @@ class type_error : public exception
}
}
private
:
private
:
type_error
(
int
id_
,
const
char
*
what_arg
)
type_error
(
int
id_
,
const
char
*
what_arg
)
:
exception
(
id_
,
what_arg
)
{}
:
exception
(
id_
,
what_arg
)
{}
};
};
/*!
/*!
...
@@ -371,8 +369,7 @@ class out_of_range : public exception
...
@@ -371,8 +369,7 @@ class out_of_range : public exception
}
}
private
:
private
:
out_of_range
(
int
id_
,
const
char
*
what_arg
)
out_of_range
(
int
id_
,
const
char
*
what_arg
)
:
exception
(
id_
,
what_arg
)
{}
:
exception
(
id_
,
what_arg
)
{}
};
};
/*!
/*!
...
@@ -397,8 +394,7 @@ class other_error : public exception
...
@@ -397,8 +394,7 @@ class other_error : public exception
}
}
private
:
private
:
other_error
(
int
id_
,
const
char
*
what_arg
)
other_error
(
int
id_
,
const
char
*
what_arg
)
:
exception
(
id_
,
what_arg
)
{}
:
exception
(
id_
,
what_arg
)
{}
};
};
...
@@ -482,9 +478,10 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
...
@@ -482,9 +478,10 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
// helpers //
// helpers //
/////////////
/////////////
template
<
typename
>
struct
is_basic_json
:
std
::
false_type
{};
template
<
typename
>
struct
is_basic_json
:
std
::
false_type
{};
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct
is_basic_json
<
NLOHMANN_BASIC_JSON_TPL
>
:
std
::
true_type
{};
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct
is_basic_json
<
NLOHMANN_BASIC_JSON_TPL
>
:
std
::
true_type
{};
// alias templates to reduce boilerplate
// alias templates to reduce boilerplate
template
<
bool
B
,
typename
T
=
void
>
template
<
bool
B
,
typename
T
=
void
>
...
@@ -495,7 +492,7 @@ using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::typ
...
@@ -495,7 +492,7 @@ using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::typ
// implementation of C++14 index_sequence and affiliates
// implementation of C++14 index_sequence and affiliates
// source: https://stackoverflow.com/a/32223343
// source: https://stackoverflow.com/a/32223343
template
<
std
::
size_t
...
Ints
>
template
<
std
::
size_t
...
Ints
>
struct
index_sequence
struct
index_sequence
{
{
using
type
=
index_sequence
;
using
type
=
index_sequence
;
...
@@ -506,15 +503,15 @@ struct index_sequence
...
@@ -506,15 +503,15 @@ struct index_sequence
}
}
};
};
template
<
class
Sequence1
,
class
Sequence2
>
template
<
class
Sequence1
,
class
Sequence2
>
struct
merge_and_renumber
;
struct
merge_and_renumber
;
template
<
std
::
size_t
...
I1
,
std
::
size_t
...
I2
>
template
<
std
::
size_t
...
I1
,
std
::
size_t
...
I2
>
struct
merge_and_renumber
<
index_sequence
<
I1
...
>
,
index_sequence
<
I2
...
>>
struct
merge_and_renumber
<
index_sequence
<
I1
...
>
,
index_sequence
<
I2
...
>>
:
index_sequence
<
I1
...,
(
sizeof
...(
I1
)
+
I2
)...
>
:
index_sequence
<
I1
...,
(
sizeof
...(
I1
)
+
I2
)...
>
{
};
{
};
template
<
std
::
size_t
N
>
template
<
std
::
size_t
N
>
struct
make_index_sequence
struct
make_index_sequence
:
merge_and_renumber
<
typename
make_index_sequence
<
N
/
2
>::
type
,
:
merge_and_renumber
<
typename
make_index_sequence
<
N
/
2
>::
type
,
typename
make_index_sequence
<
N
-
N
/
2
>::
type
>
typename
make_index_sequence
<
N
-
N
/
2
>::
type
>
...
@@ -722,10 +719,8 @@ template<class RealType, class CompatibleObjectType>
...
@@ -722,10 +719,8 @@ template<class RealType, class CompatibleObjectType>
struct
is_compatible_object_type_impl
<
true
,
RealType
,
CompatibleObjectType
>
struct
is_compatible_object_type_impl
<
true
,
RealType
,
CompatibleObjectType
>
{
{
static
constexpr
auto
value
=
static
constexpr
auto
value
=
std
::
is_constructible
<
typename
RealType
::
key_type
,
std
::
is_constructible
<
typename
RealType
::
key_type
,
typename
CompatibleObjectType
::
key_type
>::
value
and
typename
CompatibleObjectType
::
key_type
>::
value
and
std
::
is_constructible
<
typename
RealType
::
mapped_type
,
typename
CompatibleObjectType
::
mapped_type
>::
value
;
std
::
is_constructible
<
typename
RealType
::
mapped_type
,
typename
CompatibleObjectType
::
mapped_type
>::
value
;
};
};
template
<
class
BasicJsonType
,
class
CompatibleObjectType
>
template
<
class
BasicJsonType
,
class
CompatibleObjectType
>
...
@@ -772,8 +767,7 @@ struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIn
...
@@ -772,8 +767,7 @@ struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIn
using
CompatibleLimits
=
std
::
numeric_limits
<
CompatibleNumberIntegerType
>
;
using
CompatibleLimits
=
std
::
numeric_limits
<
CompatibleNumberIntegerType
>
;
static
constexpr
auto
value
=
static
constexpr
auto
value
=
std
::
is_constructible
<
RealIntegerType
,
std
::
is_constructible
<
RealIntegerType
,
CompatibleNumberIntegerType
>::
value
and
CompatibleNumberIntegerType
>::
value
and
CompatibleLimits
::
is_integer
and
CompatibleLimits
::
is_integer
and
RealLimits
::
is_signed
==
CompatibleLimits
::
is_signed
;
RealLimits
::
is_signed
==
CompatibleLimits
::
is_signed
;
};
};
...
@@ -917,7 +911,7 @@ void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
...
@@ -917,7 +911,7 @@ void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
external_constructor
<
value_t
::
object
>::
construct
(
j
,
arr
);
external_constructor
<
value_t
::
object
>::
construct
(
j
,
arr
);
}
}
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
N
,
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
N
,
enable_if_t
<
not
std
::
is_constructible
<
enable_if_t
<
not
std
::
is_constructible
<
typename
BasicJsonType
::
string_t
,
T
(
&
)[
N
]
>::
value
,
typename
BasicJsonType
::
string_t
,
T
(
&
)[
N
]
>::
value
,
int
>
=
0
>
int
>
=
0
>
...
@@ -926,19 +920,19 @@ void to_json(BasicJsonType& j, T (&arr)[N])
...
@@ -926,19 +920,19 @@ void to_json(BasicJsonType& j, T (&arr)[N])
external_constructor
<
value_t
::
array
>::
construct
(
j
,
arr
);
external_constructor
<
value_t
::
array
>::
construct
(
j
,
arr
);
}
}
template
<
typename
BasicJsonType
,
typename
...
Args
>
template
<
typename
BasicJsonType
,
typename
...
Args
>
void
to_json
(
BasicJsonType
&
j
,
const
std
::
pair
<
Args
...
>&
p
)
void
to_json
(
BasicJsonType
&
j
,
const
std
::
pair
<
Args
...
>&
p
)
{
{
j
=
{
p
.
first
,
p
.
second
};
j
=
{
p
.
first
,
p
.
second
};
}
}
template
<
typename
BasicJsonType
,
typename
Tuple
,
std
::
size_t
...
Idx
>
template
<
typename
BasicJsonType
,
typename
Tuple
,
std
::
size_t
...
Idx
>
void
to_json_tuple_impl
(
BasicJsonType
&
j
,
const
Tuple
&
t
,
index_sequence
<
Idx
...
>
)
void
to_json_tuple_impl
(
BasicJsonType
&
j
,
const
Tuple
&
t
,
index_sequence
<
Idx
...
>
)
{
{
j
=
{
std
::
get
<
Idx
>
(
t
)...};
j
=
{
std
::
get
<
Idx
>
(
t
)...};
}
}
template
<
typename
BasicJsonType
,
typename
...
Args
>
template
<
typename
BasicJsonType
,
typename
...
Args
>
void
to_json
(
BasicJsonType
&
j
,
const
std
::
tuple
<
Args
...
>&
t
)
void
to_json
(
BasicJsonType
&
j
,
const
std
::
tuple
<
Args
...
>&
t
)
{
{
to_json_tuple_impl
(
j
,
t
,
index_sequence_for
<
Args
...
>
{});
to_json_tuple_impl
(
j
,
t
,
index_sequence_for
<
Args
...
>
{});
...
@@ -960,25 +954,22 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
...
@@ -960,25 +954,22 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
{
{
case
value_t
:
:
number_unsigned
:
case
value_t
:
:
number_unsigned
:
{
{
val
=
static_cast
<
ArithmeticType
>
(
val
=
static_cast
<
ArithmeticType
>
(
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
number_unsigned_t
*>
());
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
number_unsigned_t
*>
());
break
;
break
;
}
}
case
value_t
:
:
number_integer
:
case
value_t
:
:
number_integer
:
{
{
val
=
static_cast
<
ArithmeticType
>
(
val
=
static_cast
<
ArithmeticType
>
(
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
number_integer_t
*>
());
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
number_integer_t
*>
());
break
;
break
;
}
}
case
value_t
:
:
number_float
:
case
value_t
:
:
number_float
:
{
{
val
=
static_cast
<
ArithmeticType
>
(
val
=
static_cast
<
ArithmeticType
>
(
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
number_float_t
*>
());
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
number_float_t
*>
());
break
;
break
;
}
}
default
:
default
:
{
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be number, but is "
+
j
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be number, but is "
+
std
::
string
(
j
.
type_name
()
)));
}
}
}
}
}
}
...
@@ -986,9 +977,9 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
...
@@ -986,9 +977,9 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
boolean_t
&
b
)
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
boolean_t
&
b
)
{
{
if
(
not
j
.
is_boolean
(
))
if
(
JSON_UNLIKELY
(
not
j
.
is_boolean
()
))
{
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be boolean, but is "
+
j
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be boolean, but is "
+
std
::
string
(
j
.
type_name
()
)));
}
}
b
=
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
boolean_t
*>
();
b
=
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
boolean_t
*>
();
}
}
...
@@ -996,9 +987,9 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
...
@@ -996,9 +987,9 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
string_t
&
s
)
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
string_t
&
s
)
{
{
if
(
not
j
.
is_string
(
))
if
(
JSON_UNLIKELY
(
not
j
.
is_string
()
))
{
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be string, but is "
+
j
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be string, but is "
+
std
::
string
(
j
.
type_name
()
)));
}
}
s
=
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
string_t
*>
();
s
=
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
string_t
*>
();
}
}
...
@@ -1033,9 +1024,9 @@ void from_json(const BasicJsonType& j, EnumType& e)
...
@@ -1033,9 +1024,9 @@ void from_json(const BasicJsonType& j, EnumType& e)
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
array_t
&
arr
)
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
array_t
&
arr
)
{
{
if
(
not
j
.
is_array
(
))
if
(
JSON_UNLIKELY
(
not
j
.
is_array
()
))
{
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
j
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
std
::
string
(
j
.
type_name
()
)));
}
}
arr
=
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
array_t
*>
();
arr
=
*
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
array_t
*>
();
}
}
...
@@ -1045,9 +1036,9 @@ template<typename BasicJsonType, typename T, typename Allocator,
...
@@ -1045,9 +1036,9 @@ template<typename BasicJsonType, typename T, typename Allocator,
enable_if_t
<
std
::
is_convertible
<
BasicJsonType
,
T
>::
value
,
int
>
=
0
>
enable_if_t
<
std
::
is_convertible
<
BasicJsonType
,
T
>::
value
,
int
>
=
0
>
void
from_json
(
const
BasicJsonType
&
j
,
std
::
forward_list
<
T
,
Allocator
>&
l
)
void
from_json
(
const
BasicJsonType
&
j
,
std
::
forward_list
<
T
,
Allocator
>&
l
)
{
{
if
(
not
j
.
is_array
(
))
if
(
JSON_UNLIKELY
(
not
j
.
is_array
()
))
{
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
j
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
std
::
string
(
j
.
type_name
()
)));
}
}
for
(
auto
it
=
j
.
rbegin
(),
end
=
j
.
rend
();
it
!=
end
;
++
it
)
for
(
auto
it
=
j
.
rbegin
(),
end
=
j
.
rend
();
it
!=
end
;
++
it
)
...
@@ -1059,7 +1050,6 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
...
@@ -1059,7 +1050,6 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
template
<
typename
BasicJsonType
,
typename
CompatibleArrayType
>
template
<
typename
BasicJsonType
,
typename
CompatibleArrayType
>
void
from_json_array_impl
(
const
BasicJsonType
&
j
,
CompatibleArrayType
&
arr
,
priority_tag
<
0
>
/*unused*/
)
void
from_json_array_impl
(
const
BasicJsonType
&
j
,
CompatibleArrayType
&
arr
,
priority_tag
<
0
>
/*unused*/
)
{
{
using
std
::
begin
;
using
std
::
end
;
using
std
::
end
;
std
::
transform
(
j
.
begin
(),
j
.
end
(),
std
::
transform
(
j
.
begin
(),
j
.
end
(),
...
@@ -1077,7 +1067,6 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
...
@@ -1077,7 +1067,6 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
arr
.
reserve
(
std
::
declval
<
typename
CompatibleArrayType
::
size_type
>
()),
arr
.
reserve
(
std
::
declval
<
typename
CompatibleArrayType
::
size_type
>
()),
void
())
void
())
{
{
using
std
::
begin
;
using
std
::
end
;
using
std
::
end
;
arr
.
reserve
(
j
.
size
());
arr
.
reserve
(
j
.
size
());
...
@@ -1090,7 +1079,7 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
...
@@ -1090,7 +1079,7 @@ auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, prio
});
});
}
}
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
N
>
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
N
>
void
from_json_array_impl
(
const
BasicJsonType
&
j
,
std
::
array
<
T
,
N
>&
arr
,
priority_tag
<
2
>
/*unused*/
)
void
from_json_array_impl
(
const
BasicJsonType
&
j
,
std
::
array
<
T
,
N
>&
arr
,
priority_tag
<
2
>
/*unused*/
)
{
{
for
(
std
::
size_t
i
=
0
;
i
<
N
;
++
i
)
for
(
std
::
size_t
i
=
0
;
i
<
N
;
++
i
)
...
@@ -1105,9 +1094,9 @@ template<typename BasicJsonType, typename CompatibleArrayType,
...
@@ -1105,9 +1094,9 @@ template<typename BasicJsonType, typename CompatibleArrayType,
not
std
::
is_same
<
typename
BasicJsonType
::
array_t
,
CompatibleArrayType
>::
value
,
int
>
=
0
>
not
std
::
is_same
<
typename
BasicJsonType
::
array_t
,
CompatibleArrayType
>::
value
,
int
>
=
0
>
void
from_json
(
const
BasicJsonType
&
j
,
CompatibleArrayType
&
arr
)
void
from_json
(
const
BasicJsonType
&
j
,
CompatibleArrayType
&
arr
)
{
{
if
(
not
j
.
is_array
(
))
if
(
JSON_UNLIKELY
(
not
j
.
is_array
()
))
{
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
j
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
std
::
string
(
j
.
type_name
()
)));
}
}
from_json_array_impl
(
j
,
arr
,
priority_tag
<
2
>
{});
from_json_array_impl
(
j
,
arr
,
priority_tag
<
2
>
{});
...
@@ -1117,14 +1106,12 @@ template<typename BasicJsonType, typename CompatibleObjectType,
...
@@ -1117,14 +1106,12 @@ template<typename BasicJsonType, typename CompatibleObjectType,
enable_if_t
<
is_compatible_object_type
<
BasicJsonType
,
CompatibleObjectType
>::
value
,
int
>
=
0
>
enable_if_t
<
is_compatible_object_type
<
BasicJsonType
,
CompatibleObjectType
>::
value
,
int
>
=
0
>
void
from_json
(
const
BasicJsonType
&
j
,
CompatibleObjectType
&
obj
)
void
from_json
(
const
BasicJsonType
&
j
,
CompatibleObjectType
&
obj
)
{
{
if
(
not
j
.
is_object
(
))
if
(
JSON_UNLIKELY
(
not
j
.
is_object
()
))
{
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be object, but is "
+
j
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be object, but is "
+
std
::
string
(
j
.
type_name
()
)));
}
}
auto
inner_object
=
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
object_t
*>
();
auto
inner_object
=
j
.
template
get_ptr
<
const
typename
BasicJsonType
::
object_t
*>
();
using
std
::
begin
;
using
std
::
end
;
using
value_type
=
typename
CompatibleObjectType
::
value_type
;
using
value_type
=
typename
CompatibleObjectType
::
value_type
;
std
::
transform
(
std
::
transform
(
inner_object
->
begin
(),
inner_object
->
end
(),
inner_object
->
begin
(),
inner_object
->
end
(),
...
@@ -1132,8 +1119,7 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
...
@@ -1132,8 +1119,7 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
[](
typename
BasicJsonType
::
object_t
::
value_type
const
&
p
)
[](
typename
BasicJsonType
::
object_t
::
value_type
const
&
p
)
{
{
return
value_type
(
return
value_type
(
p
.
first
,
p
.
first
,
p
.
second
p
.
second
.
template
get
<
typename
CompatibleObjectType
::
mapped_type
>
());
.
template
get
<
typename
CompatibleObjectType
::
mapped_type
>
());
});
});
}
}
...
@@ -1176,24 +1162,24 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
...
@@ -1176,24 +1162,24 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
}
}
default
:
default
:
{
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be number, but is "
+
j
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be number, but is "
+
std
::
string
(
j
.
type_name
()
)));
}
}
}
}
}
}
template
<
typename
BasicJsonType
,
typename
...
Args
>
template
<
typename
BasicJsonType
,
typename
...
Args
>
void
from_json
(
const
BasicJsonType
&
j
,
std
::
pair
<
Args
...
>&
p
)
void
from_json
(
const
BasicJsonType
&
j
,
std
::
pair
<
Args
...
>&
p
)
{
{
p
=
{
j
.
at
(
0
),
j
.
at
(
1
)};
p
=
{
j
.
at
(
0
),
j
.
at
(
1
)};
}
}
template
<
typename
BasicJsonType
,
typename
Tuple
,
std
::
size_t
...
Idx
>
template
<
typename
BasicJsonType
,
typename
Tuple
,
std
::
size_t
...
Idx
>
void
from_json_tuple_impl
(
const
BasicJsonType
&
j
,
Tuple
&
t
,
index_sequence
<
Idx
...
>
)
void
from_json_tuple_impl
(
const
BasicJsonType
&
j
,
Tuple
&
t
,
index_sequence
<
Idx
...
>
)
{
{
t
=
std
::
make_tuple
(
j
.
at
(
Idx
)...);
t
=
std
::
make_tuple
(
j
.
at
(
Idx
)...);
}
}
template
<
typename
BasicJsonType
,
typename
...
Args
>
template
<
typename
BasicJsonType
,
typename
...
Args
>
void
from_json
(
const
BasicJsonType
&
j
,
std
::
tuple
<
Args
...
>&
t
)
void
from_json
(
const
BasicJsonType
&
j
,
std
::
tuple
<
Args
...
>&
t
)
{
{
from_json_tuple_impl
(
j
,
t
,
index_sequence_for
<
Args
...
>
{});
from_json_tuple_impl
(
j
,
t
,
index_sequence_for
<
Args
...
>
{});
...
@@ -1299,9 +1285,9 @@ class cached_input_stream_adapter : public input_adapter_protocol
...
@@ -1299,9 +1285,9 @@ class cached_input_stream_adapter : public input_adapter_protocol
{
{
// clear stream flags
// clear stream flags
is
.
clear
();
is
.
clear
();
// We initially read a lot of characters into the buffer, and we may
not
// We initially read a lot of characters into the buffer, and we may
//
have processed all of them. Therefore, we need to "rewind" the stream
//
not have processed all of them. Therefore, we need to "rewind" the
// after the last processed char.
//
stream
after the last processed char.
is
.
seekg
(
start_position
);
is
.
seekg
(
start_position
);
is
.
ignore
(
static_cast
<
std
::
streamsize
>
(
processed_chars
));
is
.
ignore
(
static_cast
<
std
::
streamsize
>
(
processed_chars
));
// clear stream flags
// clear stream flags
...
@@ -1443,7 +1429,7 @@ class input_adapter
...
@@ -1443,7 +1429,7 @@ class input_adapter
:
ia
(
std
::
make_shared
<
cached_input_stream_adapter
<
16384
>>
(
i
))
{}
:
ia
(
std
::
make_shared
<
cached_input_stream_adapter
<
16384
>>
(
i
))
{}
/// input adapter for buffer
/// input adapter for buffer
template
<
typename
CharT
,
template
<
typename
CharT
,
typename
std
::
enable_if
<
typename
std
::
enable_if
<
std
::
is_pointer
<
CharT
>::
value
and
std
::
is_pointer
<
CharT
>::
value
and
std
::
is_integral
<
std
::
is_integral
<
...
@@ -1456,7 +1442,7 @@ class input_adapter
...
@@ -1456,7 +1442,7 @@ class input_adapter
// derived support
// derived support
/// input adapter for string literal
/// input adapter for string literal
template
<
typename
CharT
,
template
<
typename
CharT
,
typename
std
::
enable_if
<
typename
std
::
enable_if
<
std
::
is_pointer
<
CharT
>::
value
and
std
::
is_pointer
<
CharT
>::
value
and
std
::
is_integral
<
std
::
is_integral
<
...
@@ -1468,7 +1454,7 @@ class input_adapter
...
@@ -1468,7 +1454,7 @@ class input_adapter
std
::
strlen
(
reinterpret_cast
<
const
char
*>
(
b
)))
{}
std
::
strlen
(
reinterpret_cast
<
const
char
*>
(
b
)))
{}
/// input adapter for iterator range with contiguous storage
/// input adapter for iterator range with contiguous storage
template
<
class
IteratorType
,
template
<
class
IteratorType
,
typename
std
::
enable_if
<
typename
std
::
enable_if
<
std
::
is_same
<
typename
std
::
iterator_traits
<
std
::
is_same
<
typename
std
::
iterator_traits
<
IteratorType
>::
iterator_category
,
IteratorType
>::
iterator_category
,
...
@@ -1505,7 +1491,7 @@ class input_adapter
...
@@ -1505,7 +1491,7 @@ class input_adapter
}
}
/// input adapter for array
/// input adapter for array
template
<
class
T
,
std
::
size_t
N
>
template
<
class
T
,
std
::
size_t
N
>
input_adapter
(
T
(
&
array
)[
N
])
input_adapter
(
T
(
&
array
)[
N
])
:
input_adapter
(
std
::
begin
(
array
),
std
::
end
(
array
))
{}
:
input_adapter
(
std
::
begin
(
array
),
std
::
end
(
array
))
{}
...
@@ -1541,7 +1527,7 @@ class input_adapter
...
@@ -1541,7 +1527,7 @@ class input_adapter
This class organizes the lexical analysis during JSON deserialization.
This class organizes the lexical analysis during JSON deserialization.
*/
*/
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
class
lexer
class
lexer
{
{
using
number_integer_t
=
typename
BasicJsonType
::
number_integer_t
;
using
number_integer_t
=
typename
BasicJsonType
::
number_integer_t
;
...
@@ -1557,12 +1543,9 @@ class lexer
...
@@ -1557,12 +1543,9 @@ class lexer
literal_false
,
///< the `false` literal
literal_false
,
///< the `false` literal
literal_null
,
///< the `null` literal
literal_null
,
///< the `null` literal
value_string
,
///< a string -- use get_string() for actual value
value_string
,
///< a string -- use get_string() for actual value
value_unsigned
,
///< an unsigned integer -- use get_number_unsigned() for
value_unsigned
,
///< an unsigned integer -- use get_number_unsigned() for actual value
///actual value
value_integer
,
///< a signed integer -- use get_number_integer() for actual value
value_integer
,
///< a signed integer -- use get_number_integer() for actual
value_float
,
///< an floating point number -- use get_number_float() for actual value
///value
value_float
,
///< an floating point number -- use get_number_float() for
///actual value
begin_array
,
///< the character for array begin `[`
begin_array
,
///< the character for array begin `[`
begin_object
,
///< the character for object begin `{`
begin_object
,
///< the character for object begin `{`
end_array
,
///< the character for array end `]`
end_array
,
///< the character for array end `]`
...
@@ -1571,8 +1554,7 @@ class lexer
...
@@ -1571,8 +1554,7 @@ class lexer
value_separator
,
///< the value separator `,`
value_separator
,
///< the value separator `,`
parse_error
,
///< indicating a parse error
parse_error
,
///< indicating a parse error
end_of_input
,
///< indicating the end of the input buffer
end_of_input
,
///< indicating the end of the input buffer
literal_or_value
///< a literal or the begin of a value (only for
literal_or_value
///< a literal or the begin of a value (only for diagnostics)
///diagnostics)
};
};
/// return name of values of type token_type (only used for errors)
/// return name of values of type token_type (only used for errors)
...
@@ -1647,8 +1629,7 @@ class lexer
...
@@ -1647,8 +1629,7 @@ class lexer
/*!
/*!
@brief get codepoint from 4 hex characters following `\u`
@brief get codepoint from 4 hex characters following `\u`
@return codepoint or -1 in case of an error (e.g. EOF or non-hex
@return codepoint or -1 in case of an error (e.g. EOF or non-hex character)
character)
*/
*/
int
get_codepoint
()
int
get_codepoint
()
{
{
...
@@ -1903,9 +1884,9 @@ class lexer
...
@@ -1903,9 +1884,9 @@ class lexer
@brief scan a string literal
@brief scan a string literal
This function scans a string according to Sect. 7 of RFC 7159. While
This function scans a string according to Sect. 7 of RFC 7159. While
scanning, bytes are escaped and copied into buffer yytext. Then the
function
scanning, bytes are escaped and copied into buffer yytext. Then the
returns successfully, yytext is null-terminated and yylen contains the
function returns successfully, yytext is null-terminated and yylen
number of bytes in the string.
contains the
number of bytes in the string.
@return token_type::value_string if string could be successfully scanned,
@return token_type::value_string if string could be successfully scanned,
token_type::parse_error otherwise
token_type::parse_error otherwise
...
@@ -1988,8 +1969,7 @@ class lexer
...
@@ -1988,8 +1969,7 @@ class lexer
if
(
JSON_UNLIKELY
(
codepoint1
==
-
1
))
if
(
JSON_UNLIKELY
(
codepoint1
==
-
1
))
{
{
error_message
=
error_message
=
"invalid string: '
\\
u' must be followed by 4 hex digits"
;
"invalid string: '
\\
u' must be followed by 4 hex digits"
;
return
token_type
::
parse_error
;
return
token_type
::
parse_error
;
}
}
...
@@ -2457,27 +2437,17 @@ class lexer
...
@@ -2457,27 +2437,17 @@ class lexer
errors. In the table below, "anything" means any character but the ones
errors. In the table below, "anything" means any character but the ones
listed before.
listed before.
state | 0 | 1-9 | e E | + | - | . |
state | 0 | 1-9 | e E | + | - | . | anything
anything
---------|----------|----------|----------|---------|---------|----------|-----------
---------|----------|----------|----------|---------|---------|----------|-----------
init | zero | any1 | [error] | [error] | minus | [error] |
init | zero | any1 | [error] | [error] | minus | [error] | [error]
[error]
minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
minus | zero | any1 | [error] | [error] | [error] | [error] |
zero | done | done | exponent | done | done | decimal1 | done
[error]
any1 | any1 | any1 | exponent | done | done | decimal1 | done
zero | done | done | exponent | done | done | decimal1 |
decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
done
decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
any1 | any1 | any1 | exponent | done | done | decimal1 |
exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
done
sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] |
any2 | any2 | any2 | done | done | done | done | done
[error]
decimal2 | decimal2 | decimal2 | exponent | done | done | done |
done
exponent | any2 | any2 | [error] | sign | sign | [error] |
[error]
sign | any2 | any2 | [error] | [error] | [error] | [error] |
[error]
any2 | any2 | any2 | done | done | done | done |
done
The state machine is realized with one label per state (prefixed with
The state machine is realized with one label per state (prefixed with
"scan_number_") and `goto` statements between them. The state machine
"scan_number_") and `goto` statements between them. The state machine
...
@@ -2780,8 +2750,8 @@ scan_number_any2:
...
@@ -2780,8 +2750,8 @@ scan_number_any2:
}
}
scan_number_done
:
scan_number_done
:
// unget the character after the number (we only read it to know
// unget the character after the number (we only read it to know
that we
//
that we
are done scanning a number)
// are done scanning a number)
--
chars_read
;
--
chars_read
;
next_unget
=
true
;
next_unget
=
true
;
...
@@ -2827,8 +2797,8 @@ scan_number_done:
...
@@ -2827,8 +2797,8 @@ scan_number_done:
}
}
}
}
// this code is reached if we parse a floating-point number or if
// this code is reached if we parse a floating-point number or if
an
//
an
integer conversion above failed
// integer conversion above failed
strtof
(
value_float
,
yytext
.
data
(),
nullptr
);
strtof
(
value_float
,
yytext
.
data
(),
nullptr
);
return
token_type
::
value_float
;
return
token_type
::
value_float
;
}
}
...
@@ -2911,8 +2881,8 @@ scan_number_done:
...
@@ -2911,8 +2881,8 @@ scan_number_done:
/// return string value
/// return string value
const
std
::
string
get_string
()
const
std
::
string
get_string
()
{
{
// yytext cannot be returned as char*, because it may contain a
// yytext cannot be returned as char*, because it may contain a
null
//
null
byte (parsed as "\u0000")
// byte (parsed as "\u0000")
return
std
::
string
(
yytext
.
data
(),
yylen
);
return
std
::
string
(
yytext
.
data
(),
yylen
);
}
}
...
@@ -2976,8 +2946,7 @@ scan_number_done:
...
@@ -2976,8 +2946,7 @@ scan_number_done:
{
{
get
();
get
();
}
}
while
(
current
==
' '
or
current
==
'\t'
or
current
==
'\n'
or
while
(
current
==
' '
or
current
==
'\t'
or
current
==
'\n'
or
current
==
'\r'
);
current
==
'\r'
);
switch
(
current
)
switch
(
current
)
{
{
...
@@ -3071,13 +3040,12 @@ scan_number_done:
...
@@ -3071,13 +3040,12 @@ scan_number_done:
This class implements a recursive decent parser.
This class implements a recursive decent parser.
*/
*/
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
class
parser
class
parser
{
{
using
number_integer_t
=
typename
BasicJsonType
::
number_integer_t
;
using
number_integer_t
=
typename
BasicJsonType
::
number_integer_t
;
using
number_unsigned_t
=
typename
BasicJsonType
::
number_unsigned_t
;
using
number_unsigned_t
=
typename
BasicJsonType
::
number_unsigned_t
;
using
number_float_t
=
typename
BasicJsonType
::
number_float_t
;
using
number_float_t
=
typename
BasicJsonType
::
number_float_t
;
using
lexer_t
=
lexer
<
BasicJsonType
>
;
using
lexer_t
=
lexer
<
BasicJsonType
>
;
using
token_type
=
typename
lexer_t
::
token_type
;
using
token_type
=
typename
lexer_t
::
token_type
;
...
@@ -3367,8 +3335,7 @@ class parser
...
@@ -3367,8 +3335,7 @@ class parser
if
(
JSON_UNLIKELY
(
not
std
::
isfinite
(
result
.
m_value
.
number_float
)))
if
(
JSON_UNLIKELY
(
not
std
::
isfinite
(
result
.
m_value
.
number_float
)))
{
{
JSON_THROW
(
out_of_range
::
create
(
406
,
"number overflow parsing '"
+
JSON_THROW
(
out_of_range
::
create
(
406
,
"number overflow parsing '"
+
m_lexer
.
get_token_string
()
+
m_lexer
.
get_token_string
()
+
"'"
));
"'"
));
}
}
break
;
break
;
}
}
...
@@ -3397,9 +3364,8 @@ class parser
...
@@ -3397,9 +3364,8 @@ class parser
/*!
/*!
@brief the acutal acceptor
@brief the acutal acceptor
@invariant 1. The last token is not yet processed. Therefore, the
@invariant 1. The last token is not yet processed. Therefore, the caller
caller of this function must make sure a token has
of this function must make sure a token has been read.
been read.
2. When this function returns, the last token is processed.
2. When this function returns, the last token is processed.
That is, the last read character was already considered.
That is, the last read character was already considered.
...
@@ -3581,10 +3547,11 @@ class primitive_iterator_t
...
@@ -3581,10 +3547,11 @@ class primitive_iterator_t
public
:
public
:
using
difference_type
=
std
::
ptrdiff_t
;
using
difference_type
=
std
::
ptrdiff_t
;
difference_type
get_value
()
const
noexcept
constexpr
difference_type
get_value
()
const
noexcept
{
{
return
m_it
;
return
m_it
;
}
}
/// set iterator to a defined beginning
/// set iterator to a defined beginning
void
set_begin
()
noexcept
void
set_begin
()
noexcept
{
{
...
@@ -3609,38 +3576,32 @@ class primitive_iterator_t
...
@@ -3609,38 +3576,32 @@ class primitive_iterator_t
return
(
m_it
==
end_value
);
return
(
m_it
==
end_value
);
}
}
friend
constexpr
bool
operator
==
(
primitive_iterator_t
lhs
,
friend
constexpr
bool
operator
==
(
primitive_iterator_t
lhs
,
primitive_iterator_t
rhs
)
noexcept
primitive_iterator_t
rhs
)
noexcept
{
{
return
lhs
.
m_it
==
rhs
.
m_it
;
return
(
lhs
.
m_it
==
rhs
.
m_it
)
;
}
}
friend
constexpr
bool
operator
!=
(
primitive_iterator_t
lhs
,
friend
constexpr
bool
operator
!=
(
primitive_iterator_t
lhs
,
primitive_iterator_t
rhs
)
noexcept
primitive_iterator_t
rhs
)
noexcept
{
{
return
!
(
lhs
==
rhs
);
return
not
(
lhs
==
rhs
);
}
}
friend
constexpr
bool
operator
<
(
primitive_iterator_t
lhs
,
friend
constexpr
bool
operator
<
(
primitive_iterator_t
lhs
,
primitive_iterator_t
rhs
)
noexcept
primitive_iterator_t
rhs
)
noexcept
{
{
return
lhs
.
m_it
<
rhs
.
m_it
;
return
lhs
.
m_it
<
rhs
.
m_it
;
}
}
friend
constexpr
bool
operator
<=
(
primitive_iterator_t
lhs
,
friend
constexpr
bool
operator
<=
(
primitive_iterator_t
lhs
,
primitive_iterator_t
rhs
)
noexcept
primitive_iterator_t
rhs
)
noexcept
{
{
return
lhs
.
m_it
<=
rhs
.
m_it
;
return
lhs
.
m_it
<=
rhs
.
m_it
;
}
}
friend
constexpr
bool
operator
>
(
primitive_iterator_t
lhs
,
friend
constexpr
bool
operator
>
(
primitive_iterator_t
lhs
,
primitive_iterator_t
rhs
)
noexcept
primitive_iterator_t
rhs
)
noexcept
{
{
return
lhs
.
m_it
>
rhs
.
m_it
;
return
lhs
.
m_it
>
rhs
.
m_it
;
}
}
friend
constexpr
bool
operator
>=
(
primitive_iterator_t
lhs
,
friend
constexpr
bool
operator
>=
(
primitive_iterator_t
lhs
,
primitive_iterator_t
rhs
)
noexcept
primitive_iterator_t
rhs
)
noexcept
{
{
return
lhs
.
m_it
>=
rhs
.
m_it
;
return
lhs
.
m_it
>=
rhs
.
m_it
;
}
}
...
@@ -3652,13 +3613,12 @@ class primitive_iterator_t
...
@@ -3652,13 +3613,12 @@ class primitive_iterator_t
return
result
;
return
result
;
}
}
friend
constexpr
difference_type
friend
constexpr
difference_type
operator
-
(
primitive_iterator_t
lhs
,
primitive_iterator_t
rhs
)
noexcept
operator
-
(
primitive_iterator_t
lhs
,
primitive_iterator_t
rhs
)
noexcept
{
{
return
lhs
.
m_it
-
rhs
.
m_it
;
return
lhs
.
m_it
-
rhs
.
m_it
;
}
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
primitive_iterator_t
it
)
friend
constexpr
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
primitive_iterator_t
it
)
{
{
return
os
<<
it
.
m_it
;
return
os
<<
it
.
m_it
;
}
}
...
@@ -3712,11 +3672,10 @@ class primitive_iterator_t
...
@@ -3712,11 +3672,10 @@ class primitive_iterator_t
/*!
/*!
@brief an iterator value
@brief an iterator value
@note This structure could easily be a union, but MSVC currently does not
@note This structure could easily be a union, but MSVC currently does not allow
allow unions members with complex constructors, see
unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
https://github.com/nlohmann/json/pull/105.
*/
*/
template
<
typename
BasicJsonType
>
struct
internal_iterator
template
<
typename
BasicJsonType
>
struct
internal_iterator
{
{
/// iterator for JSON objects
/// iterator for JSON objects
typename
BasicJsonType
::
object_t
::
iterator
object_iterator
{};
typename
BasicJsonType
::
object_t
::
iterator
object_iterator
{};
...
@@ -3726,7 +3685,7 @@ template <typename BasicJsonType> struct internal_iterator
...
@@ -3726,7 +3685,7 @@ template <typename BasicJsonType> struct internal_iterator
primitive_iterator_t
primitive_iterator
{};
primitive_iterator_t
primitive_iterator
{};
};
};
template
<
typename
IteratorType
>
class
iteration_proxy
;
template
<
typename
IteratorType
>
class
iteration_proxy
;
/*!
/*!
@brief a template for a random access iterator for the @ref basic_json class
@brief a template for a random access iterator for the @ref basic_json class
...
@@ -3747,7 +3706,7 @@ This class implements a both iterators (iterator and const_iterator) for the
...
@@ -3747,7 +3706,7 @@ This class implements a both iterators (iterator and const_iterator) for the
@since version 1.0.0, simplified in version 2.0.9
@since version 1.0.0, simplified in version 2.0.9
*/
*/
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
class
iter_impl
:
public
std
::
iterator
<
std
::
random_access_iterator_tag
,
BasicJsonType
>
class
iter_impl
:
public
std
::
iterator
<
std
::
random_access_iterator_tag
,
BasicJsonType
>
{
{
/// allow basic_json to access private members
/// allow basic_json to access private members
...
@@ -3814,13 +3773,12 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -3814,13 +3773,12 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
}
}
/*!
/*!
@note The conventional copy constructor and copy assignment are
@note The conventional copy constructor and copy assignment are implicitly
implicitly defined.
defined. Combined with the following converting constructor and
Combined with the following converting constructor and assignment,
assignment, they support: (1) copy from iterator to iterator, (2)
they support: copy from iterator to iterator,
copy from const iterator to const iterator, and (3) conversion from
copy from const iterator to const iterator,
iterator to const iterator. However conversion from const iterator
and conversion from iterator to const iterator.
to iterator is not defined.
However conversion from const iterator to iterator is not defined.
*/
*/
/*!
/*!
...
@@ -3829,8 +3787,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -3829,8 +3787,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
@note It is not checked whether @a other is initialized.
@note It is not checked whether @a other is initialized.
*/
*/
iter_impl
(
const
iter_impl
<
typename
std
::
remove_const
<
BasicJsonType
>::
type
>&
other
)
noexcept
iter_impl
(
const
iter_impl
<
typename
std
::
remove_const
<
BasicJsonType
>::
type
>&
other
)
noexcept
:
m_object
(
other
.
m_object
),
:
m_object
(
other
.
m_object
),
m_it
(
other
.
m_it
)
{}
m_it
(
other
.
m_it
)
{}
/*!
/*!
@brief converting assignment
@brief converting assignment
...
@@ -3943,7 +3900,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -3943,7 +3900,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
default
:
default
:
{
{
if
(
m_it
.
primitive_iterator
.
is_begin
(
))
if
(
JSON_LIKELY
(
m_it
.
primitive_iterator
.
is_begin
()
))
{
{
return
*
m_object
;
return
*
m_object
;
}
}
...
@@ -3977,7 +3934,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -3977,7 +3934,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
default
:
default
:
{
{
if
(
m_it
.
primitive_iterator
.
is_begin
(
))
if
(
JSON_LIKELY
(
m_it
.
primitive_iterator
.
is_begin
()
))
{
{
return
m_object
;
return
m_object
;
}
}
...
@@ -4080,10 +4037,9 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4080,10 +4037,9 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
bool
operator
==
(
const
iter_impl
&
other
)
const
bool
operator
==
(
const
iter_impl
&
other
)
const
{
{
// if objects are not the same, the comparison is undefined
// if objects are not the same, the comparison is undefined
if
(
m_object
!=
other
.
m_object
)
if
(
JSON_UNLIKELY
(
m_object
!=
other
.
m_object
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
JSON_THROW
(
invalid_iterator
::
create
(
212
,
"cannot compare iterators of different containers"
));
212
,
"cannot compare iterators of different containers"
));
}
}
assert
(
m_object
!=
nullptr
);
assert
(
m_object
!=
nullptr
);
...
@@ -4123,10 +4079,9 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4123,10 +4079,9 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
bool
operator
<
(
const
iter_impl
&
other
)
const
bool
operator
<
(
const
iter_impl
&
other
)
const
{
{
// if objects are not the same, the comparison is undefined
// if objects are not the same, the comparison is undefined
if
(
m_object
!=
other
.
m_object
)
if
(
JSON_UNLIKELY
(
m_object
!=
other
.
m_object
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
JSON_THROW
(
invalid_iterator
::
create
(
212
,
"cannot compare iterators of different containers"
));
212
,
"cannot compare iterators of different containers"
));
}
}
assert
(
m_object
!=
nullptr
);
assert
(
m_object
!=
nullptr
);
...
@@ -4135,8 +4090,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4135,8 +4090,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
{
{
case
value_t
:
:
object
:
case
value_t
:
:
object
:
{
{
JSON_THROW
(
invalid_iterator
::
create
(
JSON_THROW
(
invalid_iterator
::
create
(
213
,
"cannot compare order of object iterators"
));
213
,
"cannot compare order of object iterators"
));
}
}
case
value_t
:
:
array
:
case
value_t
:
:
array
:
...
@@ -4190,8 +4144,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4190,8 +4144,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
{
{
case
value_t
:
:
object
:
case
value_t
:
:
object
:
{
{
JSON_THROW
(
invalid_iterator
::
create
(
JSON_THROW
(
invalid_iterator
::
create
(
209
,
"cannot use offsets with object iterators"
));
209
,
"cannot use offsets with object iterators"
));
}
}
case
value_t
:
:
array
:
case
value_t
:
:
array
:
...
@@ -4264,8 +4217,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4264,8 +4217,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
{
{
case
value_t
:
:
object
:
case
value_t
:
:
object
:
{
{
JSON_THROW
(
invalid_iterator
::
create
(
JSON_THROW
(
invalid_iterator
::
create
(
209
,
"cannot use offsets with object iterators"
));
209
,
"cannot use offsets with object iterators"
));
}
}
case
value_t
:
:
array
:
case
value_t
:
:
array
:
...
@@ -4292,8 +4244,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4292,8 +4244,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
{
{
case
value_t
:
:
object
:
case
value_t
:
:
object
:
{
{
JSON_THROW
(
invalid_iterator
::
create
(
JSON_THROW
(
invalid_iterator
::
create
(
208
,
"cannot use operator[] for object iterators"
));
208
,
"cannot use operator[] for object iterators"
));
}
}
case
value_t
:
:
array
:
case
value_t
:
:
array
:
...
@@ -4308,7 +4259,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4308,7 +4259,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
default
:
default
:
{
{
if
(
m_it
.
primitive_iterator
.
get_value
()
==
-
n
)
if
(
JSON_LIKELY
(
m_it
.
primitive_iterator
.
get_value
()
==
-
n
)
)
{
{
return
*
m_object
;
return
*
m_object
;
}
}
...
@@ -4326,13 +4277,12 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4326,13 +4277,12 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
{
{
assert
(
m_object
!=
nullptr
);
assert
(
m_object
!=
nullptr
);
if
(
m_object
->
is_object
(
))
if
(
JSON_LIKELY
(
m_object
->
is_object
()
))
{
{
return
m_it
.
object_iterator
->
first
;
return
m_it
.
object_iterator
->
first
;
}
}
JSON_THROW
(
invalid_iterator
::
create
(
JSON_THROW
(
invalid_iterator
::
create
(
207
,
"cannot use key() for non-object iterators"
));
207
,
"cannot use key() for non-object iterators"
));
}
}
/*!
/*!
...
@@ -4352,7 +4302,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
...
@@ -4352,7 +4302,7 @@ class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJso
};
};
/// proxy class for the iterator_wrapper functions
/// proxy class for the iterator_wrapper functions
template
<
typename
IteratorType
>
class
iteration_proxy
template
<
typename
IteratorType
>
class
iteration_proxy
{
{
private
:
private
:
/// helper class for iteration
/// helper class for iteration
...
@@ -4383,7 +4333,7 @@ template <typename IteratorType> class iteration_proxy
...
@@ -4383,7 +4333,7 @@ template <typename IteratorType> class iteration_proxy
}
}
/// inequality operator (needed for range-based for)
/// inequality operator (needed for range-based for)
bool
operator
!=
(
const
iteration_proxy_internal
&
o
)
const
constexpr
bool
operator
!=
(
const
iteration_proxy_internal
&
o
)
const
{
{
return
anchor
!=
o
.
anchor
;
return
anchor
!=
o
.
anchor
;
}
}
...
@@ -4461,7 +4411,7 @@ create @ref const_reverse_iterator).
...
@@ -4461,7 +4411,7 @@ create @ref const_reverse_iterator).
@since version 1.0.0
@since version 1.0.0
*/
*/
template
<
typename
Base
>
template
<
typename
Base
>
class
json_reverse_iterator
:
public
std
::
reverse_iterator
<
Base
>
class
json_reverse_iterator
:
public
std
::
reverse_iterator
<
Base
>
{
{
public
:
public
:
...
@@ -4472,8 +4422,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
...
@@ -4472,8 +4422,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
using
reference
=
typename
Base
::
reference
;
using
reference
=
typename
Base
::
reference
;
/// create reverse iterator from iterator
/// create reverse iterator from iterator
json_reverse_iterator
(
json_reverse_iterator
(
const
typename
base_iterator
::
iterator_type
&
it
)
noexcept
const
typename
base_iterator
::
iterator_type
&
it
)
noexcept
:
base_iterator
(
it
)
{}
:
base_iterator
(
it
)
{}
/// create reverse iterator from base class
/// create reverse iterator from base class
...
@@ -4553,7 +4502,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
...
@@ -4553,7 +4502,7 @@ class json_reverse_iterator : public std::reverse_iterator<Base>
/////////////////////
/////////////////////
/// abstract output adapter interface
/// abstract output adapter interface
template
<
typename
CharType
>
struct
output_adapter_protocol
template
<
typename
CharType
>
struct
output_adapter_protocol
{
{
virtual
void
write_character
(
CharType
c
)
=
0
;
virtual
void
write_character
(
CharType
c
)
=
0
;
virtual
void
write_characters
(
const
CharType
*
s
,
std
::
size_t
length
)
=
0
;
virtual
void
write_characters
(
const
CharType
*
s
,
std
::
size_t
length
)
=
0
;
...
@@ -4561,11 +4510,11 @@ template <typename CharType> struct output_adapter_protocol
...
@@ -4561,11 +4510,11 @@ template <typename CharType> struct output_adapter_protocol
};
};
/// a type to simplify interfaces
/// a type to simplify interfaces
template
<
typename
CharType
>
template
<
typename
CharType
>
using
output_adapter_t
=
std
::
shared_ptr
<
output_adapter_protocol
<
CharType
>>
;
using
output_adapter_t
=
std
::
shared_ptr
<
output_adapter_protocol
<
CharType
>>
;
/// output adapter for byte vectors
/// output adapter for byte vectors
template
<
typename
CharType
>
template
<
typename
CharType
>
class
output_vector_adapter
:
public
output_adapter_protocol
<
CharType
>
class
output_vector_adapter
:
public
output_adapter_protocol
<
CharType
>
{
{
public
:
public
:
...
@@ -4586,7 +4535,7 @@ class output_vector_adapter : public output_adapter_protocol<CharType>
...
@@ -4586,7 +4535,7 @@ class output_vector_adapter : public output_adapter_protocol<CharType>
};
};
/// output adapter for output streams
/// output adapter for output streams
template
<
typename
CharType
>
template
<
typename
CharType
>
class
output_stream_adapter
:
public
output_adapter_protocol
<
CharType
>
class
output_stream_adapter
:
public
output_adapter_protocol
<
CharType
>
{
{
public
:
public
:
...
@@ -4607,7 +4556,7 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
...
@@ -4607,7 +4556,7 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
};
};
/// output adapter for basic_string
/// output adapter for basic_string
template
<
typename
CharType
>
template
<
typename
CharType
>
class
output_string_adapter
:
public
output_adapter_protocol
<
CharType
>
class
output_string_adapter
:
public
output_adapter_protocol
<
CharType
>
{
{
public
:
public
:
...
@@ -4627,7 +4576,7 @@ class output_string_adapter : public output_adapter_protocol<CharType>
...
@@ -4627,7 +4576,7 @@ class output_string_adapter : public output_adapter_protocol<CharType>
std
::
basic_string
<
CharType
>&
str
;
std
::
basic_string
<
CharType
>&
str
;
};
};
template
<
typename
CharType
>
template
<
typename
CharType
>
class
output_adapter
class
output_adapter
{
{
public
:
public
:
...
@@ -4656,7 +4605,7 @@ class output_adapter
...
@@ -4656,7 +4605,7 @@ class output_adapter
/*!
/*!
@brief deserialization of CBOR and MessagePack values
@brief deserialization of CBOR and MessagePack values
*/
*/
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
class
binary_reader
class
binary_reader
{
{
using
number_integer_t
=
typename
BasicJsonType
::
number_integer_t
;
using
number_integer_t
=
typename
BasicJsonType
::
number_integer_t
;
...
@@ -5493,8 +5442,7 @@ class binary_reader
...
@@ -5493,8 +5442,7 @@ class binary_reader
{
{
std
::
stringstream
ss
;
std
::
stringstream
ss
;
ss
<<
std
::
setw
(
2
)
<<
std
::
setfill
(
'0'
)
<<
std
::
hex
<<
current
;
ss
<<
std
::
setw
(
2
)
<<
std
::
setfill
(
'0'
)
<<
std
::
hex
<<
current
;
JSON_THROW
(
parse_error
::
create
(
JSON_THROW
(
parse_error
::
create
(
112
,
chars_read
,
112
,
chars_read
,
"error reading MessagePack; last byte: 0x"
+
ss
.
str
()));
"error reading MessagePack; last byte: 0x"
+
ss
.
str
()));
}
}
}
}
...
@@ -5539,10 +5487,9 @@ class binary_reader
...
@@ -5539,10 +5487,9 @@ class binary_reader
bytes in CBOR and MessagePack are stored in network order (big
bytes in CBOR and MessagePack are stored in network order (big
endian) and therefore need reordering on little endian systems.
endian) and therefore need reordering on little endian systems.
@throw parse_error.110 if input has less than `sizeof(NumberType)`
@throw parse_error.110 if input has less than `sizeof(NumberType)` bytes
bytes
*/
*/
template
<
typename
NumberType
>
NumberType
get_number
()
template
<
typename
NumberType
>
NumberType
get_number
()
{
{
// step 1: read input into array with system's byte order
// step 1: read input into array with system's byte order
std
::
array
<
uint8_t
,
sizeof
(
NumberType
)
>
vec
;
std
::
array
<
uint8_t
,
sizeof
(
NumberType
)
>
vec
;
...
@@ -5680,8 +5627,7 @@ class binary_reader
...
@@ -5680,8 +5627,7 @@ class binary_reader
{
{
std
::
stringstream
ss
;
std
::
stringstream
ss
;
ss
<<
std
::
setw
(
2
)
<<
std
::
setfill
(
'0'
)
<<
std
::
hex
<<
current
;
ss
<<
std
::
setw
(
2
)
<<
std
::
setfill
(
'0'
)
<<
std
::
hex
<<
current
;
JSON_THROW
(
parse_error
::
create
(
JSON_THROW
(
parse_error
::
create
(
113
,
chars_read
,
"expected a CBOR string; last byte: 0x"
+
ss
.
str
()));
113
,
chars_read
,
"expected a CBOR string; last byte: 0x"
+
ss
.
str
()));
}
}
}
}
}
}
...
@@ -5763,8 +5709,7 @@ class binary_reader
...
@@ -5763,8 +5709,7 @@ class binary_reader
{
{
std
::
stringstream
ss
;
std
::
stringstream
ss
;
ss
<<
std
::
setw
(
2
)
<<
std
::
setfill
(
'0'
)
<<
std
::
hex
<<
current
;
ss
<<
std
::
setw
(
2
)
<<
std
::
setfill
(
'0'
)
<<
std
::
hex
<<
current
;
JSON_THROW
(
parse_error
::
create
(
JSON_THROW
(
parse_error
::
create
(
113
,
chars_read
,
113
,
chars_read
,
"expected a MessagePack string; last byte: 0x"
+
ss
.
str
()));
"expected a MessagePack string; last byte: 0x"
+
ss
.
str
()));
}
}
}
}
...
@@ -5799,7 +5744,7 @@ class binary_reader
...
@@ -5799,7 +5744,7 @@ class binary_reader
/*!
/*!
@brief serialization to CBOR and MessagePack values
@brief serialization to CBOR and MessagePack values
*/
*/
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
class
binary_writer
class
binary_writer
{
{
public
:
public
:
...
@@ -6085,9 +6030,8 @@ class binary_writer
...
@@ -6085,9 +6030,8 @@ class binary_writer
if
(
j
.
m_value
.
number_integer
>=
0
)
if
(
j
.
m_value
.
number_integer
>=
0
)
{
{
// MessagePack does not differentiate between positive
// MessagePack does not differentiate between positive
// signed integers and unsigned integers. Therefore, we
// signed integers and unsigned integers. Therefore, we used
// used the code from the value_t::number_unsigned case
// the code from the value_t::number_unsigned case here.
// here.
if
(
j
.
m_value
.
number_unsigned
<
128
)
if
(
j
.
m_value
.
number_unsigned
<
128
)
{
{
// positive fixnum
// positive fixnum
...
@@ -6309,11 +6253,11 @@ class binary_writer
...
@@ -6309,11 +6253,11 @@ class binary_writer
@param[in] n number of type @a NumberType
@param[in] n number of type @a NumberType
@tparam NumberType the type of the number
@tparam NumberType the type of the number
@note This function needs to respect the system's endianess, because
@note This function needs to respect the system's endianess, because
bytes
bytes in CBOR and MessagePack are stored in network order (big
in CBOR and MessagePack are stored in network order (big endian) and
endian) and
therefore need reordering on little endian systems.
therefore need reordering on little endian systems.
*/
*/
template
<
typename
NumberType
>
void
write_number
(
NumberType
n
)
template
<
typename
NumberType
>
void
write_number
(
NumberType
n
)
{
{
// step 1: write number to array of length NumberType
// step 1: write number to array of length NumberType
std
::
array
<
uint8_t
,
sizeof
(
NumberType
)
>
vec
;
std
::
array
<
uint8_t
,
sizeof
(
NumberType
)
>
vec
;
...
@@ -6341,7 +6285,7 @@ class binary_writer
...
@@ -6341,7 +6285,7 @@ class binary_writer
// serialization //
// serialization //
///////////////////
///////////////////
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
class
serializer
class
serializer
{
{
using
string_t
=
typename
BasicJsonType
::
string_t
;
using
string_t
=
typename
BasicJsonType
::
string_t
;
...
@@ -6366,10 +6310,10 @@ class serializer
...
@@ -6366,10 +6310,10 @@ class serializer
/*!
/*!
@brief internal implementation of the serialization function
@brief internal implementation of the serialization function
This function is called by the public member function dump and
This function is called by the public member function dump and
organizes
organizes the serialization internally. The indentation level i
s
the serialization internally. The indentation level is propagated a
s
propagated as additional parameter. In case of arrays and objects, the
additional parameter. In case of arrays and objects, the function is
function is
called recursively.
called recursively.
- strings and object keys are escaped using `escape_string()`
- strings and object keys are escaped using `escape_string()`
- integer numbers are converted implicitly via `operator<<`
- integer numbers are converted implicitly via `operator<<`
...
@@ -6472,9 +6416,9 @@ class serializer
...
@@ -6472,9 +6416,9 @@ class serializer
// variable to hold indentation for recursive calls
// variable to hold indentation for recursive calls
const
auto
new_indent
=
current_indent
+
indent_step
;
const
auto
new_indent
=
current_indent
+
indent_step
;
if
(
indent_string
.
size
()
<
new_indent
)
if
(
JSON_UNLIKELY
(
indent_string
.
size
()
<
new_indent
)
)
{
{
indent_string
.
resize
(
new_indent
,
' '
);
indent_string
.
resize
(
indent_string
.
size
()
*
2
,
' '
);
}
}
// first n-1 elements
// first n-1 elements
...
@@ -6666,10 +6610,10 @@ class serializer
...
@@ -6666,10 +6610,10 @@ class serializer
if
(
bytes
==
3
)
if
(
bytes
==
3
)
{
{
// codepoints that need 4 bytes (i.e., 3
// codepoints that need 4 bytes (i.e., 3
additional
//
additional bytes) in UTF-8 needs a surrogate
//
bytes) in UTF-8 needs a surrogate pair when \u
//
pair when \u escaping is used:
//
escaping is used: from 4 bytes to \uxxxx\uxxxx
//
from 4 bytes to \uxxxx\uxxxx
(12 bytes)
// (12 bytes)
res
+=
(
12
-
bytes
-
1
);
res
+=
(
12
-
bytes
-
1
);
}
}
else
else
...
@@ -6743,13 +6687,14 @@ class serializer
...
@@ -6743,13 +6687,14 @@ class serializer
/*!
/*!
@brief dump escaped string
@brief dump escaped string
Escape a string by replacing certain special characters by a sequence
Escape a string by replacing certain special characters by a sequence
of an
of an escape character (backslash) and another character and other
escape character (backslash) and another character and other control
c
ontrol c
haracters by a sequence of "\u" followed by a four-digit hex
characters by a sequence of "\u" followed by a four-digit hex
representation. The escaped string is written to output stream @a o.
representation. The escaped string is written to output stream @a o.
@param[in] s the string to escape
@param[in] s the string to escape
@param[in] ensure_ascii whether to escape non-ASCII characters with \uXXXX sequences
@param[in] ensure_ascii whether to escape non-ASCII characters with
\uXXXX sequences
@complexity Linear in the length of string @a s.
@complexity Linear in the length of string @a s.
*/
*/
...
@@ -6950,8 +6895,8 @@ class serializer
...
@@ -6950,8 +6895,8 @@ class serializer
/*!
/*!
@brief dump a floating-point number
@brief dump a floating-point number
Dump a given floating-point number to output stream @a o. Works
Dump a given floating-point number to output stream @a o. Works
internally
internally
with @a number_buffer.
with @a number_buffer.
@param[in] x floating-point number to dump
@param[in] x floating-point number to dump
*/
*/
...
@@ -7019,7 +6964,7 @@ class serializer
...
@@ -7019,7 +6964,7 @@ class serializer
std
::
none_of
(
number_buffer
.
begin
(),
number_buffer
.
begin
()
+
len
+
1
,
std
::
none_of
(
number_buffer
.
begin
(),
number_buffer
.
begin
()
+
len
+
1
,
[](
char
c
)
[](
char
c
)
{
{
return
c
==
'.'
or
c
==
'e'
;
return
(
c
==
'.'
or
c
==
'e'
)
;
});
});
if
(
value_is_int_like
)
if
(
value_is_int_like
)
...
@@ -7180,7 +7125,7 @@ class json_pointer
...
@@ -7180,7 +7125,7 @@ class json_pointer
*/
*/
std
::
string
pop_back
()
std
::
string
pop_back
()
{
{
if
(
is_root
(
))
if
(
JSON_UNLIKELY
(
is_root
()
))
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
}
}
...
@@ -7198,7 +7143,7 @@ class json_pointer
...
@@ -7198,7 +7143,7 @@ class json_pointer
json_pointer
top
()
const
json_pointer
top
()
const
{
{
if
(
is_root
(
))
if
(
JSON_UNLIKELY
(
is_root
()
))
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
JSON_THROW
(
detail
::
out_of_range
::
create
(
405
,
"JSON pointer has no parent"
));
}
}
...
@@ -7296,10 +7241,9 @@ class json_pointer
...
@@ -7296,10 +7241,9 @@ class json_pointer
}
}
// check if nonempty reference string begins with slash
// check if nonempty reference string begins with slash
if
(
reference_string
[
0
]
!=
'/'
)
if
(
JSON_UNLIKELY
(
reference_string
[
0
]
!=
'/'
)
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
JSON_THROW
(
detail
::
parse_error
::
create
(
107
,
1
,
107
,
1
,
"JSON pointer must be empty or begin with '/' - was: '"
+
"JSON pointer must be empty or begin with '/' - was: '"
+
reference_string
+
"'"
));
reference_string
+
"'"
));
}
}
...
@@ -7332,12 +7276,11 @@ class json_pointer
...
@@ -7332,12 +7276,11 @@ class json_pointer
assert
(
reference_token
[
pos
]
==
'~'
);
assert
(
reference_token
[
pos
]
==
'~'
);
// ~ must be followed by 0 or 1
// ~ must be followed by 0 or 1
if
(
pos
==
reference_token
.
size
()
-
1
or
if
(
JSON_UNLIKELY
(
pos
==
reference_token
.
size
()
-
1
or
(
reference_token
[
pos
+
1
]
!=
'0'
and
(
reference_token
[
pos
+
1
]
!=
'0'
and
reference_token
[
pos
+
1
]
!=
'1'
))
reference_token
[
pos
+
1
]
!=
'1'
)
))
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
JSON_THROW
(
detail
::
parse_error
::
create
(
108
,
0
,
"escape character '~' must be followed with '0' or '1'"
));
108
,
0
,
"escape character '~' must be followed with '0' or '1'"
));
}
}
}
}
...
@@ -7373,21 +7316,18 @@ class json_pointer
...
@@ -7373,21 +7316,18 @@ class json_pointer
{}
{}
}
}
/// escape
tilde and slash
/// escape
"~"" to "~0" and "/" to "~1"
static
std
::
string
escape
(
std
::
string
s
)
static
std
::
string
escape
(
std
::
string
s
)
{
{
// escape "~"" to "~0" and "/" to "~1"
replace_substring
(
s
,
"~"
,
"~0"
);
replace_substring
(
s
,
"~"
,
"~0"
);
replace_substring
(
s
,
"/"
,
"~1"
);
replace_substring
(
s
,
"/"
,
"~1"
);
return
s
;
return
s
;
}
}
/// unescape
tilde and slash
/// unescape
"~1" to tilde and "~0" to slash (order is important!)
static
void
unescape
(
std
::
string
&
s
)
static
void
unescape
(
std
::
string
&
s
)
{
{
// first transform any occurrence of the sequence '~1' to '/'
replace_substring
(
s
,
"~1"
,
"/"
);
replace_substring
(
s
,
"~1"
,
"/"
);
// then transform any occurrence of the sequence '~0' to '~'
replace_substring
(
s
,
"~0"
,
"~"
);
replace_substring
(
s
,
"~0"
,
"~"
);
}
}
...
@@ -7516,7 +7456,7 @@ class basic_json
...
@@ -7516,7 +7456,7 @@ class basic_json
friend
::
nlohmann
::
json_pointer
;
friend
::
nlohmann
::
json_pointer
;
friend
::
nlohmann
::
detail
::
parser
<
basic_json
>
;
friend
::
nlohmann
::
detail
::
parser
<
basic_json
>
;
friend
::
nlohmann
::
detail
::
serializer
<
basic_json
>
;
friend
::
nlohmann
::
detail
::
serializer
<
basic_json
>
;
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
friend
class
::
nlohmann
::
detail
::
iter_impl
;
friend
class
::
nlohmann
::
detail
::
iter_impl
;
friend
::
nlohmann
::
detail
::
binary_writer
<
basic_json
>
;
friend
::
nlohmann
::
detail
::
binary_writer
<
basic_json
>
;
/// workaround type for MSVC
/// workaround type for MSVC
...
@@ -7527,15 +7467,15 @@ class basic_json
...
@@ -7527,15 +7467,15 @@ class basic_json
using
parser
=
::
nlohmann
::
detail
::
parser
<
basic_json
>
;
using
parser
=
::
nlohmann
::
detail
::
parser
<
basic_json
>
;
using
primitive_iterator_t
=
::
nlohmann
::
detail
::
primitive_iterator_t
;
using
primitive_iterator_t
=
::
nlohmann
::
detail
::
primitive_iterator_t
;
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
using
internal_iterator
=
::
nlohmann
::
detail
::
internal_iterator
<
BasicJsonType
>
;
using
internal_iterator
=
::
nlohmann
::
detail
::
internal_iterator
<
BasicJsonType
>
;
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
using
iter_impl
=
::
nlohmann
::
detail
::
iter_impl
<
BasicJsonType
>
;
using
iter_impl
=
::
nlohmann
::
detail
::
iter_impl
<
BasicJsonType
>
;
template
<
typename
Iterator
>
template
<
typename
Iterator
>
using
iteration_proxy
=
::
nlohmann
::
detail
::
iteration_proxy
<
Iterator
>
;
using
iteration_proxy
=
::
nlohmann
::
detail
::
iteration_proxy
<
Iterator
>
;
template
<
typename
Base
>
using
json_reverse_iterator
=
::
nlohmann
::
detail
::
json_reverse_iterator
<
Base
>
;
template
<
typename
Base
>
using
json_reverse_iterator
=
::
nlohmann
::
detail
::
json_reverse_iterator
<
Base
>
;
template
<
typename
CharType
>
template
<
typename
CharType
>
using
output_adapter_t
=
::
nlohmann
::
detail
::
output_adapter_t
<
CharType
>
;
using
output_adapter_t
=
::
nlohmann
::
detail
::
output_adapter_t
<
CharType
>
;
using
binary_reader
=
::
nlohmann
::
detail
::
binary_reader
<
basic_json
>
;
using
binary_reader
=
::
nlohmann
::
detail
::
binary_reader
<
basic_json
>
;
...
@@ -8614,7 +8554,7 @@ class basic_json
...
@@ -8614,7 +8554,7 @@ class basic_json
bool
is_an_object
=
std
::
all_of
(
init
.
begin
(),
init
.
end
(),
bool
is_an_object
=
std
::
all_of
(
init
.
begin
(),
init
.
end
(),
[](
const
basic_json
&
element
)
[](
const
basic_json
&
element
)
{
{
return
element
.
is_array
()
and
element
.
size
()
==
2
and
element
[
0
].
is_string
(
);
return
(
element
.
is_array
()
and
element
.
size
()
==
2
and
element
[
0
].
is_string
()
);
});
});
// adjust type if type deduction is not wanted
// adjust type if type deduction is not wanted
...
@@ -8627,7 +8567,7 @@ class basic_json
...
@@ -8627,7 +8567,7 @@ class basic_json
}
}
// if object is wanted but impossible, throw an exception
// if object is wanted but impossible, throw an exception
if
(
manual_type
==
value_t
::
object
and
not
is_an_object
)
if
(
JSON_UNLIKELY
(
manual_type
==
value_t
::
object
and
not
is_an_object
)
)
{
{
JSON_THROW
(
type_error
::
create
(
301
,
"cannot create object from initializer list"
));
JSON_THROW
(
type_error
::
create
(
301
,
"cannot create object from initializer list"
));
}
}
...
@@ -8811,7 +8751,7 @@ class basic_json
...
@@ -8811,7 +8751,7 @@ class basic_json
assert
(
last
.
m_object
!=
nullptr
);
assert
(
last
.
m_object
!=
nullptr
);
// make sure iterator fits the current value
// make sure iterator fits the current value
if
(
first
.
m_object
!=
last
.
m_object
)
if
(
JSON_UNLIKELY
(
first
.
m_object
!=
last
.
m_object
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
201
,
"iterators are not compatible"
));
JSON_THROW
(
invalid_iterator
::
create
(
201
,
"iterators are not compatible"
));
}
}
...
@@ -8828,7 +8768,8 @@ class basic_json
...
@@ -8828,7 +8768,8 @@ class basic_json
case
value_t
:
:
number_unsigned
:
case
value_t
:
:
number_unsigned
:
case
value_t
:
:
string
:
case
value_t
:
:
string
:
{
{
if
(
not
first
.
m_it
.
primitive_iterator
.
is_begin
()
or
not
last
.
m_it
.
primitive_iterator
.
is_end
())
if
(
JSON_UNLIKELY
(
not
first
.
m_it
.
primitive_iterator
.
is_begin
()
or
not
last
.
m_it
.
primitive_iterator
.
is_end
()))
{
{
JSON_THROW
(
invalid_iterator
::
create
(
204
,
"iterators out of range"
));
JSON_THROW
(
invalid_iterator
::
create
(
204
,
"iterators out of range"
));
}
}
...
@@ -8890,7 +8831,7 @@ class basic_json
...
@@ -8890,7 +8831,7 @@ class basic_json
default
:
default
:
{
{
JSON_THROW
(
invalid_iterator
::
create
(
206
,
"cannot construct with iterators from "
+
JSON_THROW
(
invalid_iterator
::
create
(
206
,
"cannot construct with iterators from "
+
first
.
m_object
->
type_name
(
)));
std
::
string
(
first
.
m_object
->
type_name
()
)));
}
}
}
}
...
@@ -9231,7 +9172,7 @@ class basic_json
...
@@ -9231,7 +9172,7 @@ class basic_json
*/
*/
constexpr
bool
is_null
()
const
noexcept
constexpr
bool
is_null
()
const
noexcept
{
{
return
m_type
==
value_t
::
null
;
return
(
m_type
==
value_t
::
null
)
;
}
}
/*!
/*!
...
@@ -9253,7 +9194,7 @@ class basic_json
...
@@ -9253,7 +9194,7 @@ class basic_json
*/
*/
constexpr
bool
is_boolean
()
const
noexcept
constexpr
bool
is_boolean
()
const
noexcept
{
{
return
m_type
==
value_t
::
boolean
;
return
(
m_type
==
value_t
::
boolean
)
;
}
}
/*!
/*!
...
@@ -9312,7 +9253,7 @@ class basic_json
...
@@ -9312,7 +9253,7 @@ class basic_json
*/
*/
constexpr
bool
is_number_integer
()
const
noexcept
constexpr
bool
is_number_integer
()
const
noexcept
{
{
return
m_type
==
value_t
::
number_integer
or
m_type
==
value_t
::
number_unsigned
;
return
(
m_type
==
value_t
::
number_integer
or
m_type
==
value_t
::
number_unsigned
)
;
}
}
/*!
/*!
...
@@ -9340,7 +9281,7 @@ class basic_json
...
@@ -9340,7 +9281,7 @@ class basic_json
*/
*/
constexpr
bool
is_number_unsigned
()
const
noexcept
constexpr
bool
is_number_unsigned
()
const
noexcept
{
{
return
m_type
==
value_t
::
number_unsigned
;
return
(
m_type
==
value_t
::
number_unsigned
)
;
}
}
/*!
/*!
...
@@ -9368,7 +9309,7 @@ class basic_json
...
@@ -9368,7 +9309,7 @@ class basic_json
*/
*/
constexpr
bool
is_number_float
()
const
noexcept
constexpr
bool
is_number_float
()
const
noexcept
{
{
return
m_type
==
value_t
::
number_float
;
return
(
m_type
==
value_t
::
number_float
)
;
}
}
/*!
/*!
...
@@ -9390,7 +9331,7 @@ class basic_json
...
@@ -9390,7 +9331,7 @@ class basic_json
*/
*/
constexpr
bool
is_object
()
const
noexcept
constexpr
bool
is_object
()
const
noexcept
{
{
return
m_type
==
value_t
::
object
;
return
(
m_type
==
value_t
::
object
)
;
}
}
/*!
/*!
...
@@ -9412,7 +9353,7 @@ class basic_json
...
@@ -9412,7 +9353,7 @@ class basic_json
*/
*/
constexpr
bool
is_array
()
const
noexcept
constexpr
bool
is_array
()
const
noexcept
{
{
return
m_type
==
value_t
::
array
;
return
(
m_type
==
value_t
::
array
)
;
}
}
/*!
/*!
...
@@ -9434,7 +9375,7 @@ class basic_json
...
@@ -9434,7 +9375,7 @@ class basic_json
*/
*/
constexpr
bool
is_string
()
const
noexcept
constexpr
bool
is_string
()
const
noexcept
{
{
return
m_type
==
value_t
::
string
;
return
(
m_type
==
value_t
::
string
)
;
}
}
/*!
/*!
...
@@ -9461,7 +9402,7 @@ class basic_json
...
@@ -9461,7 +9402,7 @@ class basic_json
*/
*/
constexpr
bool
is_discarded
()
const
noexcept
constexpr
bool
is_discarded
()
const
noexcept
{
{
return
m_type
==
value_t
::
discarded
;
return
(
m_type
==
value_t
::
discarded
)
;
}
}
/*!
/*!
...
@@ -9497,12 +9438,12 @@ class basic_json
...
@@ -9497,12 +9438,12 @@ class basic_json
/// get a boolean (explicit)
/// get a boolean (explicit)
boolean_t
get_impl
(
boolean_t
*
/*unused*/
)
const
boolean_t
get_impl
(
boolean_t
*
/*unused*/
)
const
{
{
if
(
is_boolean
(
))
if
(
JSON_LIKELY
(
is_boolean
()
))
{
{
return
m_value
.
boolean
;
return
m_value
.
boolean
;
}
}
JSON_THROW
(
type_error
::
create
(
302
,
"type must be boolean, but is "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
302
,
"type must be boolean, but is "
+
std
::
string
(
type_name
()
)));
}
}
/// get a pointer to the value (object)
/// get a pointer to the value (object)
...
@@ -9603,18 +9544,15 @@ class basic_json
...
@@ -9603,18 +9544,15 @@ class basic_json
template
<
typename
ReferenceType
,
typename
ThisType
>
template
<
typename
ReferenceType
,
typename
ThisType
>
static
ReferenceType
get_ref_impl
(
ThisType
&
obj
)
static
ReferenceType
get_ref_impl
(
ThisType
&
obj
)
{
{
// helper type
using
PointerType
=
typename
std
::
add_pointer
<
ReferenceType
>::
type
;
// delegate the call to get_ptr<>()
// delegate the call to get_ptr<>()
auto
ptr
=
obj
.
template
get_ptr
<
PointerT
ype
>
();
auto
ptr
=
obj
.
template
get_ptr
<
typename
std
::
add_pointer
<
ReferenceType
>::
t
ype
>
();
if
(
ptr
!=
nullptr
)
if
(
JSON_LIKELY
(
ptr
!=
nullptr
)
)
{
{
return
*
ptr
;
return
*
ptr
;
}
}
JSON_THROW
(
type_error
::
create
(
303
,
"incompatible ReferenceType for get_ref, actual type is "
+
obj
.
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
303
,
"incompatible ReferenceType for get_ref, actual type is "
+
std
::
string
(
obj
.
type_name
()
)));
}
}
public
:
public
:
...
@@ -10010,7 +9948,7 @@ class basic_json
...
@@ -10010,7 +9948,7 @@ class basic_json
reference
at
(
size_type
idx
)
reference
at
(
size_type
idx
)
{
{
// at only works for arrays
// at only works for arrays
if
(
is_array
(
))
if
(
JSON_LIKELY
(
is_array
()
))
{
{
JSON_TRY
JSON_TRY
{
{
...
@@ -10024,7 +9962,7 @@ class basic_json
...
@@ -10024,7 +9962,7 @@ class basic_json
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
304
,
"cannot use at() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
304
,
"cannot use at() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -10057,7 +9995,7 @@ class basic_json
...
@@ -10057,7 +9995,7 @@ class basic_json
const_reference
at
(
size_type
idx
)
const
const_reference
at
(
size_type
idx
)
const
{
{
// at only works for arrays
// at only works for arrays
if
(
is_array
(
))
if
(
JSON_LIKELY
(
is_array
()
))
{
{
JSON_TRY
JSON_TRY
{
{
...
@@ -10071,7 +10009,7 @@ class basic_json
...
@@ -10071,7 +10009,7 @@ class basic_json
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
304
,
"cannot use at() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
304
,
"cannot use at() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -10108,7 +10046,7 @@ class basic_json
...
@@ -10108,7 +10046,7 @@ class basic_json
reference
at
(
const
typename
object_t
::
key_type
&
key
)
reference
at
(
const
typename
object_t
::
key_type
&
key
)
{
{
// at only works for objects
// at only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
JSON_TRY
JSON_TRY
{
{
...
@@ -10122,7 +10060,7 @@ class basic_json
...
@@ -10122,7 +10060,7 @@ class basic_json
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
304
,
"cannot use at() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
304
,
"cannot use at() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -10159,7 +10097,7 @@ class basic_json
...
@@ -10159,7 +10097,7 @@ class basic_json
const_reference
at
(
const
typename
object_t
::
key_type
&
key
)
const
const_reference
at
(
const
typename
object_t
::
key_type
&
key
)
const
{
{
// at only works for objects
// at only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
JSON_TRY
JSON_TRY
{
{
...
@@ -10173,7 +10111,7 @@ class basic_json
...
@@ -10173,7 +10111,7 @@ class basic_json
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
304
,
"cannot use at() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
304
,
"cannot use at() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -10213,7 +10151,7 @@ class basic_json
...
@@ -10213,7 +10151,7 @@ class basic_json
}
}
// operator[] only works for arrays
// operator[] only works for arrays
if
(
is_array
(
))
if
(
JSON_LIKELY
(
is_array
()
))
{
{
// fill up array with null values if given idx is outside range
// fill up array with null values if given idx is outside range
if
(
idx
>=
m_value
.
array
->
size
())
if
(
idx
>=
m_value
.
array
->
size
())
...
@@ -10226,7 +10164,7 @@ class basic_json
...
@@ -10226,7 +10164,7 @@ class basic_json
return
m_value
.
array
->
operator
[](
idx
);
return
m_value
.
array
->
operator
[](
idx
);
}
}
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -10251,12 +10189,12 @@ class basic_json
...
@@ -10251,12 +10189,12 @@ class basic_json
const_reference
operator
[](
size_type
idx
)
const
const_reference
operator
[](
size_type
idx
)
const
{
{
// const operator[] only works for arrays
// const operator[] only works for arrays
if
(
is_array
(
))
if
(
JSON_LIKELY
(
is_array
()
))
{
{
return
m_value
.
array
->
operator
[](
idx
);
return
m_value
.
array
->
operator
[](
idx
);
}
}
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -10297,12 +10235,12 @@ class basic_json
...
@@ -10297,12 +10235,12 @@ class basic_json
}
}
// operator[] only works for objects
// operator[] only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
return
m_value
.
object
->
operator
[](
key
);
return
m_value
.
object
->
operator
[](
key
);
}
}
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -10338,13 +10276,13 @@ class basic_json
...
@@ -10338,13 +10276,13 @@ class basic_json
const_reference
operator
[](
const
typename
object_t
::
key_type
&
key
)
const
const_reference
operator
[](
const
typename
object_t
::
key_type
&
key
)
const
{
{
// const operator[] only works for objects
// const operator[] only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
assert
(
m_value
.
object
->
find
(
key
)
!=
m_value
.
object
->
end
());
assert
(
m_value
.
object
->
find
(
key
)
!=
m_value
.
object
->
end
());
return
m_value
.
object
->
find
(
key
)
->
second
;
return
m_value
.
object
->
find
(
key
)
->
second
;
}
}
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -10386,12 +10324,12 @@ class basic_json
...
@@ -10386,12 +10324,12 @@ class basic_json
}
}
// at only works for objects
// at only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
return
m_value
.
object
->
operator
[](
key
);
return
m_value
.
object
->
operator
[](
key
);
}
}
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -10428,13 +10366,13 @@ class basic_json
...
@@ -10428,13 +10366,13 @@ class basic_json
const_reference
operator
[](
T
*
key
)
const
const_reference
operator
[](
T
*
key
)
const
{
{
// at only works for objects
// at only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
assert
(
m_value
.
object
->
find
(
key
)
!=
m_value
.
object
->
end
());
assert
(
m_value
.
object
->
find
(
key
)
!=
m_value
.
object
->
end
());
return
m_value
.
object
->
find
(
key
)
->
second
;
return
m_value
.
object
->
find
(
key
)
->
second
;
}
}
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
305
,
"cannot use operator[] with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -10490,7 +10428,7 @@ class basic_json
...
@@ -10490,7 +10428,7 @@ class basic_json
ValueType
value
(
const
typename
object_t
::
key_type
&
key
,
ValueType
default_value
)
const
ValueType
value
(
const
typename
object_t
::
key_type
&
key
,
ValueType
default_value
)
const
{
{
// at only works for objects
// at only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
// if key is found, return value and given default value otherwise
// if key is found, return value and given default value otherwise
const
auto
it
=
find
(
key
);
const
auto
it
=
find
(
key
);
...
@@ -10503,7 +10441,7 @@ class basic_json
...
@@ -10503,7 +10441,7 @@ class basic_json
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
306
,
"cannot use value() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
306
,
"cannot use value() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -10562,7 +10500,7 @@ class basic_json
...
@@ -10562,7 +10500,7 @@ class basic_json
ValueType
value
(
const
json_pointer
&
ptr
,
ValueType
default_value
)
const
ValueType
value
(
const
json_pointer
&
ptr
,
ValueType
default_value
)
const
{
{
// at only works for objects
// at only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
// if pointer resolves a value, return it or use default value
// if pointer resolves a value, return it or use default value
JSON_TRY
JSON_TRY
...
@@ -10575,7 +10513,7 @@ class basic_json
...
@@ -10575,7 +10513,7 @@ class basic_json
}
}
}
}
JSON_THROW
(
type_error
::
create
(
306
,
"cannot use value() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
306
,
"cannot use value() with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -10726,7 +10664,7 @@ class basic_json
...
@@ -10726,7 +10664,7 @@ class basic_json
IteratorType
erase
(
IteratorType
pos
)
IteratorType
erase
(
IteratorType
pos
)
{
{
// make sure iterator fits the current value
// make sure iterator fits the current value
if
(
this
!=
pos
.
m_object
)
if
(
JSON_UNLIKELY
(
this
!=
pos
.
m_object
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
}
}
...
@@ -10741,7 +10679,7 @@ class basic_json
...
@@ -10741,7 +10679,7 @@ class basic_json
case
value_t
:
:
number_unsigned
:
case
value_t
:
:
number_unsigned
:
case
value_t
:
:
string
:
case
value_t
:
:
string
:
{
{
if
(
not
pos
.
m_it
.
primitive_iterator
.
is_begin
(
))
if
(
JSON_UNLIKELY
(
not
pos
.
m_it
.
primitive_iterator
.
is_begin
()
))
{
{
JSON_THROW
(
invalid_iterator
::
create
(
205
,
"iterator out of range"
));
JSON_THROW
(
invalid_iterator
::
create
(
205
,
"iterator out of range"
));
}
}
...
@@ -10773,7 +10711,7 @@ class basic_json
...
@@ -10773,7 +10711,7 @@ class basic_json
default
:
default
:
{
{
JSON_THROW
(
type_error
::
create
(
307
,
"cannot use erase() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
307
,
"cannot use erase() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -10833,7 +10771,7 @@ class basic_json
...
@@ -10833,7 +10771,7 @@ class basic_json
IteratorType
erase
(
IteratorType
first
,
IteratorType
last
)
IteratorType
erase
(
IteratorType
first
,
IteratorType
last
)
{
{
// make sure iterator fits the current value
// make sure iterator fits the current value
if
(
this
!=
first
.
m_object
or
this
!=
last
.
m_object
)
if
(
JSON_UNLIKELY
(
this
!=
first
.
m_object
or
this
!=
last
.
m_object
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
203
,
"iterators do not fit current value"
));
JSON_THROW
(
invalid_iterator
::
create
(
203
,
"iterators do not fit current value"
));
}
}
...
@@ -10848,7 +10786,8 @@ class basic_json
...
@@ -10848,7 +10786,8 @@ class basic_json
case
value_t
:
:
number_unsigned
:
case
value_t
:
:
number_unsigned
:
case
value_t
:
:
string
:
case
value_t
:
:
string
:
{
{
if
(
not
first
.
m_it
.
primitive_iterator
.
is_begin
()
or
not
last
.
m_it
.
primitive_iterator
.
is_end
())
if
(
JSON_LIKELY
(
not
first
.
m_it
.
primitive_iterator
.
is_begin
()
or
not
last
.
m_it
.
primitive_iterator
.
is_end
()))
{
{
JSON_THROW
(
invalid_iterator
::
create
(
204
,
"iterators out of range"
));
JSON_THROW
(
invalid_iterator
::
create
(
204
,
"iterators out of range"
));
}
}
...
@@ -10882,7 +10821,7 @@ class basic_json
...
@@ -10882,7 +10821,7 @@ class basic_json
default
:
default
:
{
{
JSON_THROW
(
type_error
::
create
(
307
,
"cannot use erase() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
307
,
"cannot use erase() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -10921,12 +10860,12 @@ class basic_json
...
@@ -10921,12 +10860,12 @@ class basic_json
size_type
erase
(
const
typename
object_t
::
key_type
&
key
)
size_type
erase
(
const
typename
object_t
::
key_type
&
key
)
{
{
// this erase only works for objects
// this erase only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
return
m_value
.
object
->
erase
(
key
);
return
m_value
.
object
->
erase
(
key
);
}
}
JSON_THROW
(
type_error
::
create
(
307
,
"cannot use erase() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
307
,
"cannot use erase() with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -10956,9 +10895,9 @@ class basic_json
...
@@ -10956,9 +10895,9 @@ class basic_json
void
erase
(
const
size_type
idx
)
void
erase
(
const
size_type
idx
)
{
{
// this erase only works for arrays
// this erase only works for arrays
if
(
is_array
(
))
if
(
JSON_LIKELY
(
is_array
()
))
{
{
if
(
idx
>=
size
(
))
if
(
JSON_UNLIKELY
(
idx
>=
size
()
))
{
{
JSON_THROW
(
out_of_range
::
create
(
401
,
"array index "
+
std
::
to_string
(
idx
)
+
" is out of range"
));
JSON_THROW
(
out_of_range
::
create
(
401
,
"array index "
+
std
::
to_string
(
idx
)
+
" is out of range"
));
}
}
...
@@ -10967,7 +10906,7 @@ class basic_json
...
@@ -10967,7 +10906,7 @@ class basic_json
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
307
,
"cannot use erase() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
307
,
"cannot use erase() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -11681,9 +11620,9 @@ class basic_json
...
@@ -11681,9 +11620,9 @@ class basic_json
void
push_back
(
basic_json
&&
val
)
void
push_back
(
basic_json
&&
val
)
{
{
// push_back only works for null objects or arrays
// push_back only works for null objects or arrays
if
(
not
(
is_null
()
or
is_array
(
)))
if
(
JSON_UNLIKELY
(
not
(
is_null
()
or
is_array
()
)))
{
{
JSON_THROW
(
type_error
::
create
(
308
,
"cannot use push_back() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
308
,
"cannot use push_back() with "
+
std
::
string
(
type_name
()
)));
}
}
// transform null object into an array
// transform null object into an array
...
@@ -11717,9 +11656,9 @@ class basic_json
...
@@ -11717,9 +11656,9 @@ class basic_json
void
push_back
(
const
basic_json
&
val
)
void
push_back
(
const
basic_json
&
val
)
{
{
// push_back only works for null objects or arrays
// push_back only works for null objects or arrays
if
(
not
(
is_null
()
or
is_array
(
)))
if
(
JSON_UNLIKELY
(
not
(
is_null
()
or
is_array
()
)))
{
{
JSON_THROW
(
type_error
::
create
(
308
,
"cannot use push_back() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
308
,
"cannot use push_back() with "
+
std
::
string
(
type_name
()
)));
}
}
// transform null object into an array
// transform null object into an array
...
@@ -11767,9 +11706,9 @@ class basic_json
...
@@ -11767,9 +11706,9 @@ class basic_json
void
push_back
(
const
typename
object_t
::
value_type
&
val
)
void
push_back
(
const
typename
object_t
::
value_type
&
val
)
{
{
// push_back only works for null objects or objects
// push_back only works for null objects or objects
if
(
not
(
is_null
()
or
is_object
(
)))
if
(
JSON_UNLIKELY
(
not
(
is_null
()
or
is_object
()
)))
{
{
JSON_THROW
(
type_error
::
create
(
308
,
"cannot use push_back() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
308
,
"cannot use push_back() with "
+
std
::
string
(
type_name
()
)));
}
}
// transform null object into an object
// transform null object into an object
...
@@ -11867,9 +11806,9 @@ class basic_json
...
@@ -11867,9 +11806,9 @@ class basic_json
void
emplace_back
(
Args
&&
...
args
)
void
emplace_back
(
Args
&&
...
args
)
{
{
// emplace_back only works for null objects or arrays
// emplace_back only works for null objects or arrays
if
(
not
(
is_null
()
or
is_array
(
)))
if
(
JSON_UNLIKELY
(
not
(
is_null
()
or
is_array
()
)))
{
{
JSON_THROW
(
type_error
::
create
(
311
,
"cannot use emplace_back() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
311
,
"cannot use emplace_back() with "
+
std
::
string
(
type_name
()
)));
}
}
// transform null object into an array
// transform null object into an array
...
@@ -11915,9 +11854,9 @@ class basic_json
...
@@ -11915,9 +11854,9 @@ class basic_json
std
::
pair
<
iterator
,
bool
>
emplace
(
Args
&&
...
args
)
std
::
pair
<
iterator
,
bool
>
emplace
(
Args
&&
...
args
)
{
{
// emplace only works for null objects or arrays
// emplace only works for null objects or arrays
if
(
not
(
is_null
()
or
is_object
(
)))
if
(
JSON_UNLIKELY
(
not
(
is_null
()
or
is_object
()
)))
{
{
JSON_THROW
(
type_error
::
create
(
311
,
"cannot use emplace() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
311
,
"cannot use emplace() with "
+
std
::
string
(
type_name
()
)));
}
}
// transform null object into an object
// transform null object into an object
...
@@ -11963,10 +11902,10 @@ class basic_json
...
@@ -11963,10 +11902,10 @@ class basic_json
iterator
insert
(
const_iterator
pos
,
const
basic_json
&
val
)
iterator
insert
(
const_iterator
pos
,
const
basic_json
&
val
)
{
{
// insert only works for arrays
// insert only works for arrays
if
(
is_array
(
))
if
(
JSON_LIKELY
(
is_array
()
))
{
{
// check if iterator pos fits to this JSON value
// check if iterator pos fits to this JSON value
if
(
pos
.
m_object
!=
this
)
if
(
JSON_UNLIKELY
(
pos
.
m_object
!=
this
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
}
}
...
@@ -11977,7 +11916,7 @@ class basic_json
...
@@ -11977,7 +11916,7 @@ class basic_json
return
result
;
return
result
;
}
}
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -12016,10 +11955,10 @@ class basic_json
...
@@ -12016,10 +11955,10 @@ class basic_json
iterator
insert
(
const_iterator
pos
,
size_type
cnt
,
const
basic_json
&
val
)
iterator
insert
(
const_iterator
pos
,
size_type
cnt
,
const
basic_json
&
val
)
{
{
// insert only works for arrays
// insert only works for arrays
if
(
is_array
(
))
if
(
JSON_LIKELY
(
is_array
()
))
{
{
// check if iterator pos fits to this JSON value
// check if iterator pos fits to this JSON value
if
(
pos
.
m_object
!=
this
)
if
(
JSON_UNLIKELY
(
pos
.
m_object
!=
this
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
}
}
...
@@ -12030,7 +11969,7 @@ class basic_json
...
@@ -12030,7 +11969,7 @@ class basic_json
return
result
;
return
result
;
}
}
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
std
::
string
(
type_name
()
)));
}
}
/*!
/*!
...
@@ -12066,24 +12005,24 @@ class basic_json
...
@@ -12066,24 +12005,24 @@ class basic_json
iterator
insert
(
const_iterator
pos
,
const_iterator
first
,
const_iterator
last
)
iterator
insert
(
const_iterator
pos
,
const_iterator
first
,
const_iterator
last
)
{
{
// insert only works for arrays
// insert only works for arrays
if
(
not
is_array
(
))
if
(
JSON_UNLIKELY
(
not
is_array
()
))
{
{
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
std
::
string
(
type_name
()
)));
}
}
// check if iterator pos fits to this JSON value
// check if iterator pos fits to this JSON value
if
(
pos
.
m_object
!=
this
)
if
(
JSON_UNLIKELY
(
pos
.
m_object
!=
this
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
}
}
// check if range iterators belong to the same JSON object
// check if range iterators belong to the same JSON object
if
(
first
.
m_object
!=
last
.
m_object
)
if
(
JSON_UNLIKELY
(
first
.
m_object
!=
last
.
m_object
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
210
,
"iterators do not fit"
));
JSON_THROW
(
invalid_iterator
::
create
(
210
,
"iterators do not fit"
));
}
}
if
(
first
.
m_object
==
this
or
last
.
m_object
==
this
)
if
(
JSON_UNLIKELY
(
first
.
m_object
==
this
or
last
.
m_object
==
this
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
211
,
"passed iterators may not belong to container"
));
JSON_THROW
(
invalid_iterator
::
create
(
211
,
"passed iterators may not belong to container"
));
}
}
...
@@ -12124,13 +12063,13 @@ class basic_json
...
@@ -12124,13 +12063,13 @@ class basic_json
iterator
insert
(
const_iterator
pos
,
std
::
initializer_list
<
basic_json
>
ilist
)
iterator
insert
(
const_iterator
pos
,
std
::
initializer_list
<
basic_json
>
ilist
)
{
{
// insert only works for arrays
// insert only works for arrays
if
(
not
is_array
(
))
if
(
JSON_UNLIKELY
(
not
is_array
()
))
{
{
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
std
::
string
(
type_name
()
)));
}
}
// check if iterator pos fits to this JSON value
// check if iterator pos fits to this JSON value
if
(
pos
.
m_object
!=
this
)
if
(
JSON_UNLIKELY
(
pos
.
m_object
!=
this
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterator does not fit current value"
));
}
}
...
@@ -12167,19 +12106,20 @@ class basic_json
...
@@ -12167,19 +12106,20 @@ class basic_json
void
insert
(
const_iterator
first
,
const_iterator
last
)
void
insert
(
const_iterator
first
,
const_iterator
last
)
{
{
// insert only works for objects
// insert only works for objects
if
(
not
is_object
(
))
if
(
JSON_UNLIKELY
(
not
is_object
()
))
{
{
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
309
,
"cannot use insert() with "
+
std
::
string
(
type_name
()
)));
}
}
// check if range iterators belong to the same JSON object
// check if range iterators belong to the same JSON object
if
(
first
.
m_object
!=
last
.
m_object
)
if
(
JSON_UNLIKELY
(
first
.
m_object
!=
last
.
m_object
)
)
{
{
JSON_THROW
(
invalid_iterator
::
create
(
210
,
"iterators do not fit"
));
JSON_THROW
(
invalid_iterator
::
create
(
210
,
"iterators do not fit"
));
}
}
// passed iterators must belong to objects
// passed iterators must belong to objects
if
(
not
first
.
m_object
->
is_object
()
or
not
first
.
m_object
->
is_object
())
if
(
JSON_UNLIKELY
(
not
first
.
m_object
->
is_object
()
or
not
first
.
m_object
->
is_object
()))
{
{
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterators first and last must point to objects"
));
JSON_THROW
(
invalid_iterator
::
create
(
202
,
"iterators first and last must point to objects"
));
}
}
...
@@ -12239,13 +12179,13 @@ class basic_json
...
@@ -12239,13 +12179,13 @@ class basic_json
void
swap
(
array_t
&
other
)
void
swap
(
array_t
&
other
)
{
{
// swap only works for arrays
// swap only works for arrays
if
(
is_array
(
))
if
(
JSON_LIKELY
(
is_array
()
))
{
{
std
::
swap
(
*
(
m_value
.
array
),
other
);
std
::
swap
(
*
(
m_value
.
array
),
other
);
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
310
,
"cannot use swap() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
310
,
"cannot use swap() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -12272,13 +12212,13 @@ class basic_json
...
@@ -12272,13 +12212,13 @@ class basic_json
void
swap
(
object_t
&
other
)
void
swap
(
object_t
&
other
)
{
{
// swap only works for objects
// swap only works for objects
if
(
is_object
(
))
if
(
JSON_LIKELY
(
is_object
()
))
{
{
std
::
swap
(
*
(
m_value
.
object
),
other
);
std
::
swap
(
*
(
m_value
.
object
),
other
);
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
310
,
"cannot use swap() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
310
,
"cannot use swap() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -12305,13 +12245,13 @@ class basic_json
...
@@ -12305,13 +12245,13 @@ class basic_json
void
swap
(
string_t
&
other
)
void
swap
(
string_t
&
other
)
{
{
// swap only works for strings
// swap only works for strings
if
(
is_string
(
))
if
(
JSON_LIKELY
(
is_string
()
))
{
{
std
::
swap
(
*
(
m_value
.
string
),
other
);
std
::
swap
(
*
(
m_value
.
string
),
other
);
}
}
else
else
{
{
JSON_THROW
(
type_error
::
create
(
310
,
"cannot use swap() with "
+
type_name
(
)));
JSON_THROW
(
type_error
::
create
(
310
,
"cannot use swap() with "
+
std
::
string
(
type_name
()
)));
}
}
}
}
...
@@ -12360,11 +12300,11 @@ class basic_json
...
@@ -12360,11 +12300,11 @@ class basic_json
{
{
case
value_t
:
:
array
:
case
value_t
:
:
array
:
{
{
return
*
lhs
.
m_value
.
array
==
*
rhs
.
m_value
.
array
;
return
(
*
lhs
.
m_value
.
array
==
*
rhs
.
m_value
.
array
)
;
}
}
case
value_t
:
:
object
:
case
value_t
:
:
object
:
{
{
return
*
lhs
.
m_value
.
object
==
*
rhs
.
m_value
.
object
;
return
(
*
lhs
.
m_value
.
object
==
*
rhs
.
m_value
.
object
)
;
}
}
case
value_t
:
:
null
:
case
value_t
:
:
null
:
{
{
...
@@ -12372,23 +12312,23 @@ class basic_json
...
@@ -12372,23 +12312,23 @@ class basic_json
}
}
case
value_t
:
:
string
:
case
value_t
:
:
string
:
{
{
return
*
lhs
.
m_value
.
string
==
*
rhs
.
m_value
.
string
;
return
(
*
lhs
.
m_value
.
string
==
*
rhs
.
m_value
.
string
)
;
}
}
case
value_t
:
:
boolean
:
case
value_t
:
:
boolean
:
{
{
return
lhs
.
m_value
.
boolean
==
rhs
.
m_value
.
boolean
;
return
(
lhs
.
m_value
.
boolean
==
rhs
.
m_value
.
boolean
)
;
}
}
case
value_t
:
:
number_integer
:
case
value_t
:
:
number_integer
:
{
{
return
lhs
.
m_value
.
number_integer
==
rhs
.
m_value
.
number_integer
;
return
(
lhs
.
m_value
.
number_integer
==
rhs
.
m_value
.
number_integer
)
;
}
}
case
value_t
:
:
number_unsigned
:
case
value_t
:
:
number_unsigned
:
{
{
return
lhs
.
m_value
.
number_unsigned
==
rhs
.
m_value
.
number_unsigned
;
return
(
lhs
.
m_value
.
number_unsigned
==
rhs
.
m_value
.
number_unsigned
)
;
}
}
case
value_t
:
:
number_float
:
case
value_t
:
:
number_float
:
{
{
return
lhs
.
m_value
.
number_float
==
rhs
.
m_value
.
number_float
;
return
(
lhs
.
m_value
.
number_float
==
rhs
.
m_value
.
number_float
)
;
}
}
default
:
default
:
{
{
...
@@ -12398,27 +12338,27 @@ class basic_json
...
@@ -12398,27 +12338,27 @@ class basic_json
}
}
else
if
(
lhs_type
==
value_t
::
number_integer
and
rhs_type
==
value_t
::
number_float
)
else
if
(
lhs_type
==
value_t
::
number_integer
and
rhs_type
==
value_t
::
number_float
)
{
{
return
static_cast
<
number_float_t
>
(
lhs
.
m_value
.
number_integer
)
==
rhs
.
m_value
.
number_float
;
return
(
static_cast
<
number_float_t
>
(
lhs
.
m_value
.
number_integer
)
==
rhs
.
m_value
.
number_float
)
;
}
}
else
if
(
lhs_type
==
value_t
::
number_float
and
rhs_type
==
value_t
::
number_integer
)
else
if
(
lhs_type
==
value_t
::
number_float
and
rhs_type
==
value_t
::
number_integer
)
{
{
return
lhs
.
m_value
.
number_float
==
static_cast
<
number_float_t
>
(
rhs
.
m_value
.
number_integer
);
return
(
lhs
.
m_value
.
number_float
==
static_cast
<
number_float_t
>
(
rhs
.
m_value
.
number_integer
)
);
}
}
else
if
(
lhs_type
==
value_t
::
number_unsigned
and
rhs_type
==
value_t
::
number_float
)
else
if
(
lhs_type
==
value_t
::
number_unsigned
and
rhs_type
==
value_t
::
number_float
)
{
{
return
static_cast
<
number_float_t
>
(
lhs
.
m_value
.
number_unsigned
)
==
rhs
.
m_value
.
number_float
;
return
(
static_cast
<
number_float_t
>
(
lhs
.
m_value
.
number_unsigned
)
==
rhs
.
m_value
.
number_float
)
;
}
}
else
if
(
lhs_type
==
value_t
::
number_float
and
rhs_type
==
value_t
::
number_unsigned
)
else
if
(
lhs_type
==
value_t
::
number_float
and
rhs_type
==
value_t
::
number_unsigned
)
{
{
return
lhs
.
m_value
.
number_float
==
static_cast
<
number_float_t
>
(
rhs
.
m_value
.
number_unsigned
);
return
(
lhs
.
m_value
.
number_float
==
static_cast
<
number_float_t
>
(
rhs
.
m_value
.
number_unsigned
)
);
}
}
else
if
(
lhs_type
==
value_t
::
number_unsigned
and
rhs_type
==
value_t
::
number_integer
)
else
if
(
lhs_type
==
value_t
::
number_unsigned
and
rhs_type
==
value_t
::
number_integer
)
{
{
return
static_cast
<
number_integer_t
>
(
lhs
.
m_value
.
number_unsigned
)
==
rhs
.
m_value
.
number_integer
;
return
(
static_cast
<
number_integer_t
>
(
lhs
.
m_value
.
number_unsigned
)
==
rhs
.
m_value
.
number_integer
)
;
}
}
else
if
(
lhs_type
==
value_t
::
number_integer
and
rhs_type
==
value_t
::
number_unsigned
)
else
if
(
lhs_type
==
value_t
::
number_integer
and
rhs_type
==
value_t
::
number_unsigned
)
{
{
return
lhs
.
m_value
.
number_integer
==
static_cast
<
number_integer_t
>
(
rhs
.
m_value
.
number_unsigned
);
return
(
lhs
.
m_value
.
number_integer
==
static_cast
<
number_integer_t
>
(
rhs
.
m_value
.
number_unsigned
)
);
}
}
return
false
;
return
false
;
...
@@ -13041,9 +12981,9 @@ class basic_json
...
@@ -13041,9 +12981,9 @@ class basic_json
@liveexample{The following code exemplifies `type_name()` for all JSON
@liveexample{The following code exemplifies `type_name()` for all JSON
types.,type_name}
types.,type_name}
@since version 1.0.0, public since 2.1.0
@since version 1.0.0, public since 2.1.0
, const char* since 3.0.0
*/
*/
std
::
string
type_name
()
const
const
char
*
type_name
()
const
{
{
{
{
switch
(
m_type
)
switch
(
m_type
)
...
@@ -13804,7 +13744,7 @@ class basic_json
...
@@ -13804,7 +13744,7 @@ class basic_json
else
else
{
{
const
auto
idx
=
std
::
stoi
(
last_path
);
const
auto
idx
=
std
::
stoi
(
last_path
);
if
(
static_cast
<
size_type
>
(
idx
)
>
parent
.
size
(
))
if
(
JSON_UNLIKELY
(
static_cast
<
size_type
>
(
idx
)
>
parent
.
size
()
))
{
{
// avoid undefined behavior
// avoid undefined behavior
JSON_THROW
(
out_of_range
::
create
(
401
,
"array index "
+
std
::
to_string
(
idx
)
+
" is out of range"
));
JSON_THROW
(
out_of_range
::
create
(
401
,
"array index "
+
std
::
to_string
(
idx
)
+
" is out of range"
));
...
@@ -13839,7 +13779,7 @@ class basic_json
...
@@ -13839,7 +13779,7 @@ class basic_json
{
{
// perform range check
// perform range check
auto
it
=
parent
.
find
(
last_path
);
auto
it
=
parent
.
find
(
last_path
);
if
(
it
!=
parent
.
end
(
))
if
(
JSON_LIKELY
(
it
!=
parent
.
end
()
))
{
{
parent
.
erase
(
it
);
parent
.
erase
(
it
);
}
}
...
@@ -13856,7 +13796,7 @@ class basic_json
...
@@ -13856,7 +13796,7 @@ class basic_json
};
};
// type check: top level value must be an array
// type check: top level value must be an array
if
(
not
json_patch
.
is_array
(
))
if
(
JSON_UNLIKELY
(
not
json_patch
.
is_array
()
))
{
{
JSON_THROW
(
parse_error
::
create
(
104
,
0
,
"JSON patch must be an array of objects"
));
JSON_THROW
(
parse_error
::
create
(
104
,
0
,
"JSON patch must be an array of objects"
));
}
}
...
@@ -13876,13 +13816,13 @@ class basic_json
...
@@ -13876,13 +13816,13 @@ class basic_json
const
auto
error_msg
=
(
op
==
"op"
)
?
"operation"
:
"operation '"
+
op
+
"'"
;
const
auto
error_msg
=
(
op
==
"op"
)
?
"operation"
:
"operation '"
+
op
+
"'"
;
// check if desired value is present
// check if desired value is present
if
(
it
==
val
.
m_value
.
object
->
end
(
))
if
(
JSON_UNLIKELY
(
it
==
val
.
m_value
.
object
->
end
()
))
{
{
JSON_THROW
(
parse_error
::
create
(
105
,
0
,
error_msg
+
" must have member '"
+
member
+
"'"
));
JSON_THROW
(
parse_error
::
create
(
105
,
0
,
error_msg
+
" must have member '"
+
member
+
"'"
));
}
}
// check if result is of type string
// check if result is of type string
if
(
string_type
and
not
it
->
second
.
is_string
(
))
if
(
JSON_UNLIKELY
(
string_type
and
not
it
->
second
.
is_string
()
))
{
{
JSON_THROW
(
parse_error
::
create
(
105
,
0
,
error_msg
+
" must have string member '"
+
member
+
"'"
));
JSON_THROW
(
parse_error
::
create
(
105
,
0
,
error_msg
+
" must have string member '"
+
member
+
"'"
));
}
}
...
@@ -13892,7 +13832,7 @@ class basic_json
...
@@ -13892,7 +13832,7 @@ class basic_json
};
};
// type check: every element of the array must be an object
// type check: every element of the array must be an object
if
(
not
val
.
is_object
(
))
if
(
JSON_UNLIKELY
(
not
val
.
is_object
()
))
{
{
JSON_THROW
(
parse_error
::
create
(
104
,
0
,
"JSON patch must be an array of objects"
));
JSON_THROW
(
parse_error
::
create
(
104
,
0
,
"JSON patch must be an array of objects"
));
}
}
...
@@ -13965,7 +13905,7 @@ class basic_json
...
@@ -13965,7 +13905,7 @@ class basic_json
}
}
// throw an exception if test fails
// throw an exception if test fails
if
(
not
success
)
if
(
JSON_UNLIKELY
(
not
success
)
)
{
{
JSON_THROW
(
other_error
::
create
(
501
,
"unsuccessful: "
+
val
.
dump
()));
JSON_THROW
(
other_error
::
create
(
501
,
"unsuccessful: "
+
val
.
dump
()));
}
}
...
@@ -14017,8 +13957,7 @@ class basic_json
...
@@ -14017,8 +13957,7 @@ class basic_json
@since version 2.0.0
@since version 2.0.0
*/
*/
static
basic_json
diff
(
const
basic_json
&
source
,
static
basic_json
diff
(
const
basic_json
&
source
,
const
basic_json
&
target
,
const
basic_json
&
target
,
const
std
::
string
&
path
=
""
)
const
std
::
string
&
path
=
""
)
{
{
// the patch
// the patch
...
@@ -14035,9 +13974,7 @@ class basic_json
...
@@ -14035,9 +13974,7 @@ class basic_json
// different types: replace value
// different types: replace value
result
.
push_back
(
result
.
push_back
(
{
{
{
"op"
,
"replace"
},
{
"op"
,
"replace"
},
{
"path"
,
path
},
{
"value"
,
target
}
{
"path"
,
path
},
{
"value"
,
target
}
});
});
}
}
else
else
...
@@ -14107,8 +14044,7 @@ class basic_json
...
@@ -14107,8 +14044,7 @@ class basic_json
// found a key that is not in o -> remove it
// found a key that is not in o -> remove it
result
.
push_back
(
object
(
result
.
push_back
(
object
(
{
{
{
"op"
,
"remove"
},
{
"op"
,
"remove"
},
{
"path"
,
path
+
"/"
+
key
}
{
"path"
,
path
+
"/"
+
key
}
}));
}));
}
}
}
}
...
@@ -14122,8 +14058,7 @@ class basic_json
...
@@ -14122,8 +14058,7 @@ class basic_json
const
auto
key
=
json_pointer
::
escape
(
it
.
key
());
const
auto
key
=
json_pointer
::
escape
(
it
.
key
());
result
.
push_back
(
result
.
push_back
(
{
{
{
"op"
,
"add"
},
{
"op"
,
"add"
},
{
"path"
,
path
+
"/"
+
key
},
{
"path"
,
path
+
"/"
+
key
},
{
"value"
,
it
.
value
()}
{
"value"
,
it
.
value
()}
});
});
}
}
...
@@ -14137,9 +14072,7 @@ class basic_json
...
@@ -14137,9 +14072,7 @@ class basic_json
// both primitive type: replace value
// both primitive type: replace value
result
.
push_back
(
result
.
push_back
(
{
{
{
"op"
,
"replace"
},
{
"op"
,
"replace"
},
{
"path"
,
path
},
{
"value"
,
target
}
{
"path"
,
path
},
{
"value"
,
target
}
});
});
break
;
break
;
}
}
...
@@ -14177,8 +14110,8 @@ json_pointer::get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const
...
@@ -14177,8 +14110,8 @@ json_pointer::get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const
using
size_type
=
typename
NLOHMANN_BASIC_JSON_TPL
::
size_type
;
using
size_type
=
typename
NLOHMANN_BASIC_JSON_TPL
::
size_type
;
auto
result
=
&
j
;
auto
result
=
&
j
;
// in case no reference tokens exist, return a reference to the
// in case no reference tokens exist, return a reference to the
JSON value
//
JSON value
j which will be overwritten by a primitive value
// j which will be overwritten by a primitive value
for
(
const
auto
&
reference_token
:
reference_tokens
)
for
(
const
auto
&
reference_token
:
reference_tokens
)
{
{
switch
(
result
->
m_type
)
switch
(
result
->
m_type
)
...
@@ -14210,23 +14143,20 @@ json_pointer::get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const
...
@@ -14210,23 +14143,20 @@ json_pointer::get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const
// create an entry in the array
// create an entry in the array
JSON_TRY
JSON_TRY
{
{
result
=
&
result
->
operator
[](
result
=
&
result
->
operator
[](
static_cast
<
size_type
>
(
std
::
stoi
(
reference_token
)));
static_cast
<
size_type
>
(
std
::
stoi
(
reference_token
)));
}
}
JSON_CATCH
(
std
::
invalid_argument
&
)
JSON_CATCH
(
std
::
invalid_argument
&
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
JSON_THROW
(
detail
::
parse_error
::
create
(
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
}
}
break
;
break
;
}
}
/*
/*
The following code is only reached if there exists a
The following code is only reached if there exists a reference
reference token _and_ the current value is primitive. In
token _and_ the current value is primitive. In this case, we have
this case, we have an error situation, because primitive
an error situation, because primitive values may only occur as
values may only occur as single value; that is, with an
single value; that is, with an empty list of reference tokens.
empty list of reference tokens.
*/
*/
default
:
default
:
{
{
...
@@ -14256,16 +14186,10 @@ json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14256,16 +14186,10 @@ json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
return
(
x
>=
'0'
and
x
<=
'9'
);
return
(
x
>=
'0'
and
x
<=
'9'
);
});
});
// change value to array for numbers or "-" or to object
// change value to array for numbers or "-" or to object otherwise
// otherwise
*
ptr
=
(
nums
or
reference_token
==
"-"
)
if
(
nums
or
reference_token
==
"-"
)
?
detail
::
value_t
::
array
{
:
detail
::
value_t
::
object
;
*
ptr
=
detail
::
value_t
::
array
;
}
else
{
*
ptr
=
detail
::
value_t
::
object
;
}
}
}
switch
(
ptr
->
m_type
)
switch
(
ptr
->
m_type
)
...
@@ -14280,7 +14204,7 @@ json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14280,7 +14204,7 @@ json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
case
detail
:
:
value_t
::
array
:
case
detail
:
:
value_t
::
array
:
{
{
// error condition (cf. RFC 6901, Sect. 4)
// error condition (cf. RFC 6901, Sect. 4)
if
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
if
(
JSON_UNLIKELY
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
106
,
0
,
JSON_THROW
(
detail
::
parse_error
::
create
(
106
,
0
,
"array index '"
+
reference_token
+
"array index '"
+
reference_token
+
...
@@ -14302,8 +14226,7 @@ json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14302,8 +14226,7 @@ json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
}
}
JSON_CATCH
(
std
::
invalid_argument
&
)
JSON_CATCH
(
std
::
invalid_argument
&
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
JSON_THROW
(
detail
::
parse_error
::
create
(
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
}
}
}
}
break
;
break
;
...
@@ -14311,8 +14234,7 @@ json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14311,8 +14234,7 @@ json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
default
:
default
:
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
JSON_THROW
(
detail
::
out_of_range
::
create
(
404
,
"unresolved reference token '"
+
reference_token
+
"'"
));
404
,
"unresolved reference token '"
+
reference_token
+
"'"
));
}
}
}
}
}
}
...
@@ -14338,17 +14260,16 @@ json_pointer::get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14338,17 +14260,16 @@ json_pointer::get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const
case
detail
:
:
value_t
::
array
:
case
detail
:
:
value_t
::
array
:
{
{
if
(
reference_token
==
"-"
)
if
(
JSON_UNLIKELY
(
reference_token
==
"-"
)
)
{
{
// "-" always fails the range check
// "-" always fails the range check
JSON_THROW
(
detail
::
out_of_range
::
create
(
JSON_THROW
(
detail
::
out_of_range
::
create
(
402
,
402
,
"array index '-' ("
+
std
::
to_string
(
ptr
->
m_value
.
array
->
size
())
+
"array index '-' ("
+
std
::
to_string
(
ptr
->
m_value
.
array
->
size
())
+
") is out of range"
));
") is out of range"
));
}
}
// error condition (cf. RFC 6901, Sect. 4)
// error condition (cf. RFC 6901, Sect. 4)
if
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
if
(
JSON_UNLIKELY
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
106
,
0
,
JSON_THROW
(
detail
::
parse_error
::
create
(
106
,
0
,
"array index '"
+
reference_token
+
"array index '"
+
reference_token
+
...
@@ -14362,16 +14283,14 @@ json_pointer::get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14362,16 +14283,14 @@ json_pointer::get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const
}
}
JSON_CATCH
(
std
::
invalid_argument
&
)
JSON_CATCH
(
std
::
invalid_argument
&
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
JSON_THROW
(
detail
::
parse_error
::
create
(
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
}
}
break
;
break
;
}
}
default
:
default
:
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
JSON_THROW
(
detail
::
out_of_range
::
create
(
404
,
"unresolved reference token '"
+
reference_token
+
"'"
));
404
,
"unresolved reference token '"
+
reference_token
+
"'"
));
}
}
}
}
}
}
...
@@ -14397,17 +14316,16 @@ json_pointer::get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14397,17 +14316,16 @@ json_pointer::get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
case
detail
:
:
value_t
::
array
:
case
detail
:
:
value_t
::
array
:
{
{
if
(
reference_token
==
"-"
)
if
(
JSON_UNLIKELY
(
reference_token
==
"-"
)
)
{
{
// "-" cannot be used for const access
// "-" cannot be used for const access
JSON_THROW
(
detail
::
out_of_range
::
create
(
JSON_THROW
(
detail
::
out_of_range
::
create
(
402
,
402
,
"array index '-' ("
+
std
::
to_string
(
ptr
->
m_value
.
array
->
size
())
+
"array index '-' ("
+
std
::
to_string
(
ptr
->
m_value
.
array
->
size
())
+
") is out of range"
));
") is out of range"
));
}
}
// error condition (cf. RFC 6901, Sect. 4)
// error condition (cf. RFC 6901, Sect. 4)
if
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
if
(
JSON_UNLIKELY
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
106
,
0
,
JSON_THROW
(
detail
::
parse_error
::
create
(
106
,
0
,
"array index '"
+
reference_token
+
"array index '"
+
reference_token
+
...
@@ -14422,16 +14340,14 @@ json_pointer::get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14422,16 +14340,14 @@ json_pointer::get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
}
}
JSON_CATCH
(
std
::
invalid_argument
&
)
JSON_CATCH
(
std
::
invalid_argument
&
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
JSON_THROW
(
detail
::
parse_error
::
create
(
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
}
}
break
;
break
;
}
}
default
:
default
:
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
JSON_THROW
(
detail
::
out_of_range
::
create
(
404
,
"unresolved reference token '"
+
reference_token
+
"'"
));
404
,
"unresolved reference token '"
+
reference_token
+
"'"
));
}
}
}
}
}
}
...
@@ -14457,17 +14373,16 @@ json_pointer::get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14457,17 +14373,16 @@ json_pointer::get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
case
detail
:
:
value_t
::
array
:
case
detail
:
:
value_t
::
array
:
{
{
if
(
reference_token
==
"-"
)
if
(
JSON_UNLIKELY
(
reference_token
==
"-"
)
)
{
{
// "-" always fails the range check
// "-" always fails the range check
JSON_THROW
(
detail
::
out_of_range
::
create
(
JSON_THROW
(
detail
::
out_of_range
::
create
(
402
,
402
,
"array index '-' ("
+
std
::
to_string
(
ptr
->
m_value
.
array
->
size
())
+
"array index '-' ("
+
std
::
to_string
(
ptr
->
m_value
.
array
->
size
())
+
") is out of range"
));
") is out of range"
));
}
}
// error condition (cf. RFC 6901, Sect. 4)
// error condition (cf. RFC 6901, Sect. 4)
if
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
if
(
JSON_UNLIKELY
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
106
,
0
,
JSON_THROW
(
detail
::
parse_error
::
create
(
106
,
0
,
"array index '"
+
reference_token
+
"array index '"
+
reference_token
+
...
@@ -14481,16 +14396,14 @@ json_pointer::get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
...
@@ -14481,16 +14396,14 @@ json_pointer::get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
}
}
JSON_CATCH
(
std
::
invalid_argument
&
)
JSON_CATCH
(
std
::
invalid_argument
&
)
{
{
JSON_THROW
(
detail
::
parse_error
::
create
(
JSON_THROW
(
detail
::
parse_error
::
create
(
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
109
,
0
,
"array index '"
+
reference_token
+
"' is not a number"
));
}
}
break
;
break
;
}
}
default
:
default
:
{
{
JSON_THROW
(
detail
::
out_of_range
::
create
(
JSON_THROW
(
detail
::
out_of_range
::
create
(
404
,
"unresolved reference token '"
+
reference_token
+
"'"
));
404
,
"unresolved reference token '"
+
reference_token
+
"'"
));
}
}
}
}
}
}
...
@@ -14536,8 +14449,7 @@ void json_pointer::flatten(const std::string& reference_string,
...
@@ -14536,8 +14449,7 @@ void json_pointer::flatten(const std::string& reference_string,
// iterate object and use keys as reference string
// iterate object and use keys as reference string
for
(
const
auto
&
element
:
*
value
.
m_value
.
object
)
for
(
const
auto
&
element
:
*
value
.
m_value
.
object
)
{
{
flatten
(
reference_string
+
"/"
+
escape
(
element
.
first
),
element
.
second
,
flatten
(
reference_string
+
"/"
+
escape
(
element
.
first
),
element
.
second
,
result
);
result
);
}
}
}
}
break
;
break
;
...
@@ -14556,7 +14468,7 @@ NLOHMANN_BASIC_JSON_TPL_DECLARATION
...
@@ -14556,7 +14468,7 @@ NLOHMANN_BASIC_JSON_TPL_DECLARATION
NLOHMANN_BASIC_JSON_TPL
NLOHMANN_BASIC_JSON_TPL
json_pointer
::
unflatten
(
const
NLOHMANN_BASIC_JSON_TPL
&
value
)
json_pointer
::
unflatten
(
const
NLOHMANN_BASIC_JSON_TPL
&
value
)
{
{
if
(
not
value
.
is_object
(
))
if
(
JSON_UNLIKELY
(
not
value
.
is_object
()
))
{
{
JSON_THROW
(
detail
::
type_error
::
create
(
314
,
"only objects can be unflattened"
));
JSON_THROW
(
detail
::
type_error
::
create
(
314
,
"only objects can be unflattened"
));
}
}
...
@@ -14566,16 +14478,15 @@ json_pointer::unflatten(const NLOHMANN_BASIC_JSON_TPL& value)
...
@@ -14566,16 +14478,15 @@ json_pointer::unflatten(const NLOHMANN_BASIC_JSON_TPL& value)
// iterate the JSON object values
// iterate the JSON object values
for
(
const
auto
&
element
:
*
value
.
m_value
.
object
)
for
(
const
auto
&
element
:
*
value
.
m_value
.
object
)
{
{
if
(
not
element
.
second
.
is_primitive
(
))
if
(
JSON_UNLIKELY
(
not
element
.
second
.
is_primitive
()
))
{
{
JSON_THROW
(
detail
::
type_error
::
create
(
315
,
"values in object must be primitive"
));
JSON_THROW
(
detail
::
type_error
::
create
(
315
,
"values in object must be primitive"
));
}
}
// assign value to reference pointed to by JSON pointer; Note
// assign value to reference pointed to by JSON pointer; Note that if
// that if the JSON pointer is "" (i.e., points to the whole
// the JSON pointer is "" (i.e., points to the whole value), function
// value), function get_and_create returns a reference to
// get_and_create returns a reference to result itself. An assignment
// result itself. An assignment will then create a primitive
// will then create a primitive value.
// value.
json_pointer
(
element
.
first
).
get_and_create
(
result
)
=
element
.
second
;
json_pointer
(
element
.
first
).
get_and_create
(
result
)
=
element
.
second
;
}
}
...
@@ -14584,12 +14495,12 @@ json_pointer::unflatten(const NLOHMANN_BASIC_JSON_TPL& value)
...
@@ -14584,12 +14495,12 @@ json_pointer::unflatten(const NLOHMANN_BASIC_JSON_TPL& value)
inline
bool
operator
==
(
json_pointer
const
&
lhs
,
json_pointer
const
&
rhs
)
noexcept
inline
bool
operator
==
(
json_pointer
const
&
lhs
,
json_pointer
const
&
rhs
)
noexcept
{
{
return
lhs
.
reference_tokens
==
rhs
.
reference_tokens
;
return
(
lhs
.
reference_tokens
==
rhs
.
reference_tokens
)
;
}
}
inline
bool
operator
!=
(
json_pointer
const
&
lhs
,
json_pointer
const
&
rhs
)
noexcept
inline
bool
operator
!=
(
json_pointer
const
&
lhs
,
json_pointer
const
&
rhs
)
noexcept
{
{
return
!
(
lhs
==
rhs
);
return
not
(
lhs
==
rhs
);
}
}
}
// namespace nlohmann
}
// namespace nlohmann
...
@@ -14634,7 +14545,7 @@ struct hash<nlohmann::json>
...
@@ -14634,7 +14545,7 @@ struct hash<nlohmann::json>
};
};
/// specialization for std::less<value_t>
/// specialization for std::less<value_t>
template
<>
template
<>
struct
less
<::
nlohmann
::
detail
::
value_t
>
struct
less
<::
nlohmann
::
detail
::
value_t
>
{
{
/*!
/*!
...
...
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