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
a34e011e
Unverified
Commit
a34e011e
authored
Apr 25, 2021
by
Niels Lohmann
Committed by
GitHub
Apr 25, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2576 from AnthonyVH/non_default_constructable_stl_containers
Add support for deserialization of STL containers of non-default constructable types (fixes #2574).
parents
f1600cd2
2b865131
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
782 additions
and
376 deletions
+782
-376
adl_serializer.hpp
include/nlohmann/adl_serializer.hpp
+33
-9
from_json.hpp
include/nlohmann/detail/conversions/from_json.hpp
+64
-13
identity_tag.hpp
include/nlohmann/detail/meta/identity_tag.hpp
+10
-0
type_traits.hpp
include/nlohmann/detail/meta/type_traits.hpp
+57
-19
json.hpp
include/nlohmann/json.hpp
+179
-147
json.hpp
single_include/nlohmann/json.hpp
+346
-188
unit-regression2.cpp
test/src/unit-regression2.cpp
+93
-0
No files found.
include/nlohmann/adl_serializer.hpp
View file @
a34e011e
#pragma once
#pragma once
#include <type_traits>
#include <utility>
#include <utility>
#include <nlohmann/detail/conversions/from_json.hpp>
#include <nlohmann/detail/conversions/from_json.hpp>
#include <nlohmann/detail/conversions/to_json.hpp>
#include <nlohmann/detail/conversions/to_json.hpp>
#include <nlohmann/detail/meta/identity_tag.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
namespace
nlohmann
namespace
nlohmann
{
{
template
<
typename
,
typename
>
template
<
typename
ValueType
,
typename
>
struct
adl_serializer
struct
adl_serializer
{
{
/*!
/*!
...
@@ -17,11 +20,13 @@ struct adl_serializer
...
@@ -17,11 +20,13 @@ struct adl_serializer
This function is usually called by the `get()` function of the
This function is usually called by the `get()` function of the
@ref basic_json class (either explicit or via conversion operators).
@ref basic_json class (either explicit or via conversion operators).
@note This function is chosen for default-constructible value types.
@param[in] j JSON value to read from
@param[in] j JSON value to read from
@param[in,out] val value to write to
@param[in,out] val value to write to
*/
*/
template
<
typename
BasicJsonType
,
typename
ValueType
>
template
<
typename
BasicJsonType
,
typename
TargetType
=
ValueType
>
static
auto
from_json
(
BasicJsonType
&&
j
,
Value
Type
&
val
)
noexcept
(
static
auto
from_json
(
BasicJsonType
&&
j
,
Target
Type
&
val
)
noexcept
(
noexcept
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
val
)))
noexcept
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
val
)))
->
decltype
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
val
),
void
())
->
decltype
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
val
),
void
())
{
{
...
@@ -29,6 +34,26 @@ struct adl_serializer
...
@@ -29,6 +34,26 @@ struct adl_serializer
}
}
/*!
/*!
@brief convert a JSON value to any value type
This function is usually called by the `get()` function of the
@ref basic_json class (either explicit or via conversion operators).
@note This function is chosen for value types which are not default-constructible.
@param[in] j JSON value to read from
@return copy of the JSON value, converted to @a ValueType
*/
template
<
typename
BasicJsonType
,
typename
TargetType
=
ValueType
>
static
auto
from_json
(
BasicJsonType
&&
j
)
noexcept
(
noexcept
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
detail
::
identity_tag
<
TargetType
>
{})))
->
decltype
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
detail
::
identity_tag
<
TargetType
>
{}))
{
return
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
detail
::
identity_tag
<
TargetType
>
{});
}
/*!
@brief convert any value type to a JSON value
@brief convert any value type to a JSON value
This function is usually called by the constructors of the @ref basic_json
This function is usually called by the constructors of the @ref basic_json
...
@@ -37,13 +62,12 @@ struct adl_serializer
...
@@ -37,13 +62,12 @@ struct adl_serializer
@param[in,out] j JSON value to write to
@param[in,out] j JSON value to write to
@param[in] val value to read from
@param[in] val value to read from
*/
*/
template
<
typename
BasicJsonType
,
typename
ValueType
>
template
<
typename
BasicJsonType
,
typename
TargetType
=
ValueType
>
static
auto
to_json
(
BasicJsonType
&
j
,
ValueType
&&
val
)
noexcept
(
static
auto
to_json
(
BasicJsonType
&
j
,
TargetType
&&
val
)
noexcept
(
noexcept
(
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Value
Type
>
(
val
))))
noexcept
(
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Target
Type
>
(
val
))))
->
decltype
(
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Value
Type
>
(
val
)),
void
())
->
decltype
(
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Target
Type
>
(
val
)),
void
())
{
{
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Value
Type
>
(
val
));
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Target
Type
>
(
val
));
}
}
};
};
}
// namespace nlohmann
}
// namespace nlohmann
include/nlohmann/detail/conversions/from_json.hpp
View file @
a34e011e
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/identity_tag.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp>
#include <nlohmann/detail/value_t.hpp>
...
@@ -187,7 +188,10 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
...
@@ -187,7 +188,10 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
}
}
}
}
template
<
typename
BasicJsonType
,
typename
ConstructibleArrayType
>
template
<
typename
BasicJsonType
,
typename
ConstructibleArrayType
,
enable_if_t
<
std
::
is_assignable
<
ConstructibleArrayType
&
,
ConstructibleArrayType
>::
value
,
int
>
=
0
>
auto
from_json_array_impl
(
const
BasicJsonType
&
j
,
ConstructibleArrayType
&
arr
,
priority_tag
<
1
>
/*unused*/
)
auto
from_json_array_impl
(
const
BasicJsonType
&
j
,
ConstructibleArrayType
&
arr
,
priority_tag
<
1
>
/*unused*/
)
->
decltype
(
->
decltype
(
arr
.
reserve
(
std
::
declval
<
typename
ConstructibleArrayType
::
size_type
>
()),
arr
.
reserve
(
std
::
declval
<
typename
ConstructibleArrayType
::
size_type
>
()),
...
@@ -208,7 +212,10 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
...
@@ -208,7 +212,10 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
arr
=
std
::
move
(
ret
);
arr
=
std
::
move
(
ret
);
}
}
template
<
typename
BasicJsonType
,
typename
ConstructibleArrayType
>
template
<
typename
BasicJsonType
,
typename
ConstructibleArrayType
,
enable_if_t
<
std
::
is_assignable
<
ConstructibleArrayType
&
,
ConstructibleArrayType
>::
value
,
int
>
=
0
>
void
from_json_array_impl
(
const
BasicJsonType
&
j
,
ConstructibleArrayType
&
arr
,
void
from_json_array_impl
(
const
BasicJsonType
&
j
,
ConstructibleArrayType
&
arr
,
priority_tag
<
0
>
/*unused*/
)
priority_tag
<
0
>
/*unused*/
)
{
{
...
@@ -247,6 +254,25 @@ void())
...
@@ -247,6 +254,25 @@ void())
from_json_array_impl
(
j
,
arr
,
priority_tag
<
3
>
{});
from_json_array_impl
(
j
,
arr
,
priority_tag
<
3
>
{});
}
}
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
...
Idx
>
std
::
array
<
T
,
sizeof
...(
Idx
)
>
from_json_inplace_array_impl
(
BasicJsonType
&&
j
,
identity_tag
<
std
::
array
<
T
,
sizeof
...(
Idx
)
>>
/*unused*/
,
index_sequence
<
Idx
...
>
/*unused*/
)
{
return
{
{
std
::
forward
<
BasicJsonType
>
(
j
).
at
(
Idx
).
template
get
<
T
>
()...
}
};
}
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
N
>
auto
from_json
(
BasicJsonType
&&
j
,
identity_tag
<
std
::
array
<
T
,
N
>>
tag
)
->
decltype
(
from_json_inplace_array_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
tag
,
make_index_sequence
<
N
>
{}))
{
if
(
JSON_HEDLEY_UNLIKELY
(
!
j
.
is_array
()))
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
std
::
string
(
j
.
type_name
()),
j
));
}
return
from_json_inplace_array_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
tag
,
make_index_sequence
<
N
>
{});
}
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
binary_t
&
bin
)
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
binary_t
&
bin
)
{
{
...
@@ -322,22 +348,47 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
...
@@ -322,22 +348,47 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
}
}
}
}
template
<
typename
BasicJsonType
,
typename
...
Args
,
std
::
size_t
...
Idx
>
std
::
tuple
<
Args
...
>
from_json_tuple_impl_base
(
BasicJsonType
&&
j
,
index_sequence
<
Idx
...
>
/*unused*/
)
{
return
std
::
make_tuple
(
std
::
forward
<
BasicJsonType
>
(
j
).
at
(
Idx
).
template
get
<
Args
>
()...);
}
template
<
typename
BasicJsonType
,
class
A1
,
class
A2
>
std
::
pair
<
A1
,
A2
>
from_json_tuple_impl
(
BasicJsonType
&&
j
,
identity_tag
<
std
::
pair
<
A1
,
A2
>>
/*unused*/
,
priority_tag
<
0
>
/*unused*/
)
{
return
{
std
::
forward
<
BasicJsonType
>
(
j
).
at
(
0
).
template
get
<
A1
>
(),
std
::
forward
<
BasicJsonType
>
(
j
).
at
(
1
).
template
get
<
A2
>
()};
}
template
<
typename
BasicJsonType
,
typename
A1
,
typename
A2
>
template
<
typename
BasicJsonType
,
typename
A1
,
typename
A2
>
void
from_json
(
const
BasicJsonType
&
j
,
std
::
pair
<
A1
,
A2
>&
p
)
void
from_json
_tuple_impl
(
BasicJsonType
&&
j
,
std
::
pair
<
A1
,
A2
>&
p
,
priority_tag
<
1
>
/*unused*/
)
{
{
p
=
{
j
.
at
(
0
).
template
get
<
A1
>
(),
j
.
at
(
1
).
template
get
<
A2
>
()}
;
p
=
from_json_tuple_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
identity_tag
<
std
::
pair
<
A1
,
A2
>>
{},
priority_tag
<
0
>
{})
;
}
}
template
<
typename
BasicJsonType
,
typename
Tuple
,
std
::
size_t
...
Idx
>
template
<
typename
BasicJsonType
,
typename
...
Args
>
void
from_json_tuple_impl
(
const
BasicJsonType
&
j
,
Tuple
&
t
,
index_sequence
<
Idx
...
>
/*unused*/
)
std
::
tuple
<
Args
...
>
from_json_tuple_impl
(
BasicJsonType
&&
j
,
identity_tag
<
std
::
tuple
<
Args
...
>>
/*unused*/
,
priority_tag
<
2
>
/*unused*/
)
{
{
t
=
std
::
make_tuple
(
j
.
at
(
Idx
).
template
get
<
typename
std
::
tuple_element
<
Idx
,
Tuple
>::
type
>
()...
);
return
from_json_tuple_impl_base
<
BasicJsonType
,
Args
...
>
(
std
::
forward
<
BasicJsonType
>
(
j
),
index_sequence_for
<
Args
...
>
{}
);
}
}
template
<
typename
BasicJsonType
,
typename
...
Args
>
template
<
typename
BasicJsonType
,
typename
...
Args
>
void
from_json
(
const
BasicJsonType
&
j
,
std
::
tuple
<
Args
...
>&
t
)
void
from_json
_tuple_impl
(
BasicJsonType
&&
j
,
std
::
tuple
<
Args
...
>&
t
,
priority_tag
<
3
>
/*unused*/
)
{
{
from_json_tuple_impl
(
j
,
t
,
index_sequence_for
<
Args
...
>
{});
t
=
from_json_tuple_impl_base
<
BasicJsonType
,
Args
...
>
(
std
::
forward
<
BasicJsonType
>
(
j
),
index_sequence_for
<
Args
...
>
{});
}
template
<
typename
BasicJsonType
,
typename
TupleRelated
>
auto
from_json
(
BasicJsonType
&&
j
,
TupleRelated
&&
t
)
->
decltype
(
from_json_tuple_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
std
::
forward
<
TupleRelated
>
(
t
),
priority_tag
<
3
>
{}))
{
if
(
JSON_HEDLEY_UNLIKELY
(
!
j
.
is_array
()))
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
std
::
string
(
j
.
type_name
()),
j
));
}
return
from_json_tuple_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
std
::
forward
<
TupleRelated
>
(
t
),
priority_tag
<
3
>
{});
}
}
template
<
typename
BasicJsonType
,
typename
Key
,
typename
Value
,
typename
Compare
,
typename
Allocator
,
template
<
typename
BasicJsonType
,
typename
Key
,
typename
Value
,
typename
Compare
,
typename
Allocator
,
...
@@ -383,11 +434,11 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
...
@@ -383,11 +434,11 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
struct
from_json_fn
struct
from_json_fn
{
{
template
<
typename
BasicJsonType
,
typename
T
>
template
<
typename
BasicJsonType
,
typename
T
>
auto
operator
()(
const
BasicJsonType
&
j
,
T
&
val
)
const
auto
operator
()(
const
BasicJsonType
&
j
,
T
&
&
val
)
const
noexcept
(
noexcept
(
from_json
(
j
,
val
)))
noexcept
(
noexcept
(
from_json
(
j
,
std
::
forward
<
T
>
(
val
)
)))
->
decltype
(
from_json
(
j
,
val
),
void
(
))
->
decltype
(
from_json
(
j
,
std
::
forward
<
T
>
(
val
)
))
{
{
return
from_json
(
j
,
val
);
return
from_json
(
j
,
std
::
forward
<
T
>
(
val
)
);
}
}
};
};
}
// namespace detail
}
// namespace detail
...
...
include/nlohmann/detail/meta/identity_tag.hpp
0 → 100644
View file @
a34e011e
#pragma once
namespace
nlohmann
{
namespace
detail
{
// dispatching helper struct
template
<
class
T
>
struct
identity_tag
{};
}
// namespace detail
}
// namespace nlohmann
include/nlohmann/detail/meta/type_traits.hpp
View file @
a34e011e
...
@@ -106,8 +106,7 @@ struct is_getable
...
@@ -106,8 +106,7 @@ struct is_getable
};
};
template
<
typename
BasicJsonType
,
typename
T
>
template
<
typename
BasicJsonType
,
typename
T
>
struct
has_from_json
<
BasicJsonType
,
T
,
struct
has_from_json
<
BasicJsonType
,
T
,
enable_if_t
<
!
is_basic_json
<
T
>::
value
>>
enable_if_t
<
!
is_basic_json
<
T
>::
value
>>
{
{
using
serializer
=
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
;
using
serializer
=
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
;
...
@@ -151,6 +150,52 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
...
@@ -151,6 +150,52 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
// is_ functions //
// is_ functions //
///////////////////
///////////////////
// https://en.cppreference.com/w/cpp/types/conjunction
template
<
class
...
>
struct
conjunction
:
std
::
true_type
{
};
template
<
class
B1
>
struct
conjunction
<
B1
>
:
B1
{
};
template
<
class
B1
,
class
...
Bn
>
struct
conjunction
<
B1
,
Bn
...
>
:
std
::
conditional
<
bool
(
B1
::
value
),
conjunction
<
Bn
...
>
,
B1
>::
type
{};
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
template
<
typename
T
>
struct
is_default_constructible
:
std
::
is_default_constructible
<
T
>
{};
template
<
typename
T1
,
typename
T2
>
struct
is_default_constructible
<
std
::
pair
<
T1
,
T2
>>
:
conjunction
<
is_default_constructible
<
T1
>
,
is_default_constructible
<
T2
>>
{};
template
<
typename
T1
,
typename
T2
>
struct
is_default_constructible
<
const
std
::
pair
<
T1
,
T2
>>
:
conjunction
<
is_default_constructible
<
T1
>
,
is_default_constructible
<
T2
>>
{};
template
<
typename
...
Ts
>
struct
is_default_constructible
<
std
::
tuple
<
Ts
...
>>
:
conjunction
<
is_default_constructible
<
Ts
>
...
>
{};
template
<
typename
...
Ts
>
struct
is_default_constructible
<
const
std
::
tuple
<
Ts
...
>>
:
conjunction
<
is_default_constructible
<
Ts
>
...
>
{};
template
<
typename
T
,
typename
...
Args
>
struct
is_constructible
:
std
::
is_constructible
<
T
,
Args
...
>
{};
template
<
typename
T1
,
typename
T2
>
struct
is_constructible
<
std
::
pair
<
T1
,
T2
>>
:
is_default_constructible
<
std
::
pair
<
T1
,
T2
>>
{};
template
<
typename
T1
,
typename
T2
>
struct
is_constructible
<
const
std
::
pair
<
T1
,
T2
>>
:
is_default_constructible
<
const
std
::
pair
<
T1
,
T2
>>
{};
template
<
typename
...
Ts
>
struct
is_constructible
<
std
::
tuple
<
Ts
...
>>
:
is_default_constructible
<
std
::
tuple
<
Ts
...
>>
{};
template
<
typename
...
Ts
>
struct
is_constructible
<
const
std
::
tuple
<
Ts
...
>>
:
is_default_constructible
<
const
std
::
tuple
<
Ts
...
>>
{};
template
<
typename
T
,
typename
=
void
>
template
<
typename
T
,
typename
=
void
>
struct
is_iterator_traits
:
std
::
false_type
{};
struct
is_iterator_traits
:
std
::
false_type
{};
...
@@ -193,9 +238,9 @@ struct is_compatible_object_type_impl <
...
@@ -193,9 +238,9 @@ struct is_compatible_object_type_impl <
// macOS's is_constructible does not play well with nonesuch...
// macOS's is_constructible does not play well with nonesuch...
static
constexpr
bool
value
=
static
constexpr
bool
value
=
std
::
is_constructible
<
typename
object_t
::
key_type
,
is_constructible
<
typename
object_t
::
key_type
,
typename
CompatibleObjectType
::
key_type
>::
value
&&
typename
CompatibleObjectType
::
key_type
>::
value
&&
std
::
is_constructible
<
typename
object_t
::
mapped_type
,
is_constructible
<
typename
object_t
::
mapped_type
,
typename
CompatibleObjectType
::
mapped_type
>::
value
;
typename
CompatibleObjectType
::
mapped_type
>::
value
;
};
};
...
@@ -216,10 +261,10 @@ struct is_constructible_object_type_impl <
...
@@ -216,10 +261,10 @@ struct is_constructible_object_type_impl <
using
object_t
=
typename
BasicJsonType
::
object_t
;
using
object_t
=
typename
BasicJsonType
::
object_t
;
static
constexpr
bool
value
=
static
constexpr
bool
value
=
(
std
::
is_default_constructible
<
ConstructibleObjectType
>::
value
&&
(
is_default_constructible
<
ConstructibleObjectType
>::
value
&&
(
std
::
is_move_assignable
<
ConstructibleObjectType
>::
value
||
(
std
::
is_move_assignable
<
ConstructibleObjectType
>::
value
||
std
::
is_copy_assignable
<
ConstructibleObjectType
>::
value
)
&&
std
::
is_copy_assignable
<
ConstructibleObjectType
>::
value
)
&&
(
std
::
is_constructible
<
typename
ConstructibleObjectType
::
key_type
,
(
is_constructible
<
typename
ConstructibleObjectType
::
key_type
,
typename
object_t
::
key_type
>::
value
&&
typename
object_t
::
key_type
>::
value
&&
std
::
is_same
<
std
::
is_same
<
typename
object_t
::
mapped_type
,
typename
object_t
::
mapped_type
,
...
@@ -247,7 +292,7 @@ struct is_compatible_string_type_impl <
...
@@ -247,7 +292,7 @@ struct is_compatible_string_type_impl <
value_type_t
,
CompatibleStringType
>::
value
>>
value_type_t
,
CompatibleStringType
>::
value
>>
{
{
static
constexpr
auto
value
=
static
constexpr
auto
value
=
std
::
is_constructible
<
typename
BasicJsonType
::
string_t
,
CompatibleStringType
>::
value
;
is_constructible
<
typename
BasicJsonType
::
string_t
,
CompatibleStringType
>::
value
;
};
};
template
<
typename
BasicJsonType
,
typename
ConstructibleStringType
>
template
<
typename
BasicJsonType
,
typename
ConstructibleStringType
>
...
@@ -265,7 +310,7 @@ struct is_constructible_string_type_impl <
...
@@ -265,7 +310,7 @@ struct is_constructible_string_type_impl <
value_type_t
,
ConstructibleStringType
>::
value
>>
value_type_t
,
ConstructibleStringType
>::
value
>>
{
{
static
constexpr
auto
value
=
static
constexpr
auto
value
=
std
::
is_constructible
<
ConstructibleStringType
,
is_constructible
<
ConstructibleStringType
,
typename
BasicJsonType
::
string_t
>::
value
;
typename
BasicJsonType
::
string_t
>::
value
;
};
};
...
@@ -288,7 +333,7 @@ struct is_compatible_array_type_impl <
...
@@ -288,7 +333,7 @@ struct is_compatible_array_type_impl <
iterator_traits
<
CompatibleArrayType
>>::
value
>>
iterator_traits
<
CompatibleArrayType
>>::
value
>>
{
{
static
constexpr
bool
value
=
static
constexpr
bool
value
=
std
::
is_constructible
<
BasicJsonType
,
is_constructible
<
BasicJsonType
,
typename
CompatibleArrayType
::
value_type
>::
value
;
typename
CompatibleArrayType
::
value_type
>::
value
;
};
};
...
@@ -311,7 +356,7 @@ struct is_constructible_array_type_impl <
...
@@ -311,7 +356,7 @@ struct is_constructible_array_type_impl <
BasicJsonType
,
ConstructibleArrayType
,
BasicJsonType
,
ConstructibleArrayType
,
enable_if_t
<
!
std
::
is_same
<
ConstructibleArrayType
,
enable_if_t
<
!
std
::
is_same
<
ConstructibleArrayType
,
typename
BasicJsonType
::
value_type
>::
value
&&
typename
BasicJsonType
::
value_type
>::
value
&&
std
::
is_default_constructible
<
ConstructibleArrayType
>::
value
&&
is_default_constructible
<
ConstructibleArrayType
>::
value
&&
(
std
::
is_move_assignable
<
ConstructibleArrayType
>::
value
||
(
std
::
is_move_assignable
<
ConstructibleArrayType
>::
value
||
std
::
is_copy_assignable
<
ConstructibleArrayType
>::
value
)
&&
std
::
is_copy_assignable
<
ConstructibleArrayType
>::
value
)
&&
is_detected
<
value_type_t
,
ConstructibleArrayType
>::
value
&&
is_detected
<
value_type_t
,
ConstructibleArrayType
>::
value
&&
...
@@ -355,7 +400,7 @@ struct is_compatible_integer_type_impl <
...
@@ -355,7 +400,7 @@ struct is_compatible_integer_type_impl <
using
CompatibleLimits
=
std
::
numeric_limits
<
CompatibleNumberIntegerType
>
;
using
CompatibleLimits
=
std
::
numeric_limits
<
CompatibleNumberIntegerType
>
;
static
constexpr
auto
value
=
static
constexpr
auto
value
=
std
::
is_constructible
<
RealIntegerType
,
is_constructible
<
RealIntegerType
,
CompatibleNumberIntegerType
>::
value
&&
CompatibleNumberIntegerType
>::
value
&&
CompatibleLimits
::
is_integer
&&
CompatibleLimits
::
is_integer
&&
RealLimits
::
is_signed
==
CompatibleLimits
::
is_signed
;
RealLimits
::
is_signed
==
CompatibleLimits
::
is_signed
;
...
@@ -382,17 +427,10 @@ template<typename BasicJsonType, typename CompatibleType>
...
@@ -382,17 +427,10 @@ template<typename BasicJsonType, typename CompatibleType>
struct
is_compatible_type
struct
is_compatible_type
:
is_compatible_type_impl
<
BasicJsonType
,
CompatibleType
>
{};
:
is_compatible_type_impl
<
BasicJsonType
,
CompatibleType
>
{};
// https://en.cppreference.com/w/cpp/types/conjunction
template
<
class
...
>
struct
conjunction
:
std
::
true_type
{
};
template
<
class
B1
>
struct
conjunction
<
B1
>
:
B1
{
};
template
<
class
B1
,
class
...
Bn
>
struct
conjunction
<
B1
,
Bn
...
>
:
std
::
conditional
<
bool
(
B1
::
value
),
conjunction
<
Bn
...
>
,
B1
>::
type
{};
template
<
typename
T1
,
typename
T2
>
template
<
typename
T1
,
typename
T2
>
struct
is_constructible_tuple
:
std
::
false_type
{};
struct
is_constructible_tuple
:
std
::
false_type
{};
template
<
typename
T1
,
typename
...
Args
>
template
<
typename
T1
,
typename
...
Args
>
struct
is_constructible_tuple
<
T1
,
std
::
tuple
<
Args
...
>>
:
conjunction
<
std
::
is_constructible
<
T1
,
Args
>
...
>
{};
struct
is_constructible_tuple
<
T1
,
std
::
tuple
<
Args
...
>>
:
conjunction
<
is_constructible
<
T1
,
Args
>
...
>
{};
}
// namespace detail
}
// namespace detail
}
// namespace nlohmann
}
// namespace nlohmann
include/nlohmann/json.hpp
View file @
a34e011e
...
@@ -2920,50 +2920,53 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -2920,50 +2920,53 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
/// @{
/// @{
/*!
/*!
@brief get
special-case overload
@brief get
a pointer value (implicit)
This overloads avoids a lot of template boilerplate, it can be seen as th
e
Implicit pointer access to the internally stored JSON value. No copies ar
e
identity method
made.
@tparam BasicJsonType == @ref basic_json
@warning Writing data to the pointee of the result yields an undefined
state.
@return a copy of *this
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
@ref number_unsigned_t, or @ref number_float_t. Enforced by a static
assertion.
@return pointer to the internally stored JSON value if the requested
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@complexity Constant.
@complexity Constant.
@since version 2.1.0
@liveexample{The example below shows how pointers to internal values of a
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
match.,get_ptr}
@since version 1.0.0
*/
*/
template
<
typename
BasicJsonType
,
detail
::
enable_if_t
<
template
<
typename
PointerType
,
typename
std
::
enable_if
<
std
::
is_same
<
typename
std
::
remove_const
<
BasicJsonType
>::
type
,
basic_json_t
>::
value
,
std
::
is_pointer
<
PointerType
>::
value
,
int
>::
type
=
0
>
int
>
=
0
>
auto
get_ptr
()
noexcept
->
decltype
(
std
::
declval
<
basic_json_t
&>
().
get_impl_ptr
(
std
::
declval
<
PointerType
>
()))
basic_json
get
()
const
{
{
return
*
this
;
// delegate the call to get_impl_ptr<>()
return
get_impl_ptr
(
static_cast
<
PointerType
>
(
nullptr
));
}
}
/*!
/*!
@brief get special-case overload
@brief get a pointer value (implicit)
@copydoc get_ptr()
This overloads converts the current @ref basic_json in a different
@ref basic_json type
@tparam BasicJsonType == @ref basic_json
@return a copy of *this, converted into @a BasicJsonType
@complexity Depending on the implementation of the called `from_json()`
method.
@since version 3.2.0
*/
*/
template
<
typename
BasicJsonType
,
detail
::
enable_if_t
<
template
<
typename
PointerType
,
typename
std
::
enable_if
<
!
std
::
is_same
<
BasicJsonType
,
basic_json
>::
value
&&
std
::
is_pointer
<
PointerType
>::
value
&&
detail
::
is_basic_json
<
BasicJsonType
>::
value
,
int
>
=
0
>
std
::
is_const
<
typename
std
::
remove_pointer
<
PointerType
>::
type
>::
value
,
int
>::
type
=
0
>
BasicJsonType
get
()
const
constexpr
auto
get_ptr
()
const
noexcept
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
get_impl_ptr
(
std
::
declval
<
PointerType
>
()))
{
{
return
*
this
;
// delegate the call to get_impl_ptr<>() const
return
get_impl_ptr
(
static_cast
<
PointerType
>
(
nullptr
));
}
}
private
:
/*!
/*!
@brief get a value (explicit)
@brief get a value (explicit)
...
@@ -2987,7 +2990,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -2987,7 +2990,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
- @ref json_serializer<ValueType> does not have a `from_json()` method of
- @ref json_serializer<ValueType> does not have a `from_json()` method of
the form `ValueType from_json(const basic_json&)`
the form `ValueType from_json(const basic_json&)`
@tparam ValueTypeCV the provided value type
@tparam ValueType the returned value type
@tparam ValueType the returned value type
@return copy of the JSON value, converted to @a ValueType
@return copy of the JSON value, converted to @a ValueType
...
@@ -3003,23 +3005,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -3003,23 +3005,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@since version 2.1.0
@since version 2.1.0
*/
*/
template
<
typename
ValueType
CV
,
typename
ValueType
=
detail
::
uncvref_t
<
ValueTypeCV
>
,
template
<
typename
ValueType
,
detail
::
enable_if_t
<
detail
::
enable_if_t
<
!
detail
::
is_basic_json
<
ValueType
>::
value
&&
detail
::
is_default_constructible
<
ValueType
>::
value
&&
detail
::
has_from_json
<
basic_json_t
,
ValueType
>::
value
&&
detail
::
has_from_json
<
basic_json_t
,
ValueType
>::
value
,
!
detail
::
has_non_default_from_json
<
basic_json_t
,
ValueType
>::
value
,
int
>
=
0
>
int
>
=
0
>
ValueType
get
(
)
const
noexcept
(
noexcept
(
ValueType
get
_impl
(
detail
::
priority_tag
<
0
>
/*unused*/
)
const
noexcept
(
noexcept
(
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
std
::
declval
<
ValueType
&>
())))
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
std
::
declval
<
ValueType
&>
())))
{
{
// we cannot static_assert on ValueTypeCV being non-const, because
// there is support for get<const basic_json_t>(), which is why we
// still need the uncvref
static_assert
(
!
std
::
is_reference
<
ValueTypeCV
>::
value
,
"get() cannot be used with reference types, you might want to use get_ref()"
);
static_assert
(
std
::
is_default_constructible
<
ValueType
>::
value
,
"types must be DefaultConstructible when used with get()"
);
ValueType
ret
{};
ValueType
ret
{};
JSONSerializer
<
ValueType
>::
from_json
(
*
this
,
ret
);
JSONSerializer
<
ValueType
>::
from_json
(
*
this
,
ret
);
return
ret
;
return
ret
;
...
@@ -3036,7 +3029,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -3036,7 +3029,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
The function is equivalent to executing
The function is equivalent to executing
@code {.cpp}
@code {.cpp}
return JSONSerializer<ValueType
CV
>::from_json(*this);
return JSONSerializer<ValueType>::from_json(*this);
@endcode
@endcode
This overloads is chosen if:
This overloads is chosen if:
...
@@ -3047,7 +3040,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -3047,7 +3040,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@note If @ref json_serializer<ValueType> has both overloads of
@note If @ref json_serializer<ValueType> has both overloads of
`from_json()`, this one is chosen.
`from_json()`, this one is chosen.
@tparam ValueTypeCV the provided value type
@tparam ValueType the returned value type
@tparam ValueType the returned value type
@return copy of the JSON value, converted to @a ValueType
@return copy of the JSON value, converted to @a ValueType
...
@@ -3056,134 +3048,116 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -3056,134 +3048,116 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@since version 2.1.0
@since version 2.1.0
*/
*/
template
<
typename
ValueType
CV
,
typename
ValueType
=
detail
::
uncvref_t
<
ValueTypeCV
>
,
template
<
typename
ValueType
,
detail
::
enable_if_t
<
!
std
::
is_same
<
basic_json_t
,
ValueType
>::
value
&&
detail
::
enable_if_t
<
detail
::
has_non_default_from_json
<
basic_json_t
,
ValueType
>::
value
,
detail
::
has_non_default_from_json
<
basic_json_t
,
ValueType
>::
value
,
int
>
=
0
>
int
>
=
0
>
ValueType
get
(
)
const
noexcept
(
noexcept
(
ValueType
get
_impl
(
detail
::
priority_tag
<
1
>
/*unused*/
)
const
noexcept
(
noexcept
(
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
())))
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
())))
{
{
static_assert
(
!
std
::
is_reference
<
ValueTypeCV
>::
value
,
"get() cannot be used with reference types, you might want to use get_ref()"
);
return
JSONSerializer
<
ValueType
>::
from_json
(
*
this
);
return
JSONSerializer
<
ValueType
>::
from_json
(
*
this
);
}
}
/*!
/*!
@brief get a value (explicit)
@brief get special-case overload
Explicit type conversion between the JSON value and a compatible value.
The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
`from_json()` method.
The function is equivalent to executing
@code {.cpp}
ValueType v;
JSONSerializer<ValueType>::from_json(*this, v);
@endcode
This overloads is chosen if:
- @a ValueType is not @ref basic_json,
- @ref json_serializer<ValueType> has a `from_json()` method of the form
`void from_json(const basic_json&, ValueType&)`, and
@tparam ValueType the input parameter type.
This overloads converts the current @ref basic_json in a different
@ref basic_json type
@
return the input parameter, allowing chaining calls.
@
tparam BasicJsonType == @ref basic_json
@
throw what @ref json_serializer<ValueType> `from_json()` method throws
@
return a copy of *this, converted into @a BasicJsonType
@liveexample{The example below shows several conversions from JSON values
@complexity Depending on the implementation of the called `from_json()`
to other types. There a few things to note: (1) Floating-point numbers can
method.
be converted to integers\, (2) A JSON array can be converted to a standard
`std::vector<short>`\, (3) A JSON object can be converted to C++
associative containers such as `std::unordered_map<std::string\,
json>`.,get_to}
@since version 3.
3
.0
@since version 3.
2
.0
*/
*/
template
<
typename
Value
Type
,
template
<
typename
BasicJson
Type
,
detail
::
enable_if_t
<
detail
::
enable_if_t
<
!
detail
::
is_basic_json
<
ValueType
>::
value
&&
detail
::
is_basic_json
<
BasicJsonType
>::
value
,
detail
::
has_from_json
<
basic_json_t
,
ValueType
>::
value
,
int
>
=
0
>
int
>
=
0
>
ValueType
&
get_to
(
ValueType
&
v
)
const
noexcept
(
noexcept
(
BasicJsonType
get_impl
(
detail
::
priority_tag
<
2
>
/*unused*/
)
const
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
v
)))
{
{
JSONSerializer
<
ValueType
>::
from_json
(
*
this
,
v
);
return
*
this
;
return
v
;
}
}
// specialization to allow to call get_to with a basic_json value
/*!
// see https://github.com/nlohmann/json/issues/2175
@brief get special-case overload
template
<
typename
ValueType
,
detail
::
enable_if_t
<
This overloads avoids a lot of template boilerplate, it can be seen as the
detail
::
is_basic_json
<
ValueType
>::
value
,
identity method
@tparam BasicJsonType == @ref basic_json
@return a copy of *this
@complexity Constant.
@since version 2.1.0
*/
template
<
typename
BasicJsonType
,
detail
::
enable_if_t
<
std
::
is_same
<
BasicJsonType
,
basic_json_t
>::
value
,
int
>
=
0
>
int
>
=
0
>
ValueType
&
get_to
(
ValueType
&
v
)
const
basic_json
get_impl
(
detail
::
priority_tag
<
3
>
/*unused*/
)
const
{
{
v
=
*
this
;
return
*
this
;
return
v
;
}
}
template
<
/*!
typename
T
,
std
::
size_t
N
,
@brief get a pointer value (explicit)
typename
Array
=
T
(
&
)[
N
],
// NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
@copydoc get()
detail
::
enable_if_t
<
*/
detail
::
has_from_json
<
basic_json_t
,
Array
>::
value
,
int
>
=
0
>
template
<
typename
PointerType
,
Array
get_to
(
T
(
&
v
)[
N
])
const
// NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
detail
::
enable_if_t
<
noexcept
(
noexcept
(
JSONSerializer
<
Array
>::
from_json
(
std
::
is_pointer
<
PointerType
>::
value
,
std
::
declval
<
const
basic_json_t
&>
(),
v
)))
int
>
=
0
>
constexpr
auto
get_impl
(
detail
::
priority_tag
<
4
>
/*unused*/
)
const
noexcept
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
template
get_ptr
<
PointerType
>
())
{
{
JSONSerializer
<
Array
>::
from_json
(
*
this
,
v
);
// delegate the call to get_ptr
return
v
;
return
get_ptr
<
PointerType
>
()
;
}
}
public
:
/*!
/*!
@brief get a
pointer value (im
plicit)
@brief get a
(pointer) value (ex
plicit)
Implicit pointer access to the internally stored JSON value. No copies are
Performs explicit type conversion between the JSON value and a compatible value if required.
made.
@warning Writing data to the pointee of the result yields an undefined
- If the requested type is a pointer to the internally stored JSON value that pointer is returned.
stat
e.
No copies are mad
e.
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
- If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
from the current @ref basic_json.
@ref number_unsigned_t, or @ref number_float_t. Enforced by a static
assertion.
@return pointer to the internally stored JSON value if the requested
- Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
method.
@complexity Constant.
@tparam ValueTypeCV the provided value type
@tparam ValueType the returned value type
@liveexample{The example below shows how pointers to internal values of a
@return copy of the JSON value, converted to @tparam ValueType if necessary
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
match.,get_ptr}
@since version 1.0.0
@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
*/
template
<
typename
PointerType
,
typename
std
::
enable_if
<
std
::
is_pointer
<
PointerType
>::
value
,
int
>::
type
=
0
>
auto
get_ptr
()
noexcept
->
decltype
(
std
::
declval
<
basic_json_t
&>
().
get_impl_ptr
(
std
::
declval
<
PointerType
>
()))
{
// delegate the call to get_impl_ptr<>()
return
get_impl_ptr
(
static_cast
<
PointerType
>
(
nullptr
));
}
/*!
@since version 2.1.0
@brief get a pointer value (implicit)
@copydoc get_ptr()
*/
*/
template
<
typename
PointerType
,
typename
std
::
enable_if
<
template
<
typename
ValueTypeCV
,
typename
ValueType
=
detail
::
uncvref_t
<
ValueTypeCV
>>
std
::
is_pointer
<
PointerType
>::
value
&&
#if defined(JSON_HAS_CPP_14)
std
::
is_const
<
typename
std
::
remove_pointer
<
PointerType
>::
type
>::
value
,
int
>::
type
=
0
>
constexpr
constexpr
auto
get_ptr
()
const
noexcept
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
get_impl_ptr
(
std
::
declval
<
PointerType
>
()))
#endif
auto
get
()
const
noexcept
(
noexcept
(
std
::
declval
<
const
basic_json_t
&>
().
template
get_impl
<
ValueType
>
(
detail
::
priority_tag
<
4
>
{})))
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
template
get_impl
<
ValueType
>
(
detail
::
priority_tag
<
4
>
{}))
{
{
// delegate the call to get_impl_ptr<>() const
// we cannot static_assert on ValueTypeCV being non-const, because
return
get_impl_ptr
(
static_cast
<
PointerType
>
(
nullptr
));
// there is support for get<const basic_json_t>(), which is why we
// still need the uncvref
static_assert
(
!
std
::
is_reference
<
ValueTypeCV
>::
value
,
"get() cannot be used with reference types, you might want to use get_ref()"
);
return
get_impl
<
ValueType
>
(
detail
::
priority_tag
<
4
>
{});
}
}
/*!
/*!
...
@@ -3222,15 +3196,73 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -3222,15 +3196,73 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
}
/*!
/*!
@brief get a pointer value (explicit)
@brief get a value (explicit)
@copydoc get()
Explicit type conversion between the JSON value and a compatible value.
The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
`from_json()` method.
The function is equivalent to executing
@code {.cpp}
ValueType v;
JSONSerializer<ValueType>::from_json(*this, v);
@endcode
This overloads is chosen if:
- @a ValueType is not @ref basic_json,
- @ref json_serializer<ValueType> has a `from_json()` method of the form
`void from_json(const basic_json&, ValueType&)`, and
@tparam ValueType the input parameter type.
@return the input parameter, allowing chaining calls.
@throw what @ref json_serializer<ValueType> `from_json()` method throws
@liveexample{The example below shows several conversions from JSON values
to other types. There a few things to note: (1) Floating-point numbers can
be converted to integers\, (2) A JSON array can be converted to a standard
`std::vector<short>`\, (3) A JSON object can be converted to C++
associative containers such as `std::unordered_map<std::string\,
json>`.,get_to}
@since version 3.3.0
*/
*/
template
<
typename
PointerType
,
typename
std
::
enable_if
<
template
<
typename
ValueType
,
std
::
is_pointer
<
PointerType
>::
value
,
int
>::
type
=
0
>
detail
::
enable_if_t
<
constexpr
auto
get
()
const
noexcept
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
template
get_ptr
<
PointerType
>
())
!
detail
::
is_basic_json
<
ValueType
>::
value
&&
detail
::
has_from_json
<
basic_json_t
,
ValueType
>::
value
,
int
>
=
0
>
ValueType
&
get_to
(
ValueType
&
v
)
const
noexcept
(
noexcept
(
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
v
)))
{
{
// delegate the call to get_ptr
JSONSerializer
<
ValueType
>::
from_json
(
*
this
,
v
);
return
get_ptr
<
PointerType
>
();
return
v
;
}
// specialization to allow to call get_to with a basic_json value
// see https://github.com/nlohmann/json/issues/2175
template
<
typename
ValueType
,
detail
::
enable_if_t
<
detail
::
is_basic_json
<
ValueType
>::
value
,
int
>
=
0
>
ValueType
&
get_to
(
ValueType
&
v
)
const
{
v
=
*
this
;
return
v
;
}
template
<
typename
T
,
std
::
size_t
N
,
typename
Array
=
T
(
&
)[
N
],
// NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
detail
::
enable_if_t
<
detail
::
has_from_json
<
basic_json_t
,
Array
>::
value
,
int
>
=
0
>
Array
get_to
(
T
(
&
v
)[
N
])
const
// NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
noexcept
(
noexcept
(
JSONSerializer
<
Array
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
v
)))
{
JSONSerializer
<
Array
>::
from_json
(
*
this
,
v
);
return
v
;
}
}
/*!
/*!
...
...
single_include/nlohmann/json.hpp
View file @
a34e011e
...
@@ -49,6 +49,7 @@ SOFTWARE.
...
@@ -49,6 +49,7 @@ SOFTWARE.
// #include <nlohmann/adl_serializer.hpp>
// #include <nlohmann/adl_serializer.hpp>
#include <type_traits>
#include <utility>
#include <utility>
// #include <nlohmann/detail/conversions/from_json.hpp>
// #include <nlohmann/detail/conversions/from_json.hpp>
...
@@ -3166,6 +3167,18 @@ constexpr T static_const<T>::value;
...
@@ -3166,6 +3167,18 @@ constexpr T static_const<T>::value;
}
// namespace detail
}
// namespace detail
}
// namespace nlohmann
}
// namespace nlohmann
// #include <nlohmann/detail/meta/identity_tag.hpp>
namespace
nlohmann
{
namespace
detail
{
// dispatching helper struct
template
<
class
T
>
struct
identity_tag
{};
}
// namespace detail
}
// namespace nlohmann
// #include <nlohmann/detail/meta/type_traits.hpp>
// #include <nlohmann/detail/meta/type_traits.hpp>
...
@@ -3483,8 +3496,7 @@ struct is_getable
...
@@ -3483,8 +3496,7 @@ struct is_getable
};
};
template
<
typename
BasicJsonType
,
typename
T
>
template
<
typename
BasicJsonType
,
typename
T
>
struct
has_from_json
<
BasicJsonType
,
T
,
struct
has_from_json
<
BasicJsonType
,
T
,
enable_if_t
<
!
is_basic_json
<
T
>::
value
>>
enable_if_t
<
!
is_basic_json
<
T
>::
value
>>
{
{
using
serializer
=
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
;
using
serializer
=
typename
BasicJsonType
::
template
json_serializer
<
T
,
void
>
;
...
@@ -3528,6 +3540,52 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
...
@@ -3528,6 +3540,52 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
// is_ functions //
// is_ functions //
///////////////////
///////////////////
// https://en.cppreference.com/w/cpp/types/conjunction
template
<
class
...
>
struct
conjunction
:
std
::
true_type
{
};
template
<
class
B1
>
struct
conjunction
<
B1
>
:
B1
{
};
template
<
class
B1
,
class
...
Bn
>
struct
conjunction
<
B1
,
Bn
...
>
:
std
::
conditional
<
bool
(
B1
::
value
),
conjunction
<
Bn
...
>
,
B1
>::
type
{};
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
template
<
typename
T
>
struct
is_default_constructible
:
std
::
is_default_constructible
<
T
>
{};
template
<
typename
T1
,
typename
T2
>
struct
is_default_constructible
<
std
::
pair
<
T1
,
T2
>>
:
conjunction
<
is_default_constructible
<
T1
>
,
is_default_constructible
<
T2
>>
{};
template
<
typename
T1
,
typename
T2
>
struct
is_default_constructible
<
const
std
::
pair
<
T1
,
T2
>>
:
conjunction
<
is_default_constructible
<
T1
>
,
is_default_constructible
<
T2
>>
{};
template
<
typename
...
Ts
>
struct
is_default_constructible
<
std
::
tuple
<
Ts
...
>>
:
conjunction
<
is_default_constructible
<
Ts
>
...
>
{};
template
<
typename
...
Ts
>
struct
is_default_constructible
<
const
std
::
tuple
<
Ts
...
>>
:
conjunction
<
is_default_constructible
<
Ts
>
...
>
{};
template
<
typename
T
,
typename
...
Args
>
struct
is_constructible
:
std
::
is_constructible
<
T
,
Args
...
>
{};
template
<
typename
T1
,
typename
T2
>
struct
is_constructible
<
std
::
pair
<
T1
,
T2
>>
:
is_default_constructible
<
std
::
pair
<
T1
,
T2
>>
{};
template
<
typename
T1
,
typename
T2
>
struct
is_constructible
<
const
std
::
pair
<
T1
,
T2
>>
:
is_default_constructible
<
const
std
::
pair
<
T1
,
T2
>>
{};
template
<
typename
...
Ts
>
struct
is_constructible
<
std
::
tuple
<
Ts
...
>>
:
is_default_constructible
<
std
::
tuple
<
Ts
...
>>
{};
template
<
typename
...
Ts
>
struct
is_constructible
<
const
std
::
tuple
<
Ts
...
>>
:
is_default_constructible
<
const
std
::
tuple
<
Ts
...
>>
{};
template
<
typename
T
,
typename
=
void
>
template
<
typename
T
,
typename
=
void
>
struct
is_iterator_traits
:
std
::
false_type
{};
struct
is_iterator_traits
:
std
::
false_type
{};
...
@@ -3570,9 +3628,9 @@ struct is_compatible_object_type_impl <
...
@@ -3570,9 +3628,9 @@ struct is_compatible_object_type_impl <
// macOS's is_constructible does not play well with nonesuch...
// macOS's is_constructible does not play well with nonesuch...
static
constexpr
bool
value
=
static
constexpr
bool
value
=
std
::
is_constructible
<
typename
object_t
::
key_type
,
is_constructible
<
typename
object_t
::
key_type
,
typename
CompatibleObjectType
::
key_type
>::
value
&&
typename
CompatibleObjectType
::
key_type
>::
value
&&
std
::
is_constructible
<
typename
object_t
::
mapped_type
,
is_constructible
<
typename
object_t
::
mapped_type
,
typename
CompatibleObjectType
::
mapped_type
>::
value
;
typename
CompatibleObjectType
::
mapped_type
>::
value
;
};
};
...
@@ -3593,10 +3651,10 @@ struct is_constructible_object_type_impl <
...
@@ -3593,10 +3651,10 @@ struct is_constructible_object_type_impl <
using
object_t
=
typename
BasicJsonType
::
object_t
;
using
object_t
=
typename
BasicJsonType
::
object_t
;
static
constexpr
bool
value
=
static
constexpr
bool
value
=
(
std
::
is_default_constructible
<
ConstructibleObjectType
>::
value
&&
(
is_default_constructible
<
ConstructibleObjectType
>::
value
&&
(
std
::
is_move_assignable
<
ConstructibleObjectType
>::
value
||
(
std
::
is_move_assignable
<
ConstructibleObjectType
>::
value
||
std
::
is_copy_assignable
<
ConstructibleObjectType
>::
value
)
&&
std
::
is_copy_assignable
<
ConstructibleObjectType
>::
value
)
&&
(
std
::
is_constructible
<
typename
ConstructibleObjectType
::
key_type
,
(
is_constructible
<
typename
ConstructibleObjectType
::
key_type
,
typename
object_t
::
key_type
>::
value
&&
typename
object_t
::
key_type
>::
value
&&
std
::
is_same
<
std
::
is_same
<
typename
object_t
::
mapped_type
,
typename
object_t
::
mapped_type
,
...
@@ -3624,7 +3682,7 @@ struct is_compatible_string_type_impl <
...
@@ -3624,7 +3682,7 @@ struct is_compatible_string_type_impl <
value_type_t
,
CompatibleStringType
>::
value
>>
value_type_t
,
CompatibleStringType
>::
value
>>
{
{
static
constexpr
auto
value
=
static
constexpr
auto
value
=
std
::
is_constructible
<
typename
BasicJsonType
::
string_t
,
CompatibleStringType
>::
value
;
is_constructible
<
typename
BasicJsonType
::
string_t
,
CompatibleStringType
>::
value
;
};
};
template
<
typename
BasicJsonType
,
typename
ConstructibleStringType
>
template
<
typename
BasicJsonType
,
typename
ConstructibleStringType
>
...
@@ -3642,7 +3700,7 @@ struct is_constructible_string_type_impl <
...
@@ -3642,7 +3700,7 @@ struct is_constructible_string_type_impl <
value_type_t
,
ConstructibleStringType
>::
value
>>
value_type_t
,
ConstructibleStringType
>::
value
>>
{
{
static
constexpr
auto
value
=
static
constexpr
auto
value
=
std
::
is_constructible
<
ConstructibleStringType
,
is_constructible
<
ConstructibleStringType
,
typename
BasicJsonType
::
string_t
>::
value
;
typename
BasicJsonType
::
string_t
>::
value
;
};
};
...
@@ -3665,7 +3723,7 @@ struct is_compatible_array_type_impl <
...
@@ -3665,7 +3723,7 @@ struct is_compatible_array_type_impl <
iterator_traits
<
CompatibleArrayType
>>::
value
>>
iterator_traits
<
CompatibleArrayType
>>::
value
>>
{
{
static
constexpr
bool
value
=
static
constexpr
bool
value
=
std
::
is_constructible
<
BasicJsonType
,
is_constructible
<
BasicJsonType
,
typename
CompatibleArrayType
::
value_type
>::
value
;
typename
CompatibleArrayType
::
value_type
>::
value
;
};
};
...
@@ -3688,7 +3746,7 @@ struct is_constructible_array_type_impl <
...
@@ -3688,7 +3746,7 @@ struct is_constructible_array_type_impl <
BasicJsonType
,
ConstructibleArrayType
,
BasicJsonType
,
ConstructibleArrayType
,
enable_if_t
<
!
std
::
is_same
<
ConstructibleArrayType
,
enable_if_t
<
!
std
::
is_same
<
ConstructibleArrayType
,
typename
BasicJsonType
::
value_type
>::
value
&&
typename
BasicJsonType
::
value_type
>::
value
&&
std
::
is_default_constructible
<
ConstructibleArrayType
>::
value
&&
is_default_constructible
<
ConstructibleArrayType
>::
value
&&
(
std
::
is_move_assignable
<
ConstructibleArrayType
>::
value
||
(
std
::
is_move_assignable
<
ConstructibleArrayType
>::
value
||
std
::
is_copy_assignable
<
ConstructibleArrayType
>::
value
)
&&
std
::
is_copy_assignable
<
ConstructibleArrayType
>::
value
)
&&
is_detected
<
value_type_t
,
ConstructibleArrayType
>::
value
&&
is_detected
<
value_type_t
,
ConstructibleArrayType
>::
value
&&
...
@@ -3732,7 +3790,7 @@ struct is_compatible_integer_type_impl <
...
@@ -3732,7 +3790,7 @@ struct is_compatible_integer_type_impl <
using
CompatibleLimits
=
std
::
numeric_limits
<
CompatibleNumberIntegerType
>
;
using
CompatibleLimits
=
std
::
numeric_limits
<
CompatibleNumberIntegerType
>
;
static
constexpr
auto
value
=
static
constexpr
auto
value
=
std
::
is_constructible
<
RealIntegerType
,
is_constructible
<
RealIntegerType
,
CompatibleNumberIntegerType
>::
value
&&
CompatibleNumberIntegerType
>::
value
&&
CompatibleLimits
::
is_integer
&&
CompatibleLimits
::
is_integer
&&
RealLimits
::
is_signed
==
CompatibleLimits
::
is_signed
;
RealLimits
::
is_signed
==
CompatibleLimits
::
is_signed
;
...
@@ -3759,18 +3817,11 @@ template<typename BasicJsonType, typename CompatibleType>
...
@@ -3759,18 +3817,11 @@ template<typename BasicJsonType, typename CompatibleType>
struct
is_compatible_type
struct
is_compatible_type
:
is_compatible_type_impl
<
BasicJsonType
,
CompatibleType
>
{};
:
is_compatible_type_impl
<
BasicJsonType
,
CompatibleType
>
{};
// https://en.cppreference.com/w/cpp/types/conjunction
template
<
class
...
>
struct
conjunction
:
std
::
true_type
{
};
template
<
class
B1
>
struct
conjunction
<
B1
>
:
B1
{
};
template
<
class
B1
,
class
...
Bn
>
struct
conjunction
<
B1
,
Bn
...
>
:
std
::
conditional
<
bool
(
B1
::
value
),
conjunction
<
Bn
...
>
,
B1
>::
type
{};
template
<
typename
T1
,
typename
T2
>
template
<
typename
T1
,
typename
T2
>
struct
is_constructible_tuple
:
std
::
false_type
{};
struct
is_constructible_tuple
:
std
::
false_type
{};
template
<
typename
T1
,
typename
...
Args
>
template
<
typename
T1
,
typename
...
Args
>
struct
is_constructible_tuple
<
T1
,
std
::
tuple
<
Args
...
>>
:
conjunction
<
std
::
is_constructible
<
T1
,
Args
>
...
>
{};
struct
is_constructible_tuple
<
T1
,
std
::
tuple
<
Args
...
>>
:
conjunction
<
is_constructible
<
T1
,
Args
>
...
>
{};
}
// namespace detail
}
// namespace detail
}
// namespace nlohmann
}
// namespace nlohmann
...
@@ -3946,7 +3997,10 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
...
@@ -3946,7 +3997,10 @@ auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
}
}
}
}
template
<
typename
BasicJsonType
,
typename
ConstructibleArrayType
>
template
<
typename
BasicJsonType
,
typename
ConstructibleArrayType
,
enable_if_t
<
std
::
is_assignable
<
ConstructibleArrayType
&
,
ConstructibleArrayType
>::
value
,
int
>
=
0
>
auto
from_json_array_impl
(
const
BasicJsonType
&
j
,
ConstructibleArrayType
&
arr
,
priority_tag
<
1
>
/*unused*/
)
auto
from_json_array_impl
(
const
BasicJsonType
&
j
,
ConstructibleArrayType
&
arr
,
priority_tag
<
1
>
/*unused*/
)
->
decltype
(
->
decltype
(
arr
.
reserve
(
std
::
declval
<
typename
ConstructibleArrayType
::
size_type
>
()),
arr
.
reserve
(
std
::
declval
<
typename
ConstructibleArrayType
::
size_type
>
()),
...
@@ -3967,7 +4021,10 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
...
@@ -3967,7 +4021,10 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
arr
=
std
::
move
(
ret
);
arr
=
std
::
move
(
ret
);
}
}
template
<
typename
BasicJsonType
,
typename
ConstructibleArrayType
>
template
<
typename
BasicJsonType
,
typename
ConstructibleArrayType
,
enable_if_t
<
std
::
is_assignable
<
ConstructibleArrayType
&
,
ConstructibleArrayType
>::
value
,
int
>
=
0
>
void
from_json_array_impl
(
const
BasicJsonType
&
j
,
ConstructibleArrayType
&
arr
,
void
from_json_array_impl
(
const
BasicJsonType
&
j
,
ConstructibleArrayType
&
arr
,
priority_tag
<
0
>
/*unused*/
)
priority_tag
<
0
>
/*unused*/
)
{
{
...
@@ -4006,6 +4063,25 @@ void())
...
@@ -4006,6 +4063,25 @@ void())
from_json_array_impl
(
j
,
arr
,
priority_tag
<
3
>
{});
from_json_array_impl
(
j
,
arr
,
priority_tag
<
3
>
{});
}
}
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
...
Idx
>
std
::
array
<
T
,
sizeof
...(
Idx
)
>
from_json_inplace_array_impl
(
BasicJsonType
&&
j
,
identity_tag
<
std
::
array
<
T
,
sizeof
...(
Idx
)
>>
/*unused*/
,
index_sequence
<
Idx
...
>
/*unused*/
)
{
return
{
{
std
::
forward
<
BasicJsonType
>
(
j
).
at
(
Idx
).
template
get
<
T
>
()...
}
};
}
template
<
typename
BasicJsonType
,
typename
T
,
std
::
size_t
N
>
auto
from_json
(
BasicJsonType
&&
j
,
identity_tag
<
std
::
array
<
T
,
N
>>
tag
)
->
decltype
(
from_json_inplace_array_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
tag
,
make_index_sequence
<
N
>
{}))
{
if
(
JSON_HEDLEY_UNLIKELY
(
!
j
.
is_array
()))
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
std
::
string
(
j
.
type_name
()),
j
));
}
return
from_json_inplace_array_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
tag
,
make_index_sequence
<
N
>
{});
}
template
<
typename
BasicJsonType
>
template
<
typename
BasicJsonType
>
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
binary_t
&
bin
)
void
from_json
(
const
BasicJsonType
&
j
,
typename
BasicJsonType
::
binary_t
&
bin
)
{
{
...
@@ -4081,22 +4157,47 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
...
@@ -4081,22 +4157,47 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
}
}
}
}
template
<
typename
BasicJsonType
,
typename
...
Args
,
std
::
size_t
...
Idx
>
std
::
tuple
<
Args
...
>
from_json_tuple_impl_base
(
BasicJsonType
&&
j
,
index_sequence
<
Idx
...
>
/*unused*/
)
{
return
std
::
make_tuple
(
std
::
forward
<
BasicJsonType
>
(
j
).
at
(
Idx
).
template
get
<
Args
>
()...);
}
template
<
typename
BasicJsonType
,
class
A1
,
class
A2
>
std
::
pair
<
A1
,
A2
>
from_json_tuple_impl
(
BasicJsonType
&&
j
,
identity_tag
<
std
::
pair
<
A1
,
A2
>>
/*unused*/
,
priority_tag
<
0
>
/*unused*/
)
{
return
{
std
::
forward
<
BasicJsonType
>
(
j
).
at
(
0
).
template
get
<
A1
>
(),
std
::
forward
<
BasicJsonType
>
(
j
).
at
(
1
).
template
get
<
A2
>
()};
}
template
<
typename
BasicJsonType
,
typename
A1
,
typename
A2
>
template
<
typename
BasicJsonType
,
typename
A1
,
typename
A2
>
void
from_json
(
const
BasicJsonType
&
j
,
std
::
pair
<
A1
,
A2
>&
p
)
void
from_json
_tuple_impl
(
BasicJsonType
&&
j
,
std
::
pair
<
A1
,
A2
>&
p
,
priority_tag
<
1
>
/*unused*/
)
{
{
p
=
{
j
.
at
(
0
).
template
get
<
A1
>
(),
j
.
at
(
1
).
template
get
<
A2
>
()}
;
p
=
from_json_tuple_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
identity_tag
<
std
::
pair
<
A1
,
A2
>>
{},
priority_tag
<
0
>
{})
;
}
}
template
<
typename
BasicJsonType
,
typename
Tuple
,
std
::
size_t
...
Idx
>
template
<
typename
BasicJsonType
,
typename
...
Args
>
void
from_json_tuple_impl
(
const
BasicJsonType
&
j
,
Tuple
&
t
,
index_sequence
<
Idx
...
>
/*unused*/
)
std
::
tuple
<
Args
...
>
from_json_tuple_impl
(
BasicJsonType
&&
j
,
identity_tag
<
std
::
tuple
<
Args
...
>>
/*unused*/
,
priority_tag
<
2
>
/*unused*/
)
{
{
t
=
std
::
make_tuple
(
j
.
at
(
Idx
).
template
get
<
typename
std
::
tuple_element
<
Idx
,
Tuple
>::
type
>
()...
);
return
from_json_tuple_impl_base
<
BasicJsonType
,
Args
...
>
(
std
::
forward
<
BasicJsonType
>
(
j
),
index_sequence_for
<
Args
...
>
{}
);
}
}
template
<
typename
BasicJsonType
,
typename
...
Args
>
template
<
typename
BasicJsonType
,
typename
...
Args
>
void
from_json
(
const
BasicJsonType
&
j
,
std
::
tuple
<
Args
...
>&
t
)
void
from_json
_tuple_impl
(
BasicJsonType
&&
j
,
std
::
tuple
<
Args
...
>&
t
,
priority_tag
<
3
>
/*unused*/
)
{
{
from_json_tuple_impl
(
j
,
t
,
index_sequence_for
<
Args
...
>
{});
t
=
from_json_tuple_impl_base
<
BasicJsonType
,
Args
...
>
(
std
::
forward
<
BasicJsonType
>
(
j
),
index_sequence_for
<
Args
...
>
{});
}
template
<
typename
BasicJsonType
,
typename
TupleRelated
>
auto
from_json
(
BasicJsonType
&&
j
,
TupleRelated
&&
t
)
->
decltype
(
from_json_tuple_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
std
::
forward
<
TupleRelated
>
(
t
),
priority_tag
<
3
>
{}))
{
if
(
JSON_HEDLEY_UNLIKELY
(
!
j
.
is_array
()))
{
JSON_THROW
(
type_error
::
create
(
302
,
"type must be array, but is "
+
std
::
string
(
j
.
type_name
()),
j
));
}
return
from_json_tuple_impl
(
std
::
forward
<
BasicJsonType
>
(
j
),
std
::
forward
<
TupleRelated
>
(
t
),
priority_tag
<
3
>
{});
}
}
template
<
typename
BasicJsonType
,
typename
Key
,
typename
Value
,
typename
Compare
,
typename
Allocator
,
template
<
typename
BasicJsonType
,
typename
Key
,
typename
Value
,
typename
Compare
,
typename
Allocator
,
...
@@ -4142,11 +4243,11 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
...
@@ -4142,11 +4243,11 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
struct
from_json_fn
struct
from_json_fn
{
{
template
<
typename
BasicJsonType
,
typename
T
>
template
<
typename
BasicJsonType
,
typename
T
>
auto
operator
()(
const
BasicJsonType
&
j
,
T
&
val
)
const
auto
operator
()(
const
BasicJsonType
&
j
,
T
&
&
val
)
const
noexcept
(
noexcept
(
from_json
(
j
,
val
)))
noexcept
(
noexcept
(
from_json
(
j
,
std
::
forward
<
T
>
(
val
)
)))
->
decltype
(
from_json
(
j
,
val
),
void
(
))
->
decltype
(
from_json
(
j
,
std
::
forward
<
T
>
(
val
)
))
{
{
return
from_json
(
j
,
val
);
return
from_json
(
j
,
std
::
forward
<
T
>
(
val
)
);
}
}
};
};
}
// namespace detail
}
// namespace detail
...
@@ -4731,11 +4832,15 @@ constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
...
@@ -4731,11 +4832,15 @@ constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
}
// namespace
}
// namespace
}
// namespace nlohmann
}
// namespace nlohmann
// #include <nlohmann/detail/meta/identity_tag.hpp>
// #include <nlohmann/detail/meta/type_traits.hpp>
namespace
nlohmann
namespace
nlohmann
{
{
template
<
typename
,
typename
>
template
<
typename
ValueType
,
typename
>
struct
adl_serializer
struct
adl_serializer
{
{
/*!
/*!
...
@@ -4744,11 +4849,13 @@ struct adl_serializer
...
@@ -4744,11 +4849,13 @@ struct adl_serializer
This function is usually called by the `get()` function of the
This function is usually called by the `get()` function of the
@ref basic_json class (either explicit or via conversion operators).
@ref basic_json class (either explicit or via conversion operators).
@note This function is chosen for default-constructible value types.
@param[in] j JSON value to read from
@param[in] j JSON value to read from
@param[in,out] val value to write to
@param[in,out] val value to write to
*/
*/
template
<
typename
BasicJsonType
,
typename
ValueType
>
template
<
typename
BasicJsonType
,
typename
TargetType
=
ValueType
>
static
auto
from_json
(
BasicJsonType
&&
j
,
Value
Type
&
val
)
noexcept
(
static
auto
from_json
(
BasicJsonType
&&
j
,
Target
Type
&
val
)
noexcept
(
noexcept
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
val
)))
noexcept
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
val
)))
->
decltype
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
val
),
void
())
->
decltype
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
val
),
void
())
{
{
...
@@ -4756,6 +4863,26 @@ struct adl_serializer
...
@@ -4756,6 +4863,26 @@ struct adl_serializer
}
}
/*!
/*!
@brief convert a JSON value to any value type
This function is usually called by the `get()` function of the
@ref basic_json class (either explicit or via conversion operators).
@note This function is chosen for value types which are not default-constructible.
@param[in] j JSON value to read from
@return copy of the JSON value, converted to @a ValueType
*/
template
<
typename
BasicJsonType
,
typename
TargetType
=
ValueType
>
static
auto
from_json
(
BasicJsonType
&&
j
)
noexcept
(
noexcept
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
detail
::
identity_tag
<
TargetType
>
{})))
->
decltype
(
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
detail
::
identity_tag
<
TargetType
>
{}))
{
return
::
nlohmann
::
from_json
(
std
::
forward
<
BasicJsonType
>
(
j
),
detail
::
identity_tag
<
TargetType
>
{});
}
/*!
@brief convert any value type to a JSON value
@brief convert any value type to a JSON value
This function is usually called by the constructors of the @ref basic_json
This function is usually called by the constructors of the @ref basic_json
...
@@ -4764,15 +4891,14 @@ struct adl_serializer
...
@@ -4764,15 +4891,14 @@ struct adl_serializer
@param[in,out] j JSON value to write to
@param[in,out] j JSON value to write to
@param[in] val value to read from
@param[in] val value to read from
*/
*/
template
<
typename
BasicJsonType
,
typename
ValueType
>
template
<
typename
BasicJsonType
,
typename
TargetType
=
ValueType
>
static
auto
to_json
(
BasicJsonType
&
j
,
ValueType
&&
val
)
noexcept
(
static
auto
to_json
(
BasicJsonType
&
j
,
TargetType
&&
val
)
noexcept
(
noexcept
(
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Value
Type
>
(
val
))))
noexcept
(
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Target
Type
>
(
val
))))
->
decltype
(
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Value
Type
>
(
val
)),
void
())
->
decltype
(
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Target
Type
>
(
val
)),
void
())
{
{
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Value
Type
>
(
val
));
::
nlohmann
::
to_json
(
j
,
std
::
forward
<
Target
Type
>
(
val
));
}
}
};
};
}
// namespace nlohmann
}
// namespace nlohmann
// #include <nlohmann/byte_container_with_subtype.hpp>
// #include <nlohmann/byte_container_with_subtype.hpp>
...
@@ -19809,50 +19935,53 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -19809,50 +19935,53 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
/// @{
/// @{
/*!
/*!
@brief get
special-case overload
@brief get
a pointer value (implicit)
This overloads avoids a lot of template boilerplate, it can be seen as th
e
Implicit pointer access to the internally stored JSON value. No copies ar
e
identity method
made.
@tparam BasicJsonType == @ref basic_json
@warning Writing data to the pointee of the result yields an undefined
state.
@return a copy of *this
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
@ref number_unsigned_t, or @ref number_float_t. Enforced by a static
assertion.
@return pointer to the internally stored JSON value if the requested
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
@complexity Constant.
@complexity Constant.
@since version 2.1.0
@liveexample{The example below shows how pointers to internal values of a
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
match.,get_ptr}
@since version 1.0.0
*/
*/
template
<
typename
BasicJsonType
,
detail
::
enable_if_t
<
template
<
typename
PointerType
,
typename
std
::
enable_if
<
std
::
is_same
<
typename
std
::
remove_const
<
BasicJsonType
>::
type
,
basic_json_t
>::
value
,
std
::
is_pointer
<
PointerType
>::
value
,
int
>::
type
=
0
>
int
>
=
0
>
auto
get_ptr
()
noexcept
->
decltype
(
std
::
declval
<
basic_json_t
&>
().
get_impl_ptr
(
std
::
declval
<
PointerType
>
()))
basic_json
get
()
const
{
{
return
*
this
;
// delegate the call to get_impl_ptr<>()
return
get_impl_ptr
(
static_cast
<
PointerType
>
(
nullptr
));
}
}
/*!
/*!
@brief get special-case overload
@brief get a pointer value (implicit)
@copydoc get_ptr()
This overloads converts the current @ref basic_json in a different
@ref basic_json type
@tparam BasicJsonType == @ref basic_json
@return a copy of *this, converted into @a BasicJsonType
@complexity Depending on the implementation of the called `from_json()`
method.
@since version 3.2.0
*/
*/
template
<
typename
BasicJsonType
,
detail
::
enable_if_t
<
template
<
typename
PointerType
,
typename
std
::
enable_if
<
!
std
::
is_same
<
BasicJsonType
,
basic_json
>::
value
&&
std
::
is_pointer
<
PointerType
>::
value
&&
detail
::
is_basic_json
<
BasicJsonType
>::
value
,
int
>
=
0
>
std
::
is_const
<
typename
std
::
remove_pointer
<
PointerType
>::
type
>::
value
,
int
>::
type
=
0
>
BasicJsonType
get
()
const
constexpr
auto
get_ptr
()
const
noexcept
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
get_impl_ptr
(
std
::
declval
<
PointerType
>
()))
{
{
return
*
this
;
// delegate the call to get_impl_ptr<>() const
return
get_impl_ptr
(
static_cast
<
PointerType
>
(
nullptr
));
}
}
private
:
/*!
/*!
@brief get a value (explicit)
@brief get a value (explicit)
...
@@ -19876,7 +20005,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -19876,7 +20005,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
- @ref json_serializer<ValueType> does not have a `from_json()` method of
- @ref json_serializer<ValueType> does not have a `from_json()` method of
the form `ValueType from_json(const basic_json&)`
the form `ValueType from_json(const basic_json&)`
@tparam ValueTypeCV the provided value type
@tparam ValueType the returned value type
@tparam ValueType the returned value type
@return copy of the JSON value, converted to @a ValueType
@return copy of the JSON value, converted to @a ValueType
...
@@ -19892,23 +20020,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -19892,23 +20020,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@since version 2.1.0
@since version 2.1.0
*/
*/
template
<
typename
ValueType
CV
,
typename
ValueType
=
detail
::
uncvref_t
<
ValueTypeCV
>
,
template
<
typename
ValueType
,
detail
::
enable_if_t
<
detail
::
enable_if_t
<
!
detail
::
is_basic_json
<
ValueType
>::
value
&&
detail
::
is_default_constructible
<
ValueType
>::
value
&&
detail
::
has_from_json
<
basic_json_t
,
ValueType
>::
value
&&
detail
::
has_from_json
<
basic_json_t
,
ValueType
>::
value
,
!
detail
::
has_non_default_from_json
<
basic_json_t
,
ValueType
>::
value
,
int
>
=
0
>
int
>
=
0
>
ValueType
get
(
)
const
noexcept
(
noexcept
(
ValueType
get
_impl
(
detail
::
priority_tag
<
0
>
/*unused*/
)
const
noexcept
(
noexcept
(
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
std
::
declval
<
ValueType
&>
())))
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
std
::
declval
<
ValueType
&>
())))
{
{
// we cannot static_assert on ValueTypeCV being non-const, because
// there is support for get<const basic_json_t>(), which is why we
// still need the uncvref
static_assert
(
!
std
::
is_reference
<
ValueTypeCV
>::
value
,
"get() cannot be used with reference types, you might want to use get_ref()"
);
static_assert
(
std
::
is_default_constructible
<
ValueType
>::
value
,
"types must be DefaultConstructible when used with get()"
);
ValueType
ret
{};
ValueType
ret
{};
JSONSerializer
<
ValueType
>::
from_json
(
*
this
,
ret
);
JSONSerializer
<
ValueType
>::
from_json
(
*
this
,
ret
);
return
ret
;
return
ret
;
...
@@ -19925,7 +20044,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -19925,7 +20044,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
The function is equivalent to executing
The function is equivalent to executing
@code {.cpp}
@code {.cpp}
return JSONSerializer<ValueType
CV
>::from_json(*this);
return JSONSerializer<ValueType>::from_json(*this);
@endcode
@endcode
This overloads is chosen if:
This overloads is chosen if:
...
@@ -19936,7 +20055,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -19936,7 +20055,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@note If @ref json_serializer<ValueType> has both overloads of
@note If @ref json_serializer<ValueType> has both overloads of
`from_json()`, this one is chosen.
`from_json()`, this one is chosen.
@tparam ValueTypeCV the provided value type
@tparam ValueType the returned value type
@tparam ValueType the returned value type
@return copy of the JSON value, converted to @a ValueType
@return copy of the JSON value, converted to @a ValueType
...
@@ -19945,134 +20063,116 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -19945,134 +20063,116 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
@since version 2.1.0
@since version 2.1.0
*/
*/
template
<
typename
ValueType
CV
,
typename
ValueType
=
detail
::
uncvref_t
<
ValueTypeCV
>
,
template
<
typename
ValueType
,
detail
::
enable_if_t
<
!
std
::
is_same
<
basic_json_t
,
ValueType
>::
value
&&
detail
::
enable_if_t
<
detail
::
has_non_default_from_json
<
basic_json_t
,
ValueType
>::
value
,
detail
::
has_non_default_from_json
<
basic_json_t
,
ValueType
>::
value
,
int
>
=
0
>
int
>
=
0
>
ValueType
get
(
)
const
noexcept
(
noexcept
(
ValueType
get
_impl
(
detail
::
priority_tag
<
1
>
/*unused*/
)
const
noexcept
(
noexcept
(
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
())))
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
())))
{
{
static_assert
(
!
std
::
is_reference
<
ValueTypeCV
>::
value
,
"get() cannot be used with reference types, you might want to use get_ref()"
);
return
JSONSerializer
<
ValueType
>::
from_json
(
*
this
);
return
JSONSerializer
<
ValueType
>::
from_json
(
*
this
);
}
}
/*!
/*!
@brief get a value (explicit)
@brief get special-case overload
Explicit type conversion between the JSON value and a compatible value.
The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
`from_json()` method.
The function is equivalent to executing
@code {.cpp}
ValueType v;
JSONSerializer<ValueType>::from_json(*this, v);
@endcode
This overloads is chosen if:
- @a ValueType is not @ref basic_json,
- @ref json_serializer<ValueType> has a `from_json()` method of the form
`void from_json(const basic_json&, ValueType&)`, and
@tparam ValueType the input parameter type.
This overloads converts the current @ref basic_json in a different
@ref basic_json type
@
return the input parameter, allowing chaining calls.
@
tparam BasicJsonType == @ref basic_json
@
throw what @ref json_serializer<ValueType> `from_json()` method throws
@
return a copy of *this, converted into @a BasicJsonType
@liveexample{The example below shows several conversions from JSON values
@complexity Depending on the implementation of the called `from_json()`
to other types. There a few things to note: (1) Floating-point numbers can
method.
be converted to integers\, (2) A JSON array can be converted to a standard
`std::vector<short>`\, (3) A JSON object can be converted to C++
associative containers such as `std::unordered_map<std::string\,
json>`.,get_to}
@since version 3.
3
.0
@since version 3.
2
.0
*/
*/
template
<
typename
Value
Type
,
template
<
typename
BasicJson
Type
,
detail
::
enable_if_t
<
detail
::
enable_if_t
<
!
detail
::
is_basic_json
<
ValueType
>::
value
&&
detail
::
is_basic_json
<
BasicJsonType
>::
value
,
detail
::
has_from_json
<
basic_json_t
,
ValueType
>::
value
,
int
>
=
0
>
int
>
=
0
>
ValueType
&
get_to
(
ValueType
&
v
)
const
noexcept
(
noexcept
(
BasicJsonType
get_impl
(
detail
::
priority_tag
<
2
>
/*unused*/
)
const
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
v
)))
{
{
JSONSerializer
<
ValueType
>::
from_json
(
*
this
,
v
);
return
*
this
;
return
v
;
}
}
// specialization to allow to call get_to with a basic_json value
/*!
// see https://github.com/nlohmann/json/issues/2175
@brief get special-case overload
template
<
typename
ValueType
,
detail
::
enable_if_t
<
This overloads avoids a lot of template boilerplate, it can be seen as the
detail
::
is_basic_json
<
ValueType
>::
value
,
identity method
@tparam BasicJsonType == @ref basic_json
@return a copy of *this
@complexity Constant.
@since version 2.1.0
*/
template
<
typename
BasicJsonType
,
detail
::
enable_if_t
<
std
::
is_same
<
BasicJsonType
,
basic_json_t
>::
value
,
int
>
=
0
>
int
>
=
0
>
ValueType
&
get_to
(
ValueType
&
v
)
const
basic_json
get_impl
(
detail
::
priority_tag
<
3
>
/*unused*/
)
const
{
{
v
=
*
this
;
return
*
this
;
return
v
;
}
}
template
<
/*!
typename
T
,
std
::
size_t
N
,
@brief get a pointer value (explicit)
typename
Array
=
T
(
&
)[
N
],
// NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
@copydoc get()
detail
::
enable_if_t
<
*/
detail
::
has_from_json
<
basic_json_t
,
Array
>::
value
,
int
>
=
0
>
template
<
typename
PointerType
,
Array
get_to
(
T
(
&
v
)[
N
])
const
// NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
detail
::
enable_if_t
<
noexcept
(
noexcept
(
JSONSerializer
<
Array
>::
from_json
(
std
::
is_pointer
<
PointerType
>::
value
,
std
::
declval
<
const
basic_json_t
&>
(),
v
)))
int
>
=
0
>
constexpr
auto
get_impl
(
detail
::
priority_tag
<
4
>
/*unused*/
)
const
noexcept
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
template
get_ptr
<
PointerType
>
())
{
{
JSONSerializer
<
Array
>::
from_json
(
*
this
,
v
);
// delegate the call to get_ptr
return
v
;
return
get_ptr
<
PointerType
>
()
;
}
}
public
:
/*!
/*!
@brief get a
pointer value (im
plicit)
@brief get a
(pointer) value (ex
plicit)
Implicit pointer access to the internally stored JSON value. No copies are
Performs explicit type conversion between the JSON value and a compatible value if required.
made.
@warning Writing data to the pointee of the result yields an undefined
- If the requested type is a pointer to the internally stored JSON value that pointer is returned.
stat
e.
No copies are mad
e.
@tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
- If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
from the current @ref basic_json.
@ref number_unsigned_t, or @ref number_float_t. Enforced by a static
assertion.
@return pointer to the internally stored JSON value if the requested
- Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
method.
@complexity Constant.
@tparam ValueTypeCV the provided value type
@tparam ValueType the returned value type
@liveexample{The example below shows how pointers to internal values of a
@return copy of the JSON value, converted to @tparam ValueType if necessary
JSON value can be requested. Note that no type conversions are made and a
`nullptr` is returned if the value and the requested pointer type does not
match.,get_ptr}
@since version 1.0.0
@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
*/
template
<
typename
PointerType
,
typename
std
::
enable_if
<
std
::
is_pointer
<
PointerType
>::
value
,
int
>::
type
=
0
>
auto
get_ptr
()
noexcept
->
decltype
(
std
::
declval
<
basic_json_t
&>
().
get_impl_ptr
(
std
::
declval
<
PointerType
>
()))
{
// delegate the call to get_impl_ptr<>()
return
get_impl_ptr
(
static_cast
<
PointerType
>
(
nullptr
));
}
/*!
@since version 2.1.0
@brief get a pointer value (implicit)
@copydoc get_ptr()
*/
*/
template
<
typename
PointerType
,
typename
std
::
enable_if
<
template
<
typename
ValueTypeCV
,
typename
ValueType
=
detail
::
uncvref_t
<
ValueTypeCV
>>
std
::
is_pointer
<
PointerType
>::
value
&&
#if defined(JSON_HAS_CPP_14)
std
::
is_const
<
typename
std
::
remove_pointer
<
PointerType
>::
type
>::
value
,
int
>::
type
=
0
>
constexpr
constexpr
auto
get_ptr
()
const
noexcept
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
get_impl_ptr
(
std
::
declval
<
PointerType
>
()))
#endif
auto
get
()
const
noexcept
(
noexcept
(
std
::
declval
<
const
basic_json_t
&>
().
template
get_impl
<
ValueType
>
(
detail
::
priority_tag
<
4
>
{})))
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
template
get_impl
<
ValueType
>
(
detail
::
priority_tag
<
4
>
{}))
{
{
// delegate the call to get_impl_ptr<>() const
// we cannot static_assert on ValueTypeCV being non-const, because
return
get_impl_ptr
(
static_cast
<
PointerType
>
(
nullptr
));
// there is support for get<const basic_json_t>(), which is why we
// still need the uncvref
static_assert
(
!
std
::
is_reference
<
ValueTypeCV
>::
value
,
"get() cannot be used with reference types, you might want to use get_ref()"
);
return
get_impl
<
ValueType
>
(
detail
::
priority_tag
<
4
>
{});
}
}
/*!
/*!
...
@@ -20111,15 +20211,73 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
...
@@ -20111,15 +20211,73 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
}
/*!
/*!
@brief get a pointer value (explicit)
@brief get a value (explicit)
@copydoc get()
Explicit type conversion between the JSON value and a compatible value.
The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
`from_json()` method.
The function is equivalent to executing
@code {.cpp}
ValueType v;
JSONSerializer<ValueType>::from_json(*this, v);
@endcode
This overloads is chosen if:
- @a ValueType is not @ref basic_json,
- @ref json_serializer<ValueType> has a `from_json()` method of the form
`void from_json(const basic_json&, ValueType&)`, and
@tparam ValueType the input parameter type.
@return the input parameter, allowing chaining calls.
@throw what @ref json_serializer<ValueType> `from_json()` method throws
@liveexample{The example below shows several conversions from JSON values
to other types. There a few things to note: (1) Floating-point numbers can
be converted to integers\, (2) A JSON array can be converted to a standard
`std::vector<short>`\, (3) A JSON object can be converted to C++
associative containers such as `std::unordered_map<std::string\,
json>`.,get_to}
@since version 3.3.0
*/
*/
template
<
typename
PointerType
,
typename
std
::
enable_if
<
template
<
typename
ValueType
,
std
::
is_pointer
<
PointerType
>::
value
,
int
>::
type
=
0
>
detail
::
enable_if_t
<
constexpr
auto
get
()
const
noexcept
->
decltype
(
std
::
declval
<
const
basic_json_t
&>
().
template
get_ptr
<
PointerType
>
())
!
detail
::
is_basic_json
<
ValueType
>::
value
&&
detail
::
has_from_json
<
basic_json_t
,
ValueType
>::
value
,
int
>
=
0
>
ValueType
&
get_to
(
ValueType
&
v
)
const
noexcept
(
noexcept
(
JSONSerializer
<
ValueType
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
v
)))
{
{
// delegate the call to get_ptr
JSONSerializer
<
ValueType
>::
from_json
(
*
this
,
v
);
return
get_ptr
<
PointerType
>
();
return
v
;
}
// specialization to allow to call get_to with a basic_json value
// see https://github.com/nlohmann/json/issues/2175
template
<
typename
ValueType
,
detail
::
enable_if_t
<
detail
::
is_basic_json
<
ValueType
>::
value
,
int
>
=
0
>
ValueType
&
get_to
(
ValueType
&
v
)
const
{
v
=
*
this
;
return
v
;
}
template
<
typename
T
,
std
::
size_t
N
,
typename
Array
=
T
(
&
)[
N
],
// NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
detail
::
enable_if_t
<
detail
::
has_from_json
<
basic_json_t
,
Array
>::
value
,
int
>
=
0
>
Array
get_to
(
T
(
&
v
)[
N
])
const
// NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
noexcept
(
noexcept
(
JSONSerializer
<
Array
>::
from_json
(
std
::
declval
<
const
basic_json_t
&>
(),
v
)))
{
JSONSerializer
<
Array
>::
from_json
(
*
this
,
v
);
return
v
;
}
}
/*!
/*!
...
...
test/src/unit-regression2.cpp
View file @
a34e011e
...
@@ -134,6 +134,29 @@ struct NotSerializableData
...
@@ -134,6 +134,29 @@ struct NotSerializableData
};
};
/////////////////////////////////////////////////////////////////////
// for #2574
/////////////////////////////////////////////////////////////////////
struct
NonDefaultConstructible
{
explicit
NonDefaultConstructible
(
int
a
)
:
x
(
a
)
{
}
int
x
;
};
namespace
nlohmann
{
template
<>
struct
adl_serializer
<
NonDefaultConstructible
>
{
static
NonDefaultConstructible
from_json
(
json
const
&
j
)
{
return
NonDefaultConstructible
(
j
.
get
<
int
>
());
}
};
}
// namespace nlohmann
TEST_CASE
(
"regression tests 2"
)
TEST_CASE
(
"regression tests 2"
)
{
{
SECTION
(
"issue #1001 - Fix memory leak during parser callback"
)
SECTION
(
"issue #1001 - Fix memory leak during parser callback"
)
...
@@ -501,4 +524,74 @@ TEST_CASE("regression tests 2")
...
@@ -501,4 +524,74 @@ TEST_CASE("regression tests 2")
CHECK
(
j
.
dump
()
==
"
\"
Hello, world!
\"
"
);
CHECK
(
j
.
dump
()
==
"
\"
Hello, world!
\"
"
);
}
}
#endif
#endif
SECTION
(
"issue #2574 - Deserialization to std::array, std::pair, and std::tuple with non-default constructable types fails"
)
{
SECTION
(
"std::array"
)
{
{
json
j
=
{
7
,
4
};
auto
arr
=
j
.
get
<
std
::
array
<
NonDefaultConstructible
,
2
>>
();
CHECK
(
arr
[
0
].
x
==
7
);
CHECK
(
arr
[
1
].
x
==
4
);
}
{
json
j
=
7
;
CHECK_THROWS_AS
((
j
.
get
<
std
::
array
<
NonDefaultConstructible
,
1
>>
()),
json
::
type_error
);
}
}
SECTION
(
"std::pair"
)
{
{
json
j
=
{
3
,
8
};
auto
p
=
j
.
get
<
std
::
pair
<
NonDefaultConstructible
,
NonDefaultConstructible
>>
();
CHECK
(
p
.
first
.
x
==
3
);
CHECK
(
p
.
second
.
x
==
8
);
}
{
json
j
=
{
4
,
1
};
auto
p
=
j
.
get
<
std
::
pair
<
int
,
NonDefaultConstructible
>>
();
CHECK
(
p
.
first
==
4
);
CHECK
(
p
.
second
.
x
==
1
);
}
{
json
j
=
{
6
,
7
};
auto
p
=
j
.
get
<
std
::
pair
<
NonDefaultConstructible
,
int
>>
();
CHECK
(
p
.
first
.
x
==
6
);
CHECK
(
p
.
second
==
7
);
}
{
json
j
=
7
;
CHECK_THROWS_AS
((
j
.
get
<
std
::
pair
<
NonDefaultConstructible
,
int
>>
()),
json
::
type_error
);
}
}
SECTION
(
"std::tuple"
)
{
{
json
j
=
{
9
};
auto
t
=
j
.
get
<
std
::
tuple
<
NonDefaultConstructible
>>
();
CHECK
(
std
::
get
<
0
>
(
t
).
x
==
9
);
}
{
json
j
=
{
9
,
8
,
7
};
auto
t
=
j
.
get
<
std
::
tuple
<
NonDefaultConstructible
,
int
,
NonDefaultConstructible
>>
();
CHECK
(
std
::
get
<
0
>
(
t
).
x
==
9
);
CHECK
(
std
::
get
<
1
>
(
t
)
==
8
);
CHECK
(
std
::
get
<
2
>
(
t
).
x
==
7
);
}
{
json
j
=
7
;
CHECK_THROWS_AS
((
j
.
get
<
std
::
tuple
<
NonDefaultConstructible
>>
()),
json
::
type_error
);
}
}
}
}
}
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