make from_json SFINAE-correct

This commit is contained in:
Théo DELRIEU 2018-09-06 16:54:42 +02:00
parent f7971f04a5
commit 4b4bbceebf
No known key found for this signature in database
GPG key ID: 7D6E00D1DF01DEAF
4 changed files with 16 additions and 56 deletions

View file

@ -20,8 +20,10 @@ struct adl_serializer
@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 ValueType>
static void from_json(BasicJsonType&& j, ValueType& val) noexcept( static auto from_json(BasicJsonType&& j, ValueType& 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()
)
{ {
::nlohmann::from_json(std::forward<BasicJsonType>(j), val); ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
} }

View file

@ -218,8 +218,8 @@ template <typename BasicJsonType, typename CompatibleArrayType,
auto from_json(const BasicJsonType& j, CompatibleArrayType& arr) auto from_json(const BasicJsonType& j, CompatibleArrayType& arr)
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
j.template get<typename CompatibleArrayType::value_type>(), j.template get<typename CompatibleArrayType::value_type>(),
void()) void())
{ {
if (JSON_UNLIKELY(not j.is_array())) if (JSON_UNLIKELY(not j.is_array()))
{ {
@ -350,35 +350,13 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
struct from_json_fn struct from_json_fn
{ {
private:
template<typename BasicJsonType, typename T> template<typename BasicJsonType, typename T>
auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const auto operator()(const BasicJsonType& j, T& val) const
noexcept(noexcept(from_json(j, val))) noexcept(noexcept(from_json(j, val)))
-> decltype(from_json(j, val), void()) -> decltype(from_json(j, val), void())
{ {
return from_json(j, val); return from_json(j, val);
} }
template<typename BasicJsonType, typename T>
void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
{
static_assert(sizeof(BasicJsonType) == 0,
"could not find from_json() method in T's namespace");
#ifdef _MSC_VER
// MSVC does not show a stacktrace for the above assert
using decayed = uncvref_t<T>;
static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
"forcing MSVC stacktrace to show which T we're talking about.");
#endif
}
public:
template<typename BasicJsonType, typename T>
void operator()(const BasicJsonType& j, T& val) const
noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
{
return call(j, val, priority_tag<1> {});
}
}; };
} }

View file

@ -1212,8 +1212,8 @@ template <typename BasicJsonType, typename CompatibleArrayType,
auto from_json(const BasicJsonType& j, CompatibleArrayType& arr) auto from_json(const BasicJsonType& j, CompatibleArrayType& arr)
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
j.template get<typename CompatibleArrayType::value_type>(), j.template get<typename CompatibleArrayType::value_type>(),
void()) void())
{ {
if (JSON_UNLIKELY(not j.is_array())) if (JSON_UNLIKELY(not j.is_array()))
{ {
@ -1344,35 +1344,13 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
struct from_json_fn struct from_json_fn
{ {
private:
template<typename BasicJsonType, typename T> template<typename BasicJsonType, typename T>
auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const auto operator()(const BasicJsonType& j, T& val) const
noexcept(noexcept(from_json(j, val))) noexcept(noexcept(from_json(j, val)))
-> decltype(from_json(j, val), void()) -> decltype(from_json(j, val), void())
{ {
return from_json(j, val); return from_json(j, val);
} }
template<typename BasicJsonType, typename T>
void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
{
static_assert(sizeof(BasicJsonType) == 0,
"could not find from_json() method in T's namespace");
#ifdef _MSC_VER
// MSVC does not show a stacktrace for the above assert
using decayed = uncvref_t<T>;
static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
"forcing MSVC stacktrace to show which T we're talking about.");
#endif
}
public:
template<typename BasicJsonType, typename T>
void operator()(const BasicJsonType& j, T& val) const
noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
{
return call(j, val, priority_tag<1> {});
}
}; };
} }
@ -11112,8 +11090,10 @@ struct adl_serializer
@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 ValueType>
static void from_json(BasicJsonType&& j, ValueType& val) noexcept( static auto from_json(BasicJsonType&& j, ValueType& 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()
)
{ {
::nlohmann::from_json(std::forward<BasicJsonType>(j), val); ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
} }

View file

@ -317,8 +317,8 @@ TEST_CASE("object inspection")
SECTION("round trips") SECTION("round trips")
{ {
for (const auto& s : for (const auto& s :
{"3.141592653589793", "1000000000000000010E5" {"3.141592653589793", "1000000000000000010E5"
}) })
{ {
json j1 = json::parse(s); json j1 = json::parse(s);
std::string s1 = j1.dump(); std::string s1 = j1.dump();