Add restriction for tuple specialization of to_json

This commit fix the issue #1825

Signed-off-by: Camille Bégué <c.begue@samsung.com>
This commit is contained in:
Camille Bégué 2019-10-31 18:39:01 +01:00
parent 3790bd9ae0
commit 8b686b30eb
4 changed files with 38 additions and 6 deletions

View file

@ -322,10 +322,10 @@ void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>
j = { std::get<Idx>(t)... };
}
template<typename BasicJsonType, typename... Args>
void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
void to_json(BasicJsonType& j, const T& t)
{
to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
}
struct to_json_fn

View file

@ -357,5 +357,18 @@ struct is_compatible_type_impl <
template <typename BasicJsonType, typename CompatibleType>
struct is_compatible_type
: is_compatible_type_impl<BasicJsonType, CompatibleType> {};
// https://en.cppreference.com/w/cpp/types/conjunction
template<class...> struct conjunction : std::true_type { };
template<class B1> struct conjunction<B1> : B1 { };
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template <typename T1, typename T2>
struct is_constructible_tuple : std::false_type {};
template <typename T1, typename... Args>
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
} // namespace detail
} // namespace nlohmann

View file

@ -2794,6 +2794,19 @@ struct is_compatible_type_impl <
template <typename BasicJsonType, typename CompatibleType>
struct is_compatible_type
: is_compatible_type_impl<BasicJsonType, CompatibleType> {};
// https://en.cppreference.com/w/cpp/types/conjunction
template<class...> struct conjunction : std::true_type { };
template<class B1> struct conjunction<B1> : B1 { };
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template <typename T1, typename T2>
struct is_constructible_tuple : std::false_type {};
template <typename T1, typename... Args>
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
} // namespace detail
} // namespace nlohmann
@ -3753,10 +3766,10 @@ void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>
j = { std::get<Idx>(t)... };
}
template<typename BasicJsonType, typename... Args>
void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
void to_json(BasicJsonType& j, const T& t)
{
to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
}
struct to_json_fn

View file

@ -1842,6 +1842,12 @@ TEST_CASE("regression tests")
static_assert(!std::is_constructible<json, std::pair<NotSerializableData, std::string>>::value, "");
static_assert(std::is_constructible<json, std::pair<int, std::string>>::value, "");
}
SECTION("issue #1825 - A tuple<Args..> is json constructible only if all T in Args are json constructible")
{
static_assert(!std::is_constructible<json, std::tuple<std::string, NotSerializableData>>::value, "");
static_assert(!std::is_constructible<json, std::tuple<NotSerializableData, std::string>>::value, "");
static_assert(std::is_constructible<json, std::tuple<int, std::string>>::value, "");
}
}
#if not defined(JSON_NOEXCEPTION)