mirror of
https://github.com/nlohmann/json.git
synced 2026-09-28 18:50:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2dc43e8bf8 | ||
|
|
e0eb3e7490 | ||
|
|
3ae4d7c45e |
@@ -272,6 +272,15 @@ basic_json(basic_json&& other) noexcept;
|
|||||||
When used without parentheses around an empty initializer list, `basic_json()` is called instead of this
|
When used without parentheses around an empty initializer list, `basic_json()` is called instead of this
|
||||||
function, yielding the JSON `#!json null` value.
|
function, yielding the JSON `#!json null` value.
|
||||||
|
|
||||||
|
- Overload 4:
|
||||||
|
|
||||||
|
!!! info "Implicit conversion"
|
||||||
|
|
||||||
|
The conversion is implicit unless [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md)
|
||||||
|
is defined to `0` and `BasicJsonType::string_t` differs from `string_t`. In that case, the constructor is
|
||||||
|
`explicit`, so a JSON value with a different string type is no longer silently converted, for example when it is
|
||||||
|
passed to a function taking `#!cpp const json&`. Write `#!cpp json(other)` or `#!cpp other.get<json>()` instead.
|
||||||
|
|
||||||
- Overload 7:
|
- Overload 7:
|
||||||
|
|
||||||
!!! info "Preconditions"
|
!!! info "Preconditions"
|
||||||
@@ -420,7 +429,8 @@ basic_json(basic_json&& other) noexcept;
|
|||||||
1. Since version 1.0.0.
|
1. Since version 1.0.0.
|
||||||
2. Since version 1.0.0.
|
2. Since version 1.0.0.
|
||||||
3. Since version 2.1.0.
|
3. Since version 2.1.0.
|
||||||
4. Since version 3.2.0.
|
4. Since version 3.2.0. Explicit for different string types if `JSON_USE_IMPLICIT_CONVERSIONS` is `0` since
|
||||||
|
version 3.13.0.
|
||||||
5. Since version 1.0.0.
|
5. Since version 1.0.0.
|
||||||
6. Since version 1.0.0.
|
6. Since version 1.0.0.
|
||||||
7. Since version 1.0.0.
|
7. Since version 1.0.0.
|
||||||
|
|||||||
@@ -86,9 +86,6 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
|||||||
- Throws [`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) if an array index in the passed
|
- Throws [`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) if an array index in the passed
|
||||||
JSON pointer `ptr` exceeds the range of `size_type` (e.g., on 32-bit platforms).
|
JSON pointer `ptr` exceeds the range of `size_type` (e.g., on 32-bit platforms).
|
||||||
|
|
||||||
For the **const** version, an object key or array index in `ptr` that does not exist is not reported by an
|
|
||||||
exception, but is undefined behavior (see the notes below). Use [`at`](at.md) for checked access.
|
|
||||||
|
|
||||||
## Complexity
|
## Complexity
|
||||||
|
|
||||||
1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`.
|
1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`.
|
||||||
@@ -103,12 +100,9 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
|||||||
The following cases apply to the **const** overloads; the non-const overloads instead insert the missing element
|
The following cases apply to the **const** overloads; the non-const overloads instead insert the missing element
|
||||||
(see the notes below).
|
(see the notes below).
|
||||||
|
|
||||||
1. If the element at index `idx` does not exist, the behavior is undefined and is **guarded by a
|
1. If the element at index `idx` does not exist, the behavior is undefined.
|
||||||
[runtime assertion](../../features/assertions.md)**!
|
|
||||||
2. If the element with key `key` does not exist, the behavior is undefined and is **guarded by a
|
2. If the element with key `key` does not exist, the behavior is undefined and is **guarded by a
|
||||||
[runtime assertion](../../features/assertions.md)**!
|
[runtime assertion](../../features/assertions.md)**!
|
||||||
3. If the JSON pointer `ptr` refers to an object key or an array index that does not exist, the behavior is
|
|
||||||
undefined and is **guarded by a [runtime assertion](../../features/assertions.md)**!
|
|
||||||
|
|
||||||
1. The non-const version may add values: If `idx` is beyond the range of the array (i.e., `idx >= size()`), then the
|
1. The non-const version may add values: If `idx` is beyond the range of the array (i.e., `idx >= size()`), then the
|
||||||
array is silently filled up with `#!json null` values to make `idx` a valid reference to the last stored element. In
|
array is silently filled up with `#!json null` values to make `idx` a valid reference to the last stored element. In
|
||||||
@@ -263,11 +257,9 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
|||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
1. Added in version 1.0.0. A missing index in the const version is guarded by a runtime assertion since version
|
1. Added in version 1.0.0.
|
||||||
3.13.0.
|
|
||||||
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3)
|
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3)
|
||||||
in version 3.11.0.
|
in version 3.11.0.
|
||||||
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
|
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
|
||||||
already supported by [`at`](at.md), [`value`](value.md), [`find`](find.md), and other lookup functions.
|
already supported by [`at`](at.md), [`value`](value.md), [`find`](find.md), and other lookup functions.
|
||||||
4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since
|
4. Added in version 2.0.0.
|
||||||
version 3.13.0.
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. The
|
When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. The
|
||||||
value directly affects [`operator ValueType`](../basic_json/operator_ValueType.md).
|
value directly affects [`operator ValueType`](../basic_json/operator_ValueType.md) and the
|
||||||
|
[converting constructor](../basic_json/basic_json.md) from a `basic_json` specialization with a different string
|
||||||
|
type (overload 4).
|
||||||
|
|
||||||
## Default definition
|
## Default definition
|
||||||
|
|
||||||
@@ -57,6 +59,25 @@ By default, implicit conversions are enabled.
|
|||||||
auto s = j.get<std::string>();
|
auto s = j.get<std::string>();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
??? example "Conversion between `basic_json` specializations"
|
||||||
|
|
||||||
|
A `basic_json` specialization with a different string type is also no longer converted implicitly when
|
||||||
|
`JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
using wjson = nlohmann::basic_json<std::map, std::vector, std::wstring>;
|
||||||
|
|
||||||
|
void load(const nlohmann::json& j);
|
||||||
|
|
||||||
|
wjson wj = /* ... */;
|
||||||
|
load(wj); // error: no implicit conversion
|
||||||
|
load(nlohmann::json(wj)); // OK: explicit conversion
|
||||||
|
load(wj.get<nlohmann::json>()); // OK: explicit conversion
|
||||||
|
```
|
||||||
|
|
||||||
|
Specializations that share the same string type, such as `json` and `ordered_json`, remain implicitly
|
||||||
|
convertible.
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [**operator ValueType**](../basic_json/operator_ValueType.md) - get a value (implicit)
|
- [**operator ValueType**](../basic_json/operator_ValueType.md) - get a value (implicit)
|
||||||
@@ -66,3 +87,4 @@ By default, implicit conversions are enabled.
|
|||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 3.9.0.
|
- Added in version 3.9.0.
|
||||||
|
- Also affects the conversion between `basic_json` specializations with different string types since version 3.13.0.
|
||||||
|
|||||||
@@ -16,15 +16,14 @@ before including the `json.hpp` header.
|
|||||||
|
|
||||||
## Function with runtime assertions
|
## Function with runtime assertions
|
||||||
|
|
||||||
### Unchecked access to a const value
|
### Unchecked object access to a const value
|
||||||
|
|
||||||
Function [`operator[]`](../api/basic_json/operator%5B%5D.md) implements unchecked access for arrays and objects. Whereas
|
Function [`operator[]`](../api/basic_json/operator%5B%5D.md) implements unchecked access for objects. Whereas a missing
|
||||||
a missing element is added in the case of non-const values, accessing a const value with a missing object key or an
|
key is added in the case of non-const objects, accessing a const object with a missing key is undefined behavior (think
|
||||||
invalid array index is undefined behavior (think of a dereferenced null pointer) and yields a runtime assertion. This
|
of a dereferenced null pointer) and yields a runtime assertion.
|
||||||
also applies to a [JSON pointer](json_pointer.md) that refers to a missing key or an invalid index.
|
|
||||||
|
|
||||||
If you are not sure whether an element exists, use checked access with the [`at` function](../api/basic_json/at.md)
|
If you are not sure whether an element in an object exists, use checked access with the
|
||||||
or call the [`contains` function](../api/basic_json/contains.md) before.
|
[`at` function](../api/basic_json/at.md) or call the [`contains` function](../api/basic_json/contains.md) before.
|
||||||
|
|
||||||
See also the documentation on [element access](element_access/index.md).
|
See also the documentation on [element access](element_access/index.md).
|
||||||
|
|
||||||
@@ -47,30 +46,7 @@ See also the documentation on [element access](element_access/index.md).
|
|||||||
Output:
|
Output:
|
||||||
|
|
||||||
```
|
```
|
||||||
Assertion failed: (it != m_data.m_value.object->end()), function operator[], file json.hpp, line 28795.
|
Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144.
|
||||||
```
|
|
||||||
|
|
||||||
??? example "Example 2: Invalid array index in a JSON pointer"
|
|
||||||
|
|
||||||
The following code will trigger an assertion at runtime:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
using json = nlohmann::json;
|
|
||||||
using namespace nlohmann::literals;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
const json j = {{"array", {1, 2, 3}}};
|
|
||||||
auto v = j["/array/5"_json_pointer];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Output:
|
|
||||||
|
|
||||||
```
|
|
||||||
Assertion failed: (idx < m_data.m_value.array->size()), function operator[], file json.hpp, line 28758.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Constructing from an uninitialized iterator range
|
### Constructing from an uninitialized iterator range
|
||||||
|
|||||||
@@ -291,7 +291,9 @@ void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept
|
|||||||
{
|
{
|
||||||
if (opt.has_value())
|
if (opt.has_value())
|
||||||
{
|
{
|
||||||
j = *opt;
|
// explicit construction, as the conversion from a basic_json with a different
|
||||||
|
// string type is explicit if JSON_USE_IMPLICIT_CONVERSIONS is 0 (#2649)
|
||||||
|
j = BasicJsonType(*opt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -535,10 +535,6 @@ class json_pointer
|
|||||||
@return const reference to the JSON value pointed to by the JSON
|
@return const reference to the JSON value pointed to by the JSON
|
||||||
pointer
|
pointer
|
||||||
|
|
||||||
@pre Every object key and array index the pointer refers to exists.
|
|
||||||
Like the const operator[] for keys and indices, a missing one is
|
|
||||||
undefined behavior, guarded by a runtime assertion.
|
|
||||||
|
|
||||||
@throw parse_error.106 if an array index begins with '0'
|
@throw parse_error.106 if an array index begins with '0'
|
||||||
@throw parse_error.109 if an array index was not a number
|
@throw parse_error.109 if an array index was not a number
|
||||||
@throw out_of_range.402 if the array index '-' is used
|
@throw out_of_range.402 if the array index '-' is used
|
||||||
@@ -553,8 +549,7 @@ class json_pointer
|
|||||||
{
|
{
|
||||||
case detail::value_t::object:
|
case detail::value_t::object:
|
||||||
{
|
{
|
||||||
// use unchecked object access; the const operator[]
|
// use unchecked object access
|
||||||
// asserts that the key exists
|
|
||||||
ptr = &ptr->operator[](reference_token);
|
ptr = &ptr->operator[](reference_token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -567,8 +562,7 @@ class json_pointer
|
|||||||
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
|
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// use unchecked array access; the const operator[]
|
// use unchecked array access
|
||||||
// asserts that the index exists
|
|
||||||
ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
|
ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1605,12 +1605,42 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// whether a basic_json specialization can be converted implicitly into this one;
|
||||||
|
/// with JSON_USE_IMPLICIT_CONVERSIONS set to 0, this is only the case if both share
|
||||||
|
/// the same string type (see https://github.com/nlohmann/json/issues/2649)
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
using is_implicitly_convertible_basic_json = std::integral_constant < bool,
|
||||||
|
(JSON_USE_IMPLICIT_CONVERSIONS != 0)
|
||||||
|
|| std::is_same<typename BasicJsonType::string_t, string_t>::value >;
|
||||||
|
|
||||||
|
/// tag to select the constructor that performs the conversion from another basic_json specialization
|
||||||
|
struct convert_basic_json_tag {};
|
||||||
|
|
||||||
|
public:
|
||||||
/// @brief create a JSON value from an existing one
|
/// @brief create a JSON value from an existing one
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||||
template < typename BasicJsonType,
|
template < typename BasicJsonType,
|
||||||
detail::enable_if_t <
|
detail::enable_if_t <
|
||||||
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
|
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value
|
||||||
|
&& is_implicitly_convertible_basic_json<BasicJsonType>::value, int > = 0 >
|
||||||
basic_json(const BasicJsonType& val)
|
basic_json(const BasicJsonType& val)
|
||||||
|
: basic_json(val, convert_basic_json_tag{})
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// @brief create a JSON value from an existing one
|
||||||
|
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||||
|
template < typename BasicJsonType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value
|
||||||
|
&& !is_implicitly_convertible_basic_json<BasicJsonType>::value, int > = 0 >
|
||||||
|
explicit basic_json(const BasicJsonType& val)
|
||||||
|
: basic_json(val, convert_basic_json_tag{})
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
basic_json(const BasicJsonType& val, convert_basic_json_tag /*unused*/)
|
||||||
#if JSON_DIAGNOSTIC_POSITIONS
|
#if JSON_DIAGNOSTIC_POSITIONS
|
||||||
: start_position(val.start_pos()),
|
: start_position(val.start_pos()),
|
||||||
end_position(val.end_pos())
|
end_position(val.end_pos())
|
||||||
@@ -1666,6 +1696,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
/// @brief create a container (array or object) from an initializer list
|
/// @brief create a container (array or object) from an initializer list
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||||
basic_json(initializer_list_t init,
|
basic_json(initializer_list_t init,
|
||||||
@@ -2432,7 +2463,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
int > = 0 >
|
int > = 0 >
|
||||||
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
||||||
{
|
{
|
||||||
return *this;
|
return BasicJsonType(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -2571,7 +2602,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
int> = 0>
|
int> = 0>
|
||||||
ValueType & get_to(ValueType& v) const
|
ValueType & get_to(ValueType& v) const
|
||||||
{
|
{
|
||||||
v = *this;
|
v = ValueType(*this);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2866,7 +2897,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
// const operator[] only works for arrays
|
// const operator[] only works for arrays
|
||||||
if (JSON_HEDLEY_LIKELY(is_array()))
|
if (JSON_HEDLEY_LIKELY(is_array()))
|
||||||
{
|
{
|
||||||
JSON_ASSERT(idx < m_data.m_value.array->size());
|
|
||||||
return m_data.m_value.array->operator[](idx);
|
return m_data.m_value.array->operator[](idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6820,7 +6820,9 @@ void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept
|
|||||||
{
|
{
|
||||||
if (opt.has_value())
|
if (opt.has_value())
|
||||||
{
|
{
|
||||||
j = *opt;
|
// explicit construction, as the conversion from a basic_json with a different
|
||||||
|
// string type is explicit if JSON_USE_IMPLICIT_CONVERSIONS is 0 (#2649)
|
||||||
|
j = BasicJsonType(*opt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -19179,10 +19181,6 @@ class json_pointer
|
|||||||
@return const reference to the JSON value pointed to by the JSON
|
@return const reference to the JSON value pointed to by the JSON
|
||||||
pointer
|
pointer
|
||||||
|
|
||||||
@pre Every object key and array index the pointer refers to exists.
|
|
||||||
Like the const operator[] for keys and indices, a missing one is
|
|
||||||
undefined behavior, guarded by a runtime assertion.
|
|
||||||
|
|
||||||
@throw parse_error.106 if an array index begins with '0'
|
@throw parse_error.106 if an array index begins with '0'
|
||||||
@throw parse_error.109 if an array index was not a number
|
@throw parse_error.109 if an array index was not a number
|
||||||
@throw out_of_range.402 if the array index '-' is used
|
@throw out_of_range.402 if the array index '-' is used
|
||||||
@@ -19197,8 +19195,7 @@ class json_pointer
|
|||||||
{
|
{
|
||||||
case detail::value_t::object:
|
case detail::value_t::object:
|
||||||
{
|
{
|
||||||
// use unchecked object access; the const operator[]
|
// use unchecked object access
|
||||||
// asserts that the key exists
|
|
||||||
ptr = &ptr->operator[](reference_token);
|
ptr = &ptr->operator[](reference_token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -19211,8 +19208,7 @@ class json_pointer
|
|||||||
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
|
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// use unchecked array access; the const operator[]
|
// use unchecked array access
|
||||||
// asserts that the index exists
|
|
||||||
ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
|
ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -27494,12 +27490,42 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// whether a basic_json specialization can be converted implicitly into this one;
|
||||||
|
/// with JSON_USE_IMPLICIT_CONVERSIONS set to 0, this is only the case if both share
|
||||||
|
/// the same string type (see https://github.com/nlohmann/json/issues/2649)
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
using is_implicitly_convertible_basic_json = std::integral_constant < bool,
|
||||||
|
(JSON_USE_IMPLICIT_CONVERSIONS != 0)
|
||||||
|
|| std::is_same<typename BasicJsonType::string_t, string_t>::value >;
|
||||||
|
|
||||||
|
/// tag to select the constructor that performs the conversion from another basic_json specialization
|
||||||
|
struct convert_basic_json_tag {};
|
||||||
|
|
||||||
|
public:
|
||||||
/// @brief create a JSON value from an existing one
|
/// @brief create a JSON value from an existing one
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||||
template < typename BasicJsonType,
|
template < typename BasicJsonType,
|
||||||
detail::enable_if_t <
|
detail::enable_if_t <
|
||||||
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
|
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value
|
||||||
|
&& is_implicitly_convertible_basic_json<BasicJsonType>::value, int > = 0 >
|
||||||
basic_json(const BasicJsonType& val)
|
basic_json(const BasicJsonType& val)
|
||||||
|
: basic_json(val, convert_basic_json_tag{})
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// @brief create a JSON value from an existing one
|
||||||
|
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||||
|
template < typename BasicJsonType,
|
||||||
|
detail::enable_if_t <
|
||||||
|
detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value
|
||||||
|
&& !is_implicitly_convertible_basic_json<BasicJsonType>::value, int > = 0 >
|
||||||
|
explicit basic_json(const BasicJsonType& val)
|
||||||
|
: basic_json(val, convert_basic_json_tag{})
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename BasicJsonType>
|
||||||
|
basic_json(const BasicJsonType& val, convert_basic_json_tag /*unused*/)
|
||||||
#if JSON_DIAGNOSTIC_POSITIONS
|
#if JSON_DIAGNOSTIC_POSITIONS
|
||||||
: start_position(val.start_pos()),
|
: start_position(val.start_pos()),
|
||||||
end_position(val.end_pos())
|
end_position(val.end_pos())
|
||||||
@@ -27555,6 +27581,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
assert_invariant();
|
assert_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
/// @brief create a container (array or object) from an initializer list
|
/// @brief create a container (array or object) from an initializer list
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
/// @sa https://json.nlohmann.me/api/basic_json/basic_json/
|
||||||
basic_json(initializer_list_t init,
|
basic_json(initializer_list_t init,
|
||||||
@@ -28321,7 +28348,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
int > = 0 >
|
int > = 0 >
|
||||||
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
||||||
{
|
{
|
||||||
return *this;
|
return BasicJsonType(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -28460,7 +28487,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
int> = 0>
|
int> = 0>
|
||||||
ValueType & get_to(ValueType& v) const
|
ValueType & get_to(ValueType& v) const
|
||||||
{
|
{
|
||||||
v = *this;
|
v = ValueType(*this);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28755,7 +28782,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
// const operator[] only works for arrays
|
// const operator[] only works for arrays
|
||||||
if (JSON_HEDLEY_LIKELY(is_array()))
|
if (JSON_HEDLEY_LIKELY(is_array()))
|
||||||
{
|
{
|
||||||
JSON_ASSERT(idx < m_data.m_value.array->size());
|
|
||||||
return m_data.m_value.array->operator[](idx);
|
return m_data.m_value.array->operator[](idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -374,4 +375,39 @@ TEST_CASE("alternative string type")
|
|||||||
const auto j2 = j.flatten();
|
const auto j2 = j.flatten();
|
||||||
CHECK(j2.dump() == R"({"/foo/0":"bar","/foo/1":"baz"})");
|
CHECK(j2.dump() == R"({"/foo/0":"bar","/foo/1":"baz"})");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("conversion between basic_json specializations (#2649)")
|
||||||
|
{
|
||||||
|
// explicit conversions are always possible
|
||||||
|
CHECK(std::is_constructible<nlohmann::json, alt_json>::value);
|
||||||
|
CHECK(std::is_constructible<alt_json, nlohmann::json>::value);
|
||||||
|
CHECK(std::is_constructible<nlohmann::json, nlohmann::ordered_json>::value);
|
||||||
|
CHECK(std::is_constructible<nlohmann::ordered_json, nlohmann::json>::value);
|
||||||
|
|
||||||
|
// specializations with the same string type are implicitly convertible
|
||||||
|
CHECK(std::is_convertible<nlohmann::ordered_json, nlohmann::json>::value);
|
||||||
|
CHECK(std::is_convertible<nlohmann::json, nlohmann::ordered_json>::value);
|
||||||
|
|
||||||
|
// specializations with different string types are only implicitly convertible
|
||||||
|
// if implicit conversions are enabled
|
||||||
|
#if JSON_USE_IMPLICIT_CONVERSIONS
|
||||||
|
CHECK(std::is_convertible<alt_json, nlohmann::json>::value);
|
||||||
|
CHECK(std::is_convertible<nlohmann::json, alt_json>::value);
|
||||||
|
#else
|
||||||
|
CHECK_FALSE(std::is_convertible<alt_json, nlohmann::json>::value);
|
||||||
|
CHECK_FALSE(std::is_convertible<nlohmann::json, alt_json>::value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// get<BasicJsonType>() works in either case
|
||||||
|
const nlohmann::json j = {{"foo", 1}, {"bar", true}};
|
||||||
|
CHECK(j.get<nlohmann::ordered_json>() == nlohmann::ordered_json(j));
|
||||||
|
// (only a number is converted here, as objects and strings are affected by #3425)
|
||||||
|
CHECK(nlohmann::json(42).get<alt_json>() == 42);
|
||||||
|
CHECK(alt_json(nlohmann::json(42)) == 42);
|
||||||
|
|
||||||
|
// get_to() also works in either case
|
||||||
|
alt_json a;
|
||||||
|
nlohmann::json(42).get_to(a);
|
||||||
|
CHECK(a == 42);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user