Fix handling of formattable types with to_string_view (#2181)

This commit is contained in:
Victor Zverovich 2021-03-19 06:43:38 -07:00
parent 6ae402fd0b
commit 14a2a64df4
2 changed files with 28 additions and 2 deletions

View File

@ -203,8 +203,7 @@ FMT_END_NAMESPACE
// Some compilers masquerade as both MSVC and GCC-likes or otherwise support // Some compilers masquerade as both MSVC and GCC-likes or otherwise support
// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
// MSVC intrinsics if the clz and clzll builtins are not available. // MSVC intrinsics if the clz and clzll builtins are not available.
#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && \ #if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(FMT_BUILTIN_CTZLL)
!defined(FMT_BUILTIN_CTZLL)
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
namespace detail { namespace detail {
// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
@ -2103,6 +2102,12 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view<Char> value) {
return base_iterator(out, it); return base_iterator(out, it);
} }
template <typename Char, typename OutputIt, typename T,
FMT_ENABLE_IF(is_string<T>::value)>
constexpr OutputIt write(OutputIt out, const T& value) {
return write<Char>(out, to_string_view(value));
}
template <typename Char, typename OutputIt, typename T, template <typename Char, typename OutputIt, typename T,
FMT_ENABLE_IF(is_integral<T>::value && FMT_ENABLE_IF(is_integral<T>::value &&
!std::is_same<T, bool>::value && !std::is_same<T, bool>::value &&

View File

@ -288,6 +288,27 @@ TEST(CompileTest, UnknownFormatFallback) {
} }
TEST(CompileTest, Empty) { EXPECT_EQ("", fmt::format(FMT_COMPILE(""))); } TEST(CompileTest, Empty) { EXPECT_EQ("", fmt::format(FMT_COMPILE(""))); }
struct to_stringable {
friend fmt::string_view to_string_view(to_stringable) { return {}; }
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<to_stringable> {
auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const to_stringable&, FormatContext& ctx) -> decltype(ctx.out()) {
return ctx.out();
}
};
FMT_END_NAMESPACE
TEST(CompileTest, ToStringAndFormatter) {
fmt::format(FMT_COMPILE("{}"), to_stringable());
}
#endif #endif
#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS