mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Fix handling of types convertible to int
This commit is contained in:
16
fmt/format.h
16
fmt/format.h
@ -1171,17 +1171,17 @@ T &get();
|
|||||||
Yes &convert(fmt::ULongLong);
|
Yes &convert(fmt::ULongLong);
|
||||||
No &convert(...);
|
No &convert(...);
|
||||||
|
|
||||||
template<typename T, bool ENABLE_CONVERSION>
|
template <typename T, bool ENABLE_CONVERSION>
|
||||||
struct ConvertToIntImpl {
|
struct ConvertToIntImpl {
|
||||||
enum { value = ENABLE_CONVERSION };
|
enum { value = ENABLE_CONVERSION };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, bool ENABLE_CONVERSION>
|
template <typename T, bool ENABLE_CONVERSION>
|
||||||
struct ConvertToIntImpl2 {
|
struct ConvertToIntImpl2 {
|
||||||
enum { value = false };
|
enum { value = false };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
struct ConvertToIntImpl2<T, true> {
|
struct ConvertToIntImpl2<T, true> {
|
||||||
enum {
|
enum {
|
||||||
// Don't convert numeric types.
|
// Don't convert numeric types.
|
||||||
@ -1189,7 +1189,7 @@ struct ConvertToIntImpl2<T, true> {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
struct ConvertToInt {
|
struct ConvertToInt {
|
||||||
enum {
|
enum {
|
||||||
enable_conversion = sizeof(fmt::internal::convert(get<T>())) == sizeof(Yes)
|
enable_conversion = sizeof(fmt::internal::convert(get<T>())) == sizeof(Yes)
|
||||||
@ -1206,16 +1206,16 @@ FMT_DISABLE_CONVERSION_TO_INT(float);
|
|||||||
FMT_DISABLE_CONVERSION_TO_INT(double);
|
FMT_DISABLE_CONVERSION_TO_INT(double);
|
||||||
FMT_DISABLE_CONVERSION_TO_INT(long double);
|
FMT_DISABLE_CONVERSION_TO_INT(long double);
|
||||||
|
|
||||||
template<bool B, class T = void>
|
template <bool B, class T = void>
|
||||||
struct EnableIf {};
|
struct EnableIf {};
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
struct EnableIf<true, T> { typedef T type; };
|
struct EnableIf<true, T> { typedef T type; };
|
||||||
|
|
||||||
template<bool B, class T, class F>
|
template <bool B, class T, class F>
|
||||||
struct Conditional { typedef T type; };
|
struct Conditional { typedef T type; };
|
||||||
|
|
||||||
template<class T, class F>
|
template <class T, class F>
|
||||||
struct Conditional<false, T, F> { typedef F type; };
|
struct Conditional<false, T, F> { typedef F type; };
|
||||||
|
|
||||||
// For bcc32 which doesn't understand ! in template arguments.
|
// For bcc32 which doesn't understand ! in template arguments.
|
||||||
|
@ -52,13 +52,15 @@ Yes &convert(std::ostream &);
|
|||||||
|
|
||||||
struct DummyStream : std::ostream {
|
struct DummyStream : std::ostream {
|
||||||
DummyStream(); // Suppress a bogus warning in MSVC.
|
DummyStream(); // Suppress a bogus warning in MSVC.
|
||||||
|
|
||||||
// Hide all operator<< overloads from std::ostream.
|
// Hide all operator<< overloads from std::ostream.
|
||||||
void operator<<(Null<>);
|
template <typename T>
|
||||||
|
typename EnableIf<sizeof(T) == 0>::type operator<<(const T &);
|
||||||
};
|
};
|
||||||
|
|
||||||
No &operator<<(std::ostream &, int);
|
No &operator<<(std::ostream &, int);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
struct ConvertToIntImpl<T, true> {
|
struct ConvertToIntImpl<T, true> {
|
||||||
// Convert to int only if T doesn't have an overloaded operator<<.
|
// Convert to int only if T doesn't have an overloaded operator<<.
|
||||||
enum {
|
enum {
|
||||||
|
@ -172,3 +172,18 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
|
|||||||
} while (size != 0);
|
} while (size != 0);
|
||||||
fmt::internal::write(os, w);
|
fmt::internal::write(os, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ConvertibleToInt {
|
||||||
|
template <typename ValueType>
|
||||||
|
operator ValueType() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream &operator<<(std::ostream &o, ConvertibleToInt) {
|
||||||
|
return o << "foo";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(FormatTest, FormatConvertibleToInt) {
|
||||||
|
EXPECT_EQ("foo", fmt::format("{}", ConvertibleToInt()));
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user