mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Workaround broken is_default_constructible in MSVC
This commit is contained in:
@ -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 =
|
||||||
|
Reference in New Issue
Block a user