From 4c11646d17a67d4d1c08d07c9c3b96282f438549 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 9 May 2025 13:25:55 +0530 Subject: [PATCH 1/6] use display width precision --- include/fmt/format.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 13e30f6b1fc2..88e056663877 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2110,13 +2110,35 @@ FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, return write_int(out, make_write_int_arg(value, specs.sign()), specs); } +FMT_INLINE auto count_code_points_with_display_width_precision(string_view s, size_t display_width_precision) -> size_t { + size_t display_width = 0; + size_t code_points = 0; + + // Iterate through the string to compute display width + for_each_codepoint(s, [&](uint32_t cp, string_view sv) { + // Compute the display width of the current code point + size_t cp_width = compute_width(sv); + if (display_width + cp_width > display_width_precision) { + return false; // Stop iteration when display width exceeds precision + } + + display_width += cp_width; + code_points++; + return true; + }); + + return code_points; +} + template FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, const format_specs& specs) -> OutputIt { auto data = s.data(); auto size = s.size(); - if (specs.precision >= 0 && to_unsigned(specs.precision) < size) - size = code_point_index(s, to_unsigned(specs.precision)); + if (specs.precision >= 0 && to_unsigned(specs.precision) < size) { + auto code_points = count_code_points_with_display_width_precision(s, specs.precision); + size = code_point_index(s, to_unsigned(code_points)); + } bool is_debug = specs.type() == presentation_type::debug; if (is_debug) { From 9609f0d0ce6b522086313785d8309f66075c3a45 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 9 May 2025 22:36:18 +0530 Subject: [PATCH 2/6] use constexpr to compile only relevant branch --- include/fmt/format.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 88e056663877..d605ee9fd9f4 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2136,8 +2136,12 @@ FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, auto data = s.data(); auto size = s.size(); if (specs.precision >= 0 && to_unsigned(specs.precision) < size) { - auto code_points = count_code_points_with_display_width_precision(s, specs.precision); - size = code_point_index(s, to_unsigned(code_points)); + if constexpr (std::is_same::value) { + auto code_points = count_code_points_with_display_width_precision(to_string_view(data), to_unsigned(specs.precision)); + size = code_point_index(s, to_unsigned(code_points)); + } else { + size = code_point_index(s, to_unsigned(size)); + } } bool is_debug = specs.type() == presentation_type::debug; From 07cf0cea0f07e70d247eadffaa0247ceb82af440 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 9 May 2025 22:56:21 +0530 Subject: [PATCH 3/6] use enable_if --- include/fmt/format.h | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index d605ee9fd9f4..782fdd58cc33 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2130,18 +2130,31 @@ FMT_INLINE auto count_code_points_with_display_width_precision(string_view s, si return code_points; } +template +FMT_CONSTEXPR auto handle_precision( + basic_string_view s, const Char* data, const format_specs& specs, + typename std::enable_if::value>::type* = nullptr) + -> size_t { + auto code_points = count_code_points_with_display_width_precision( + to_string_view(data), to_unsigned(specs.precision)); + return code_point_index(s, to_unsigned(code_points)); +} + +template +FMT_CONSTEXPR auto handle_precision( + basic_string_view s, const Char*, const format_specs& specs, + typename std::enable_if::value>::type* = nullptr) + -> size_t { + return code_point_index(s, to_unsigned(s.size())); +} + template FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, const format_specs& specs) -> OutputIt { auto data = s.data(); auto size = s.size(); if (specs.precision >= 0 && to_unsigned(specs.precision) < size) { - if constexpr (std::is_same::value) { - auto code_points = count_code_points_with_display_width_precision(to_string_view(data), to_unsigned(specs.precision)); - size = code_point_index(s, to_unsigned(code_points)); - } else { - size = code_point_index(s, to_unsigned(size)); - } + size = handle_precision(s, data, specs); } bool is_debug = specs.type() == presentation_type::debug; From 4857e7394ca242c8ab36b3df682d3ed8a136c2b7 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 9 May 2025 23:51:27 +0530 Subject: [PATCH 4/6] fix formatting --- include/fmt/format.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 782fdd58cc33..edaf2a940efb 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -33,6 +33,7 @@ #ifndef FMT_FORMAT_H_ #define FMT_FORMAT_H_ +#include #ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES # define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES # define FMT_REMOVE_TRANSITIVE_INCLUDES @@ -2110,31 +2111,31 @@ FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, return write_int(out, make_write_int_arg(value, specs.sign()), specs); } -FMT_INLINE auto count_code_points_with_display_width_precision(string_view s, size_t display_width_precision) -> size_t { - size_t display_width = 0; - size_t code_points = 0; +FMT_INLINE auto count_code_points_with_display_width_precision( + string_view s, size_t display_width_precision) -> size_t { + size_t display_width = 0; + size_t code_points = 0; - // Iterate through the string to compute display width - for_each_codepoint(s, [&](uint32_t cp, string_view sv) { - // Compute the display width of the current code point - size_t cp_width = compute_width(sv); - if (display_width + cp_width > display_width_precision) { - return false; // Stop iteration when display width exceeds precision - } + // Iterate through the string to compute display width + for_each_codepoint(s, [&](uint32_t cp, string_view sv) { + // Compute the display width of the current code point + size_t cp_width = compute_width(sv); + if (display_width + cp_width > display_width_precision) { + return false; // Stop iteration when display width exceeds precision + } - display_width += cp_width; - code_points++; - return true; - }); + display_width += cp_width; + code_points++; + return true; + }); - return code_points; + return code_points; } template FMT_CONSTEXPR auto handle_precision( basic_string_view s, const Char* data, const format_specs& specs, - typename std::enable_if::value>::type* = nullptr) - -> size_t { + FMT_ENABLE_IF(std::is_same::value)) -> size_t { auto code_points = count_code_points_with_display_width_precision( to_string_view(data), to_unsigned(specs.precision)); return code_point_index(s, to_unsigned(code_points)); @@ -2143,8 +2144,7 @@ FMT_CONSTEXPR auto handle_precision( template FMT_CONSTEXPR auto handle_precision( basic_string_view s, const Char*, const format_specs& specs, - typename std::enable_if::value>::type* = nullptr) - -> size_t { + FMT_ENABLE_IF(!std::is_same::value)) -> size_t { return code_point_index(s, to_unsigned(s.size())); } From b80b43da9b690737d13b23c24f84d1150d781f46 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Sat, 10 May 2025 11:22:00 +0530 Subject: [PATCH 5/6] handle unused parameters --- include/fmt/format.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index edaf2a940efb..ad7ee133c34d 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2117,7 +2117,7 @@ FMT_INLINE auto count_code_points_with_display_width_precision( size_t code_points = 0; // Iterate through the string to compute display width - for_each_codepoint(s, [&](uint32_t cp, string_view sv) { + for_each_codepoint(s, [&](uint32_t, string_view sv) { // Compute the display width of the current code point size_t cp_width = compute_width(sv); if (display_width + cp_width > display_width_precision) { @@ -2143,7 +2143,7 @@ FMT_CONSTEXPR auto handle_precision( template FMT_CONSTEXPR auto handle_precision( - basic_string_view s, const Char*, const format_specs& specs, + basic_string_view s, const Char*, const format_specs&, FMT_ENABLE_IF(!std::is_same::value)) -> size_t { return code_point_index(s, to_unsigned(s.size())); } From 0b6c4e052b25759a8b37e53838733b5e0ec9a656 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Sat, 10 May 2025 11:30:33 +0530 Subject: [PATCH 6/6] remove unnecessay include --- include/fmt/format.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index ad7ee133c34d..94b07449626c 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -33,7 +33,6 @@ #ifndef FMT_FORMAT_H_ #define FMT_FORMAT_H_ -#include #ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES # define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES # define FMT_REMOVE_TRANSITIVE_INCLUDES