Skip to content

Commit

Permalink
try to fix gcc bug nlohmann#2
Browse files Browse the repository at this point in the history
  • Loading branch information
oficsu committed Jul 26, 2020
1 parent 700f279 commit 7cb074f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 24 deletions.
6 changes: 3 additions & 3 deletions include/nlohmann/adl_serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ struct adl_serializer
*/
template<typename... Args>
static auto from_json(Args&& ... args) noexcept(
noexcept(::nlohmann::from_json.call(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...)))
-> decltype(::nlohmann::from_json.call(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...))
noexcept(::nlohmann::detail::from_json_impl(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...)))
-> decltype(::nlohmann::detail::from_json_impl(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...))
{
return ::nlohmann::from_json.call(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...);
return ::nlohmann::detail::from_json_impl(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...);
}

/*!
Expand Down
30 changes: 21 additions & 9 deletions include/nlohmann/detail/conversions/from_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,26 +384,27 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
}
}

struct from_json_fn
/// [workaround for gcc](https://gcc.gnu.org/bugzilla/show_bug.cgi?format=multiple&id=52869)
struct from_json_impl_fn
{
template<typename BasicJsonType, typename ValueType, typename... Args>
auto call(adl_tag<ValueType>, detail::priority_tag<1>, BasicJsonType&& j, Args&& ... args) const
auto operator()(adl_tag<ValueType>, detail::priority_tag<1>, BasicJsonType&& j, Args&& ... args) const
noexcept(noexcept(ValueType::from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)...)))
-> decltype(ValueType::from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)...))
{
return ValueType::from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)...);
}

template<typename BasicJsonType, typename ValueType, typename... Args>
auto call(adl_tag<ValueType>, priority_tag<0>, BasicJsonType&& j, Args&& ... args) const
auto operator()(adl_tag<ValueType>, priority_tag<0>, BasicJsonType&& j, Args&& ... args) const
noexcept(noexcept(from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)..., adl_tag<ValueType> {})))
-> decltype (from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)..., adl_tag<ValueType> {}))
{
return from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)..., adl_tag<ValueType> {});
}

template<typename BasicJsonType, typename ValueType, typename ValueTypeCV, typename... Args>
auto call(adl_tag<ValueType>, priority_tag<2>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
auto operator()(adl_tag<ValueType>, priority_tag<2>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
noexcept(noexcept(std::forward<ValueTypeCV>(val).from_json(j, std::forward<Args>(args)...)))
-> decltype (std::forward<ValueTypeCV>(val).from_json(j, std::forward<Args>(args)...), void())
{
Expand All @@ -413,7 +414,7 @@ struct from_json_fn
}

template<typename BasicJsonType, typename ValueType, typename ValueTypeCV, typename... Args>
auto call(adl_tag<ValueType>, priority_tag<1>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
auto operator()(adl_tag<ValueType>, priority_tag<1>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
noexcept(noexcept(uncvref_t<ValueType>::from_json(std::forward<BasicJsonType>(j), std::forward<ValueTypeCV>(val), std::forward<Args>(args)...)))
-> decltype(uncvref_t<ValueType>::from_json(std::forward<BasicJsonType>(j), std::forward<ValueTypeCV>(val), std::forward<Args>(args)...), void())
{
Expand All @@ -423,22 +424,33 @@ struct from_json_fn
}

template<typename BasicJsonType, typename ValueType, typename ValueTypeCV, typename... Args>
auto call(adl_tag<ValueType>, priority_tag<0>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
auto operator()(adl_tag<ValueType>, priority_tag<0>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
noexcept(noexcept(from_json(j, std::forward<ValueTypeCV>(val), std::forward<Args>(args)...)))
-> decltype(from_json(j, std::forward<ValueTypeCV>(val), std::forward<Args>(args)...), void())
{
static_assert(std::is_same<uncvref_t<ValueType>, uncvref_t<ValueTypeCV>>::value,
"ValueType and ValueTypeCV should be same");
from_json(j, std::forward<ValueTypeCV>(val), std::forward<Args>(args)...);
}
};

/// namespace to hold default `from_json` function
/// to see why this is required:
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
namespace
{
constexpr const auto& from_json_impl = detail::static_const<detail::from_json_impl_fn>::value;
} // namespace

struct from_json_fn
{
//
template<typename BasicJsonType, typename ValueType, typename... Args>
auto operator()(BasicJsonType&& j, ValueType&& val, Args&& ... args) const
noexcept(noexcept(call(adl_tag<ValueType> {}, max_priority_t{}, j, val, std::forward<Args>(args)...)))
-> decltype(call(adl_tag<uncvref_t<ValueType>> {}, max_priority_t{}, j, val, std::forward<Args>(args)...), void())
noexcept(noexcept(from_json_impl(adl_tag<ValueType> {}, max_priority_t{}, j, val, std::forward<Args>(args)...)))
-> decltype(from_json_impl(adl_tag<uncvref_t<ValueType>> {}, max_priority_t{}, j, val, std::forward<Args>(args)...), void())
{
call(adl_tag<uncvref_t<ValueType>> {}, max_priority_t{}, j, val, std::forward<Args>(args)...);
from_json_impl(adl_tag<uncvref_t<ValueType>> {}, max_priority_t{}, j, val, std::forward<Args>(args)...);
}
};
} // namespace detail
Expand Down
36 changes: 24 additions & 12 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3806,26 +3806,27 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
}
}

struct from_json_fn
/// [workaround for gcc](https://gcc.gnu.org/bugzilla/show_bug.cgi?format=multiple&id=52869)
struct from_json_impl_fn
{
template<typename BasicJsonType, typename ValueType, typename... Args>
auto call(adl_tag<ValueType>, detail::priority_tag<1>, BasicJsonType&& j, Args&& ... args) const
auto operator()(adl_tag<ValueType>, detail::priority_tag<1>, BasicJsonType&& j, Args&& ... args) const
noexcept(noexcept(ValueType::from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)...)))
-> decltype(ValueType::from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)...))
{
return ValueType::from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)...);
}

template<typename BasicJsonType, typename ValueType, typename... Args>
auto call(adl_tag<ValueType>, priority_tag<0>, BasicJsonType&& j, Args&& ... args) const
auto operator()(adl_tag<ValueType>, priority_tag<0>, BasicJsonType&& j, Args&& ... args) const
noexcept(noexcept(from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)..., adl_tag<ValueType> {})))
-> decltype (from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)..., adl_tag<ValueType> {}))
{
return from_json(std::forward<BasicJsonType>(j), std::forward<Args>(args)..., adl_tag<ValueType> {});
}

template<typename BasicJsonType, typename ValueType, typename ValueTypeCV, typename... Args>
auto call(adl_tag<ValueType>, priority_tag<2>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
auto operator()(adl_tag<ValueType>, priority_tag<2>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
noexcept(noexcept(std::forward<ValueTypeCV>(val).from_json(j, std::forward<Args>(args)...)))
-> decltype (std::forward<ValueTypeCV>(val).from_json(j, std::forward<Args>(args)...), void())
{
Expand All @@ -3835,7 +3836,7 @@ struct from_json_fn
}

template<typename BasicJsonType, typename ValueType, typename ValueTypeCV, typename... Args>
auto call(adl_tag<ValueType>, priority_tag<1>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
auto operator()(adl_tag<ValueType>, priority_tag<1>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
noexcept(noexcept(uncvref_t<ValueType>::from_json(std::forward<BasicJsonType>(j), std::forward<ValueTypeCV>(val), std::forward<Args>(args)...)))
-> decltype(uncvref_t<ValueType>::from_json(std::forward<BasicJsonType>(j), std::forward<ValueTypeCV>(val), std::forward<Args>(args)...), void())
{
Expand All @@ -3845,22 +3846,33 @@ struct from_json_fn
}

template<typename BasicJsonType, typename ValueType, typename ValueTypeCV, typename... Args>
auto call(adl_tag<ValueType>, priority_tag<0>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
auto operator()(adl_tag<ValueType>, priority_tag<0>, BasicJsonType&& j, ValueTypeCV&& val, Args&& ... args) const
noexcept(noexcept(from_json(j, std::forward<ValueTypeCV>(val), std::forward<Args>(args)...)))
-> decltype(from_json(j, std::forward<ValueTypeCV>(val), std::forward<Args>(args)...), void())
{
static_assert(std::is_same<uncvref_t<ValueType>, uncvref_t<ValueTypeCV>>::value,
"ValueType and ValueTypeCV should be same");
from_json(j, std::forward<ValueTypeCV>(val), std::forward<Args>(args)...);
}
};

/// namespace to hold default `from_json` function
/// to see why this is required:
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
namespace
{
constexpr const auto& from_json_impl = detail::static_const<detail::from_json_impl_fn>::value;
} // namespace

struct from_json_fn
{
//
template<typename BasicJsonType, typename ValueType, typename... Args>
auto operator()(BasicJsonType&& j, ValueType&& val, Args&& ... args) const
noexcept(noexcept(call(adl_tag<ValueType> {}, max_priority_t{}, j, val, std::forward<Args>(args)...)))
-> decltype(call(adl_tag<uncvref_t<ValueType>> {}, max_priority_t{}, j, val, std::forward<Args>(args)...), void())
noexcept(noexcept(from_json_impl(adl_tag<ValueType> {}, max_priority_t{}, j, val, std::forward<Args>(args)...)))
-> decltype(from_json_impl(adl_tag<uncvref_t<ValueType>> {}, max_priority_t{}, j, val, std::forward<Args>(args)...), void())
{
call(adl_tag<uncvref_t<ValueType>> {}, max_priority_t{}, j, val, std::forward<Args>(args)...);
from_json_impl(adl_tag<uncvref_t<ValueType>> {}, max_priority_t{}, j, val, std::forward<Args>(args)...);
}
};
} // namespace detail
Expand Down Expand Up @@ -4449,10 +4461,10 @@ struct adl_serializer
*/
template<typename... Args>
static auto from_json(Args&& ... args) noexcept(
noexcept(::nlohmann::from_json.call(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...)))
-> decltype(::nlohmann::from_json.call(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...))
noexcept(::nlohmann::detail::from_json_impl(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...)))
-> decltype(::nlohmann::detail::from_json_impl(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...))
{
return ::nlohmann::from_json.call(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...);
return ::nlohmann::detail::from_json_impl(adl_tag<ValueType> {}, detail::max_priority_t{}, std::forward<Args>(args)...);
}

/*!
Expand Down

0 comments on commit 7cb074f

Please sign in to comment.