Commit 6ebf274c authored by Anthony VH's avatar Anthony VH

Add internal version of is_default_constructible to work around LWG 2367.

parent 672e8bfc
......@@ -149,6 +149,52 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
///////////////////
// is_ functions //
///////////////////
// 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 {};
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
// Based on commit fixing this in gcc: https://github.com/gcc-mirror/gcc/commit/d3c64041b32b6962ad6b2d879231537a477631fb
template <typename T>
struct is_default_constructible : std::is_default_constructible<T> {};
template <typename T1, typename T2>
struct is_default_constructible<std::pair<T1, T2>>
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
template <typename T1, typename T2>
struct is_default_constructible<const std::pair<T1, T2>>
: conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
template <typename... Ts>
struct is_default_constructible<std::tuple<Ts...>>
: conjunction<is_default_constructible<Ts>...> {};
template <typename... Ts>
struct is_default_constructible<const std::tuple<Ts...>>
: conjunction<is_default_constructible<Ts>...> {};
template <typename T, typename... Args>
struct is_constructible : std::is_constructible<T, Args...> {};
template <typename T1, typename T2>
struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
template <typename T1, typename T2>
struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
template <typename... Ts>
struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
template <typename... Ts>
struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
template<typename T, typename = void>
struct is_iterator_traits : std::false_type {};
......@@ -192,9 +238,9 @@ struct is_compatible_object_type_impl <
// macOS's is_constructible does not play well with nonesuch...
static constexpr bool value =
std::is_constructible<typename object_t::key_type,
is_constructible<typename object_t::key_type,
typename CompatibleObjectType::key_type>::value &&
std::is_constructible<typename object_t::mapped_type,
is_constructible<typename object_t::mapped_type,
typename CompatibleObjectType::mapped_type>::value;
};
......@@ -215,10 +261,10 @@ struct is_constructible_object_type_impl <
using object_t = typename BasicJsonType::object_t;
static constexpr bool value =
(std::is_default_constructible<ConstructibleObjectType>::value &&
(is_default_constructible<ConstructibleObjectType>::value &&
(std::is_move_assignable<ConstructibleObjectType>::value ||
std::is_copy_assignable<ConstructibleObjectType>::value) &&
(std::is_constructible<typename ConstructibleObjectType::key_type,
(is_constructible<typename ConstructibleObjectType::key_type,
typename object_t::key_type>::value &&
std::is_same <
typename object_t::mapped_type,
......@@ -246,7 +292,7 @@ struct is_compatible_string_type_impl <
value_type_t, CompatibleStringType>::value >>
{
static constexpr auto value =
std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
};
template<typename BasicJsonType, typename ConstructibleStringType>
......@@ -264,7 +310,7 @@ struct is_constructible_string_type_impl <
value_type_t, ConstructibleStringType>::value >>
{
static constexpr auto value =
std::is_constructible<ConstructibleStringType,
is_constructible<ConstructibleStringType,
typename BasicJsonType::string_t>::value;
};
......@@ -287,7 +333,7 @@ struct is_compatible_array_type_impl <
iterator_traits<CompatibleArrayType >>::value >>
{
static constexpr bool value =
std::is_constructible<BasicJsonType,
is_constructible<BasicJsonType,
typename CompatibleArrayType::value_type>::value;
};
......@@ -310,7 +356,7 @@ struct is_constructible_array_type_impl <
BasicJsonType, ConstructibleArrayType,
enable_if_t < !std::is_same<ConstructibleArrayType,
typename BasicJsonType::value_type>::value&&
std::is_default_constructible<ConstructibleArrayType>::value&&
is_default_constructible<ConstructibleArrayType>::value&&
(std::is_move_assignable<ConstructibleArrayType>::value ||
std::is_copy_assignable<ConstructibleArrayType>::value)&&
is_detected<value_type_t, ConstructibleArrayType>::value&&
......@@ -354,7 +400,7 @@ struct is_compatible_integer_type_impl <
using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
static constexpr auto value =
std::is_constructible<RealIntegerType,
is_constructible<RealIntegerType,
CompatibleNumberIntegerType>::value &&
CompatibleLimits::is_integer &&
RealLimits::is_signed == CompatibleLimits::is_signed;
......@@ -381,17 +427,10 @@ 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>...> {};
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
} // namespace detail
} // namespace nlohmann
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment