diff --git a/include/fmt/base.h b/include/fmt/base.h index bc6abaa4..2028d82b 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -2812,29 +2812,29 @@ template struct runtime_format_string { inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; } /// A compile-time format string. -template struct fstring { +template struct fstring { private: static constexpr int num_static_named_args = detail::count_static_named_args(); using checker = detail::format_string_checker< - Char, static_cast(sizeof...(T)), num_static_named_args, + char, static_cast(sizeof...(T)), num_static_named_args, num_static_named_args != detail::count_named_args()>; using arg_pack = detail::arg_pack; public: - basic_string_view str; + string_view str; using t = fstring; // Reports a compile-time error if S is not a valid format string for T. template - FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const Char (&s)[N]) : str(s, N - 1) { + FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) { using namespace detail; static_assert(count<(std::is_base_of>::value && std::is_reference::value)...>() == 0, "passing views as lvalues is disallowed"); - if (FMT_USE_CONSTEVAL) parse_format_string(s, checker(s, arg_pack())); + if (FMT_USE_CONSTEVAL) parse_format_string(s, checker(s, arg_pack())); #ifdef FMT_ENFORCE_COMPILE_STRING static_assert( FMT_USE_CONSTEVAL && sizeof(s) != 0, @@ -2842,11 +2842,10 @@ template struct fstring { #endif } template >::value)> + FMT_ENABLE_IF(std::is_convertible::value)> FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) { if (FMT_USE_CONSTEVAL) - detail::parse_format_string(s, checker(s, arg_pack())); + detail::parse_format_string(s, checker(s, arg_pack())); #ifdef FMT_ENFORCE_COMPILE_STRING static_assert( FMT_USE_CONSTEVAL && sizeof(s) != 0, @@ -2855,23 +2854,21 @@ template struct fstring { } template ::value&& - std::is_same::value)> + std::is_same::value)> FMT_ALWAYS_INLINE fstring(const S&) : str(S()) { - FMT_CONSTEXPR auto sv = basic_string_view(S()); + FMT_CONSTEXPR auto sv = string_view(S()); FMT_CONSTEXPR int ignore = (parse_format_string(sv, checker(sv, arg_pack())), 0); detail::ignore_unused(ignore); } - fstring(runtime_format_string fmt) : str(fmt.str) {} + fstring(runtime_format_string<> fmt) : str(fmt.str) {} // Returning by reference generates better code in debug mode. - FMT_ALWAYS_INLINE operator const basic_string_view&() const { - return str; - } - auto get() const -> basic_string_view { return str; } + FMT_ALWAYS_INLINE operator const string_view&() const { return str; } + auto get() const -> string_view { return str; } }; -template using format_string = typename fstring::t; +template using format_string = typename fstring::t; template using is_formattable = bool_constant< diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index f2b27292..553e9d30 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -65,11 +65,49 @@ using wformat_context = buffered_context; using wformat_args = basic_format_args; using wmemory_buffer = basic_memory_buffer; +template struct basic_fstring { + private: + basic_string_view str_; + + static constexpr int num_static_named_args = + detail::count_static_named_args(); + + using checker = detail::format_string_checker< + Char, static_cast(sizeof...(T)), num_static_named_args, + num_static_named_args != detail::count_named_args()>; + + using arg_pack = detail::arg_pack; + + public: + using t = basic_fstring; + + template >::value)> + FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(const S& s) : str_(s) { + if (FMT_USE_CONSTEVAL) + detail::parse_format_string(s, checker(s, arg_pack())); + } + template ::value&& + std::is_same::value)> + FMT_ALWAYS_INLINE basic_fstring(const S&) : str_(S()) { + FMT_CONSTEXPR auto sv = basic_string_view(S()); + FMT_CONSTEXPR int ignore = + (parse_format_string(sv, checker(sv, arg_pack())), 0); + detail::ignore_unused(ignore); + } + basic_fstring(runtime_format_string fmt) : str_(fmt.str) {} + + operator basic_string_view() const { return str_; } + auto get() const -> basic_string_view { return str_; } +}; + template -using basic_format_string = fstring; +using basic_format_string = basic_fstring; template -using wformat_string = typename fstring::t; +using wformat_string = typename basic_format_string::t; inline auto runtime(wstring_view s) -> runtime_format_string { return {{s}}; } @@ -318,14 +356,12 @@ inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) { } template -void print(std::wostream& os, typename fstring::t fmt, - T&&... args) { +void print(std::wostream& os, wformat_string fmt, T&&... args) { vprint(os, fmt, fmt::make_format_args>(args...)); } template -void println(std::wostream& os, typename fstring::t fmt, - T&&... args) { +void println(std::wostream& os, wformat_string fmt, T&&... args) { print(os, L"{}\n", fmt::format(fmt, std::forward(args)...)); }