diff --git a/include/fmt/base.h b/include/fmt/base.h index cbc6d6b4..2ea13bf5 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -465,15 +465,14 @@ struct is_std_string_like().find_first_of( // Returns true iff the literal encoding is UTF-8. constexpr auto is_utf8_enabled() -> bool { return "\u00A7"[1] == '\xA7'; } -constexpr auto use_utf8() -> bool { - return !FMT_MSC_VERSION || is_utf8_enabled(); -} +// It is a macro for better debug codegen without if constexpr. +#define FMT_USE_UTF8 (!FMT_MSC_VERSION || fmt::detail::is_utf8_enabled()) #ifndef FMT_UNICODE # define FMT_UNICODE 1 #endif -static_assert(!FMT_UNICODE || use_utf8(), +static_assert(!FMT_UNICODE || FMT_USE_UTF8, "Unicode support requires compiling with /utf-8"); template FMT_CONSTEXPR auto length(const Char* s) -> size_t { @@ -3061,7 +3060,7 @@ FMT_API void vprintln(FILE* f, string_view fmt, format_args args); template FMT_INLINE void print(format_string fmt, T&&... args) { const auto& vargs = fmt::make_format_args(args...); - if (!detail::use_utf8()) return detail::vprint_mojibake(stdout, fmt, vargs); + if (!FMT_USE_UTF8) return detail::vprint_mojibake(stdout, fmt, vargs); return detail::is_locking() ? vprint_buffered(stdout, fmt, vargs) : vprint(fmt, vargs); } @@ -3077,7 +3076,7 @@ FMT_INLINE void print(format_string fmt, T&&... args) { template FMT_INLINE void print(FILE* f, format_string fmt, T&&... args) { const auto& vargs = fmt::make_format_args(args...); - if (!detail::use_utf8()) return detail::vprint_mojibake(f, fmt, vargs); + if (!FMT_USE_UTF8) return detail::vprint_mojibake(f, fmt, vargs); return detail::is_locking() ? vprint_buffered(f, fmt, vargs) : vprint(f, fmt, vargs); } @@ -3087,8 +3086,8 @@ FMT_INLINE void print(FILE* f, format_string fmt, T&&... args) { template FMT_INLINE void println(FILE* f, format_string fmt, T&&... args) { const auto& vargs = fmt::make_format_args(args...); - return detail::use_utf8() ? vprintln(f, fmt, vargs) - : detail::vprint_mojibake(f, fmt, vargs, true); + return FMT_USE_UTF8 ? vprintln(f, fmt, vargs) + : detail::vprint_mojibake(f, fmt, vargs, true); } /// Formats `args` according to specifications in `fmt` and writes the output diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 583d07f6..3af4ff21 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -357,7 +357,7 @@ void write_codecvt(codecvt_result& out, string_view in_buf, template auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc) -> OutputIt { - if (detail::use_utf8() && loc != get_classic_locale()) { + if (FMT_USE_UTF8 && loc != get_classic_locale()) { // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and // gcc-4. #if FMT_MSC_VERSION != 0 || \ @@ -651,7 +651,8 @@ FMT_CONSTEXPR inline auto get_units() -> const char* { if (std::is_same::value) return "fs"; if (std::is_same::value) return "ps"; if (std::is_same::value) return "ns"; - if (std::is_same::value) return use_utf8() ? "µs" : "us"; + if (std::is_same::value) + return FMT_USE_UTF8 ? "µs" : "us"; if (std::is_same::value) return "ms"; if (std::is_same::value) return "cs"; if (std::is_same::value) return "ds"; diff --git a/include/fmt/format.h b/include/fmt/format.h index 040e3058..07a1088a 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1860,7 +1860,7 @@ auto find_escape(const Char* begin, const Char* end) inline auto find_escape(const char* begin, const char* end) -> find_escape_result { - if (!use_utf8()) return find_escape(begin, end); + if (!FMT_USE_UTF8) return find_escape(begin, end); auto result = find_escape_result{end, nullptr, 0}; for_each_codepoint(string_view(begin, to_unsigned(end - begin)), [&](uint32_t cp, string_view sv) { diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index 98faef65..e7f6caa2 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -179,7 +179,7 @@ void vprint(std::basic_ostream& os, FMT_EXPORT template void print(std::ostream& os, format_string fmt, T&&... args) { const auto& vargs = fmt::make_format_args(args...); - if (detail::use_utf8()) + if (FMT_USE_UTF8) vprint(os, fmt, vargs); else detail::vprint_directly(os, fmt, vargs); diff --git a/test/ranges-test.cc b/test/ranges-test.cc index 0b6c32c1..09d202e3 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -560,7 +560,7 @@ TEST(ranges_test, escape) { EXPECT_EQ(fmt::format("{}", vec{"\x7f"}), "[\"\\x7f\"]"); EXPECT_EQ(fmt::format("{}", vec{"n\xcc\x83"}), "[\"n\xcc\x83\"]"); - if (fmt::detail::use_utf8()) { + if (FMT_USE_UTF8) { EXPECT_EQ(fmt::format("{}", vec{"\xcd\xb8"}), "[\"\\u0378\"]"); // Unassigned Unicode code points. EXPECT_EQ(fmt::format("{}", vec{"\xf0\xaa\x9b\x9e"}), "[\"\\U0002a6de\"]"); diff --git a/test/unicode-test.cc b/test/unicode-test.cc index 07b7eb35..f2c04e95 100644 --- a/test/unicode-test.cc +++ b/test/unicode-test.cc @@ -15,7 +15,7 @@ using testing::Contains; -TEST(unicode_test, use_utf8) { EXPECT_TRUE(fmt::detail::use_utf8()); } +TEST(unicode_test, use_utf8) { EXPECT_TRUE(FMT_USE_UTF8); } TEST(unicode_test, legacy_locale) { auto loc = get_locale("be_BY.CP1251", "Belarusian_Belarus.1251");