mirror of
https://github.com/nlohmann/json.git
synced 2025-08-07 18:02:57 +03:00
Refactor json::get() to use priority_tag.
This commit is contained in:
@@ -2838,50 +2838,53 @@ class basic_json
|
|||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief get special-case overload
|
@brief get a pointer value (implicit)
|
||||||
|
|
||||||
This overloads avoids a lot of template boilerplate, it can be seen as the
|
Implicit pointer access to the internally stored JSON value. No copies are
|
||||||
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 @tparam 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)
|
||||||
|
|
||||||
@@ -2923,21 +2926,12 @@ class basic_json
|
|||||||
*/
|
*/
|
||||||
template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
|
template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
|
||||||
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;
|
||||||
@@ -2975,15 +2969,142 @@ class basic_json
|
|||||||
@since version 2.1.0
|
@since version 2.1.0
|
||||||
*/
|
*/
|
||||||
template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
|
template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
|
||||||
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&>())))
|
||||||
{
|
{
|
||||||
|
return JSONSerializer<ValueType>::from_json(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief get special-case overload
|
||||||
|
|
||||||
|
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 @tparam BasicJsonType
|
||||||
|
|
||||||
|
@complexity Depending on the implementation of the called `from_json()`
|
||||||
|
method.
|
||||||
|
|
||||||
|
@since version 3.2.0
|
||||||
|
*/
|
||||||
|
template < typename BasicJsonType, detail::enable_if_t <
|
||||||
|
detail::is_basic_json<BasicJsonType>::value,
|
||||||
|
int > = 0 >
|
||||||
|
BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief get special-case overload
|
||||||
|
|
||||||
|
This overloads avoids a lot of template boilerplate, it can be seen as the
|
||||||
|
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>
|
||||||
|
basic_json get_impl(detail::priority_tag<3> /*unused*/) const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief get a pointer value (explicit)
|
||||||
|
@copydoc get()
|
||||||
|
*/
|
||||||
|
template<typename PointerType, detail::enable_if_t<
|
||||||
|
std::is_pointer<PointerType>::value, int> = 0>
|
||||||
|
constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
|
||||||
|
-> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
|
||||||
|
{
|
||||||
|
// delegate the call to get_ptr
|
||||||
|
return get_ptr<PointerType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
@brief get a (pointer) value (explicit)
|
||||||
|
|
||||||
|
Performs explicit type conversion between the JSON value and a compatible value if required.
|
||||||
|
|
||||||
|
- If the requested type is a pointer to the internally stored JSON value that pointer is returned.
|
||||||
|
No copies are made.
|
||||||
|
|
||||||
|
- If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
|
||||||
|
from the current @ref basic_json.
|
||||||
|
|
||||||
|
- Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
|
||||||
|
method.
|
||||||
|
|
||||||
|
@tparam ValueTypeCV the provided value type
|
||||||
|
@tparam ValueType the returned value type
|
||||||
|
|
||||||
|
@return copy of the JSON value, converted to @tparam ValueType if necessary
|
||||||
|
|
||||||
|
@throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
|
||||||
|
|
||||||
|
@since version 2.1.0
|
||||||
|
*/
|
||||||
|
template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
|
||||||
|
constexpr auto get() const noexcept(noexcept(get_impl<ValueType>(detail::priority_tag<4> {})))
|
||||||
|
-> decltype(get_impl<ValueType>(detail::priority_tag<4> {}))
|
||||||
|
{
|
||||||
|
// 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,
|
static_assert(!std::is_reference<ValueTypeCV>::value,
|
||||||
"get() cannot be used with reference types, you might want to use get_ref()");
|
"get() cannot be used with reference types, you might want to use get_ref()");
|
||||||
return JSONSerializer<ValueType>::from_json(*this);
|
return get_impl<ValueType>(detail::priority_tag<4> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief get a pointer value (explicit)
|
||||||
|
|
||||||
|
Explicit pointer access to the internally stored JSON value. No copies are
|
||||||
|
made.
|
||||||
|
|
||||||
|
@warning The pointer becomes invalid if the underlying JSON object
|
||||||
|
changes.
|
||||||
|
|
||||||
|
@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.
|
||||||
|
|
||||||
|
@return pointer to the internally stored JSON value if the requested
|
||||||
|
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
|
||||||
|
|
||||||
|
@complexity Constant.
|
||||||
|
|
||||||
|
@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__PointerType}
|
||||||
|
|
||||||
|
@sa @ref get_ptr() for explicit pointer-member access
|
||||||
|
|
||||||
|
@since version 1.0.0
|
||||||
|
*/
|
||||||
|
template<typename PointerType, typename std::enable_if<
|
||||||
|
std::is_pointer<PointerType>::value, int>::type = 0>
|
||||||
|
auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
|
||||||
|
{
|
||||||
|
// delegate the call to get_ptr
|
||||||
|
return get_ptr<PointerType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -3056,101 +3177,6 @@ class basic_json
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief get a pointer value (implicit)
|
|
||||||
|
|
||||||
Implicit pointer access to the internally stored JSON value. No copies are
|
|
||||||
made.
|
|
||||||
|
|
||||||
@warning Writing data to the pointee of the result yields an undefined
|
|
||||||
state.
|
|
||||||
|
|
||||||
@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.
|
|
||||||
|
|
||||||
@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 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief get a pointer value (implicit)
|
|
||||||
@copydoc get_ptr()
|
|
||||||
*/
|
|
||||||
template < typename PointerType, typename std::enable_if <
|
|
||||||
std::is_pointer<PointerType>::value&&
|
|
||||||
std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
|
|
||||||
constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
|
|
||||||
{
|
|
||||||
// delegate the call to get_impl_ptr<>() const
|
|
||||||
return get_impl_ptr(static_cast<PointerType>(nullptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief get a pointer value (explicit)
|
|
||||||
|
|
||||||
Explicit pointer access to the internally stored JSON value. No copies are
|
|
||||||
made.
|
|
||||||
|
|
||||||
@warning The pointer becomes invalid if the underlying JSON object
|
|
||||||
changes.
|
|
||||||
|
|
||||||
@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.
|
|
||||||
|
|
||||||
@return pointer to the internally stored JSON value if the requested
|
|
||||||
pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
|
|
||||||
|
|
||||||
@complexity Constant.
|
|
||||||
|
|
||||||
@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__PointerType}
|
|
||||||
|
|
||||||
@sa @ref get_ptr() for explicit pointer-member access
|
|
||||||
|
|
||||||
@since version 1.0.0
|
|
||||||
*/
|
|
||||||
template<typename PointerType, typename std::enable_if<
|
|
||||||
std::is_pointer<PointerType>::value, int>::type = 0>
|
|
||||||
auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
|
|
||||||
{
|
|
||||||
// delegate the call to get_ptr
|
|
||||||
return get_ptr<PointerType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief get a pointer value (explicit)
|
|
||||||
@copydoc get()
|
|
||||||
*/
|
|
||||||
template<typename PointerType, typename std::enable_if<
|
|
||||||
std::is_pointer<PointerType>::value, int>::type = 0>
|
|
||||||
constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
|
|
||||||
{
|
|
||||||
// delegate the call to get_ptr
|
|
||||||
return get_ptr<PointerType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief get a reference value (implicit)
|
@brief get a reference value (implicit)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user