Workaround broken is_default_constructible in MSVC

This commit is contained in:
Victor Zverovich
2019-01-21 09:54:48 -08:00
parent 5f1ceebc7f
commit 7cdb1e5e40

View File

@ -333,22 +333,19 @@ struct error_handler {
// GCC 4.6.x cannot expand `T...`. // GCC 4.6.x cannot expand `T...`.
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 407 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 407
template <typename... T> struct is_constructible : std::false_type {};
typedef char yes[1]; typedef char yes[1];
typedef char no[2]; typedef char no[2];
template <typename T> struct is_default_constructible { template <typename T, typename V> struct is_constructible {
template <typename U> static yes& test(int (*)[sizeof(new U)]); template <typename U> static yes& test(int (*)[sizeof(new U(declval<V>()))]);
template <typename U> static no& test(...); template <typename U> static no& test(...);
enum { value = sizeof(test<T>(FMT_NULL)) == sizeof(yes) }; enum { value = sizeof(test<T>(FMT_NULL)) == sizeof(yes) };
}; };
#else #else
template <typename... T> template <typename... T>
struct is_constructible : std::is_constructible<T...> {}; struct is_constructible : std::is_constructible<T...> {};
template <typename T>
struct is_default_constructible : std::is_default_constructible<T> {};
#endif #endif
struct dummy_formatter_arg {}; // Workaround broken is_constructible in MSVC.
} // namespace internal } // namespace internal
/** /**
@ -506,7 +503,7 @@ template <typename Context> class basic_format_args;
// A formatter for objects of type T. // A formatter for objects of type T.
template <typename T, typename Char = char, typename Enable = void> template <typename T, typename Char = char, typename Enable = void>
struct formatter { struct formatter {
formatter() = delete; explicit formatter(internal::dummy_formatter_arg);
}; };
template <typename T, typename Char, typename Enable = void> template <typename T, typename Char, typename Enable = void>
@ -632,11 +629,12 @@ template <typename Context> class value {
} }
value(const void* val) { pointer = val; } value(const void* val) { pointer = val; }
template <typename T, template <
typename std::enable_if< typename T,
is_default_constructible< typename std::enable_if<
typename Context::template formatter_type<T>::type>::value, !is_constructible<typename Context::template formatter_type<T>::type,
int>::type = 0> internal::dummy_formatter_arg>::value,
int>::type = 0>
explicit value(const T& val) { explicit value(const T& val) {
custom.value = &val; custom.value = &val;
// Get the formatter type through the context to allow different contexts // Get the formatter type through the context to allow different contexts
@ -646,11 +644,12 @@ template <typename Context> class value {
custom.format = &format_custom_arg<T, formatter>; custom.format = &format_custom_arg<T, formatter>;
} }
template <typename T, template <
typename std::enable_if< typename T,
!is_default_constructible< typename std::enable_if<
typename Context::template formatter_type<T>::type>::value, is_constructible<typename Context::template formatter_type<T>::type,
int>::type = 0> internal::dummy_formatter_arg>::value,
int>::type = 0>
explicit value(const T& val) { explicit value(const T& val) {
custom.value = &val; custom.value = &val;
custom.format = custom.format =