mirror of
https://github.com/nlohmann/json.git
synced 2025-07-28 12:02:00 +03:00
Fix issue #1237
* Make the conversion operator SFINAE correct. * Workaround a GCC bug with some traits in type_traits.hpp The first bullet-point implies that every `get`/`get_ptr` be SFINAE correct as well.
This commit is contained in:
@ -2623,6 +2623,53 @@ class basic_json
|
||||
return JSONSerializer<ValueTypeCV>::from_json(*this);
|
||||
}
|
||||
|
||||
/*!
|
||||
@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 and
|
||||
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)
|
||||
|
||||
@ -2652,7 +2699,7 @@ class basic_json
|
||||
*/
|
||||
template<typename PointerType, typename std::enable_if<
|
||||
std::is_pointer<PointerType>::value, int>::type = 0>
|
||||
PointerType get() noexcept
|
||||
auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
|
||||
{
|
||||
// delegate the call to get_ptr
|
||||
return get_ptr<PointerType>();
|
||||
@ -2664,89 +2711,12 @@ class basic_json
|
||||
*/
|
||||
template<typename PointerType, typename std::enable_if<
|
||||
std::is_pointer<PointerType>::value, int>::type = 0>
|
||||
constexpr const PointerType get() const noexcept
|
||||
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 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>
|
||||
PointerType get_ptr() noexcept
|
||||
{
|
||||
// get the type of the PointerType (remove pointer and const)
|
||||
using pointee_t = typename std::remove_const<typename
|
||||
std::remove_pointer<typename
|
||||
std::remove_const<PointerType>::type>::type>::type;
|
||||
// make sure the type matches the allowed types
|
||||
static_assert(
|
||||
std::is_same<object_t, pointee_t>::value
|
||||
or std::is_same<array_t, pointee_t>::value
|
||||
or std::is_same<string_t, pointee_t>::value
|
||||
or std::is_same<boolean_t, pointee_t>::value
|
||||
or std::is_same<number_integer_t, pointee_t>::value
|
||||
or std::is_same<number_unsigned_t, pointee_t>::value
|
||||
or std::is_same<number_float_t, pointee_t>::value
|
||||
, "incompatible pointer type");
|
||||
|
||||
// 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 and
|
||||
std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
|
||||
constexpr const PointerType get_ptr() const noexcept
|
||||
{
|
||||
// get the type of the PointerType (remove pointer and const)
|
||||
using pointee_t = typename std::remove_const<typename
|
||||
std::remove_pointer<typename
|
||||
std::remove_const<PointerType>::type>::type>::type;
|
||||
// make sure the type matches the allowed types
|
||||
static_assert(
|
||||
std::is_same<object_t, pointee_t>::value
|
||||
or std::is_same<array_t, pointee_t>::value
|
||||
or std::is_same<string_t, pointee_t>::value
|
||||
or std::is_same<boolean_t, pointee_t>::value
|
||||
or std::is_same<number_integer_t, pointee_t>::value
|
||||
or std::is_same<number_unsigned_t, pointee_t>::value
|
||||
or std::is_same<number_float_t, pointee_t>::value
|
||||
, "incompatible pointer type");
|
||||
|
||||
// delegate the call to get_impl_ptr<>() const
|
||||
return get_impl_ptr(static_cast<PointerType>(nullptr));
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief get a reference value (implicit)
|
||||
|
||||
@ -2828,12 +2798,14 @@ class basic_json
|
||||
not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
|
||||
not std::is_same<ValueType, typename string_t::value_type>::value and
|
||||
not detail::is_basic_json<ValueType>::value
|
||||
|
||||
#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
|
||||
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
|
||||
#if defined(JSON_HAS_CPP_17) && defined(_MSC_VER) and _MSC_VER <= 1914
|
||||
and not std::is_same<ValueType, typename std::string_view>::value
|
||||
#endif
|
||||
#endif
|
||||
and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
|
||||
, int >::type = 0 >
|
||||
operator ValueType() const
|
||||
{
|
||||
|
Reference in New Issue
Block a user