mirror of
https://github.com/nlohmann/json.git
synced 2026-10-06 14:40:32 +00:00
Fix std::terminate when converting std::optional with MSVC 2017
MSVC 2017 evaluates std::is_nothrow_assignable<json&, const T&> as true even if T's to_json throws, so to_json(json&, const std::optional<T>&) was noexcept there and the exception from #5642's test called std::terminate instead of propagating. Make that conversion never noexcept on MSVC 2017; all other compilers keep the exact condition. The static_asserts on the condition are skipped for MSVC 2017; the runtime check that the exception propagates still runs there. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
3 files changed
+27
-5
No files matched your search
@@ -287,9 +287,20 @@ struct external_constructor<value_t::object>
|
||||
/////////////
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
// whether storing the value of a std::optional<T> cannot throw; MSVC 2017
|
||||
// evaluates std::is_nothrow_assignable as true even if T's to_json throws, so
|
||||
// the exception would call std::terminate (#5642)
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1920
|
||||
template<typename BasicJsonType, typename T>
|
||||
using is_nothrow_optional_to_json = std::false_type;
|
||||
#else
|
||||
template<typename BasicJsonType, typename T>
|
||||
using is_nothrow_optional_to_json = std::is_nothrow_assignable<BasicJsonType&, const T&>;
|
||||
#endif
|
||||
|
||||
template<typename BasicJsonType, typename T,
|
||||
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
|
||||
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(std::is_nothrow_assignable<BasicJsonType&, const T&>::value)
|
||||
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept(is_nothrow_optional_to_json<BasicJsonType, T>::value)
|
||||
{
|
||||
if (opt.has_value())
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user