mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Improve handling of streamable and convertible to bool types (#1766)
This commit is contained in:
@ -49,17 +49,27 @@ template <class Char> class formatbuf : public std::basic_streambuf<Char> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct converter {
|
||||||
|
template <typename T, FMT_ENABLE_IF(is_integral<T>::value)> converter(T);
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Char> struct test_stream : std::basic_ostream<Char> {
|
template <typename Char> struct test_stream : std::basic_ostream<Char> {
|
||||||
private:
|
private:
|
||||||
// Hide all operator<< from std::basic_ostream<Char>.
|
void_t<> operator<<(converter);
|
||||||
void_t<> operator<<(null<>);
|
|
||||||
void_t<> operator<<(const Char*);
|
|
||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(std::is_convertible<T, int>::value &&
|
|
||||||
!std::is_enum<T>::value)>
|
|
||||||
void_t<> operator<<(T);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hide insertion operators for built-in types.
|
||||||
|
template <typename Char, typename Traits>
|
||||||
|
void_t<> operator<<(std::basic_ostream<Char, Traits>&, Char);
|
||||||
|
template <typename Char, typename Traits>
|
||||||
|
void_t<> operator<<(std::basic_ostream<Char, Traits>&, char);
|
||||||
|
template <typename Traits>
|
||||||
|
void_t<> operator<<(std::basic_ostream<char, Traits>&, char);
|
||||||
|
template <typename Traits>
|
||||||
|
void_t<> operator<<(std::basic_ostream<char, Traits>&, signed char);
|
||||||
|
template <typename Traits>
|
||||||
|
void_t<> operator<<(std::basic_ostream<char, Traits>&, unsigned char);
|
||||||
|
|
||||||
// Checks if T has a user-defined operator<< (e.g. not a member of
|
// Checks if T has a user-defined operator<< (e.g. not a member of
|
||||||
// std::ostream).
|
// std::ostream).
|
||||||
template <typename T, typename Char> class is_streamable {
|
template <typename T, typename Char> class is_streamable {
|
||||||
|
@ -290,9 +290,20 @@ std::ostream& operator<<(std::ostream& os,
|
|||||||
TEST(OStreamTest, FormatExplicitlyConvertibleToStdStringView) {
|
TEST(OStreamTest, FormatExplicitlyConvertibleToStdStringView) {
|
||||||
EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like()));
|
EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FMT_USE_STRING_VIEW
|
#endif // FMT_USE_STRING_VIEW
|
||||||
|
|
||||||
|
struct streamable_and_convertible_to_bool {
|
||||||
|
operator bool() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, streamable_and_convertible_to_bool) {
|
||||||
|
return os << "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(OStreamTest, FormatConvertibleToBool) {
|
||||||
|
EXPECT_EQ("foo", fmt::format("{}", streamable_and_convertible_to_bool()));
|
||||||
|
}
|
||||||
|
|
||||||
struct copyfmt_test {};
|
struct copyfmt_test {};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, copyfmt_test) {
|
std::ostream& operator<<(std::ostream& os, copyfmt_test) {
|
||||||
|
Reference in New Issue
Block a user