From 33efc3c94fb8eea56dbf6067d7957a8cee0c9a8d Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 30 Jul 2020 07:03:11 -0700 Subject: [PATCH 01/10] Fix handling of iterators in locale-specific formatting (#1782) --- include/fmt/format.h | 9 +++++---- test/locale-test.cc | 12 ++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index b1ba0713..7213a0da 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -745,9 +745,9 @@ FMT_CONSTEXPR bool is_supported_floating_point(T) { // Smallest of uint32_t, uint64_t, uint128_t that is large enough to // represent all values of T. template -using uint32_or_64_or_128_t = conditional_t< - num_bits() <= 32, uint32_t, - conditional_t() <= 64, uint64_t, uint128_t>>; +using uint32_or_64_or_128_t = + conditional_t() <= 32, uint32_t, + conditional_t() <= 64, uint64_t, uint128_t>>; // Static data is placed in this class template for the header-only config. template struct FMT_EXTERN_TEMPLATE_API basic_data { @@ -1593,7 +1593,8 @@ template struct int_writer { make_checked(p, s.size())); } if (prefix_size != 0) p[-1] = static_cast('-'); - write(out, basic_string_view(buffer.data(), buffer.size()), specs); + out = write(out, basic_string_view(buffer.data(), buffer.size()), + specs); } void on_chr() { *out++ = static_cast(abs_value); } diff --git a/test/locale-test.cc b/test/locale-test.cc index 15a40d99..b2cb8a63 100644 --- a/test/locale-test.cc +++ b/test/locale-test.cc @@ -89,4 +89,16 @@ TEST(LocaleTest, WFormat) { fmt::format(small_grouping_loc, L"{:L}", max_value())); } +TEST(LocaleTest, DoubleFormatter) { + auto loc = std::locale(std::locale(), new special_grouping()); + auto f = fmt::formatter(); + auto parse_ctx = fmt::format_parse_context("L"); + f.parse(parse_ctx); + char buf[10] = {}; + fmt::basic_format_context format_ctx( + buf, {}, fmt::detail::locale_ref(loc)); + *f.format(12345, format_ctx) = 0; + EXPECT_STREQ("12,345", buf); +} + #endif // FMT_STATIC_THOUSANDS_SEPARATOR From 0cc73ebf79ec39ba74f3d31a76c0acb2df824908 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 30 Jul 2020 07:16:15 -0700 Subject: [PATCH 02/10] Report error on missing named argument (#1796) --- include/fmt/core.h | 2 +- test/format-test.cc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 40c4ddb0..e83800ce 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1713,7 +1713,7 @@ template class basic_format_args { } template int get_id(basic_string_view name) const { - if (!has_named_args()) return {}; + if (!has_named_args()) return -1; const auto& named_args = (is_packed() ? values_[-1] : args_[-1].value_).named_args; for (size_t i = 0; i < named_args.size; ++i) { diff --git a/test/format-test.cc b/test/format-test.cc index 978feef2..2a25566c 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -543,7 +543,6 @@ TEST(FormatterTest, ManyArgs) { TEST(FormatterTest, NamedArg) { EXPECT_EQ("1/a/A", format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'), fmt::arg("A_", "A"), fmt::arg("_1", 1))); - EXPECT_THROW_MSG(format("{a}"), format_error, "argument not found"); EXPECT_EQ(" -42", format("{0:{width}}", -42, fmt::arg("width", 4))); EXPECT_EQ("st", format("{0:.{precision}}", "str", fmt::arg("precision", 2))); EXPECT_EQ("1 2", format("{} {two}", 1, fmt::arg("two", 2))); @@ -553,6 +552,8 @@ TEST(FormatterTest, NamedArg) { fmt::arg("i", 0), fmt::arg("j", 0), fmt::arg("k", 0), fmt::arg("l", 0), fmt::arg("m", 0), fmt::arg("n", 0), fmt::arg("o", 0), fmt::arg("p", 0))); + EXPECT_THROW_MSG(format("{a}"), format_error, "argument not found"); + EXPECT_THROW_MSG(format("{a}", 42), format_error, "argument not found"); } TEST(FormatterTest, AutoArgIndex) { From ccf8561cb3e85676179c286e3e40edaebe0a45ae Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 30 Jul 2020 09:42:24 -0700 Subject: [PATCH 03/10] Workaround broken numeric_limites, part 2 (#1787) --- include/fmt/format.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 7213a0da..ca7cefd9 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -724,13 +724,18 @@ class FMT_API format_error : public std::runtime_error { namespace detail { +template +constexpr bool is_signed() { + return std::numeric_limits::is_signed || std::is_same(); +} + // Returns true if value is negative, false otherwise. // Same as `value < 0` but doesn't produce warnings if T is an unsigned type. -template ::is_signed)> +template ())> FMT_CONSTEXPR bool is_negative(T value) { return value < 0; } -template ::is_signed)> +template ())> FMT_CONSTEXPR bool is_negative(T) { return false; } From eaaaec99929ece68baa8bebce7325a78cd21cc96 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 30 Jul 2020 11:13:54 -0700 Subject: [PATCH 04/10] Workaround a bug in msvc --- include/fmt/format.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index ca7cefd9..405b7e96 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -725,17 +725,17 @@ class FMT_API format_error : public std::runtime_error { namespace detail { template -constexpr bool is_signed() { - return std::numeric_limits::is_signed || std::is_same(); -} +using is_signed = + std::integral_constant::is_signed || + std::is_same::value>; // Returns true if value is negative, false otherwise. // Same as `value < 0` but doesn't produce warnings if T is an unsigned type. -template ())> +template ::value)> FMT_CONSTEXPR bool is_negative(T value) { return value < 0; } -template ())> +template ::value)> FMT_CONSTEXPR bool is_negative(T) { return false; } From 37c8f4eaf33cecff0930d753e0021533fb722db5 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Fri, 31 Jul 2020 02:21:35 +0200 Subject: [PATCH 05/10] Don't use 128 bit integers with clang-cl (#1800) clang-cl currently has a long-standing bug that using 128 bit integers generates references to symbols that are provided neither by its own nor by the Microsoft runtime: https://bugs.llvm.org/show_bug.cgi?id=25305 --- include/fmt/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index e83800ce..73f23c91 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -299,7 +299,7 @@ template struct std_string_view {}; #ifdef FMT_USE_INT128 // Do nothing. -#elif defined(__SIZEOF_INT128__) && !FMT_NVCC +#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && !(FMT_CLANG_VERSION && FMT_MSC_VER) # define FMT_USE_INT128 1 using int128_t = __int128_t; using uint128_t = __uint128_t; From 0907c08ae56de6e0cea4874dfc45eef44f4178c9 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 3 Aug 2020 10:51:42 -0700 Subject: [PATCH 06/10] Fix handling of default alignmment with locale (#1801) --- include/fmt/format.h | 7 +++++-- test/locale-test.cc | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 405b7e96..17509b7b 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1598,8 +1598,11 @@ template struct int_writer { make_checked(p, s.size())); } if (prefix_size != 0) p[-1] = static_cast('-'); - out = write(out, basic_string_view(buffer.data(), buffer.size()), - specs); + using iterator = remove_reference_t; + auto data = buffer.data(); + out = write_padded(out, specs, size, size, [=](iterator it) { + return copy_str(data, data + size, it); + }); } void on_chr() { *out++ = static_cast(abs_value); } diff --git a/test/locale-test.cc b/test/locale-test.cc index b2cb8a63..af3078af 100644 --- a/test/locale-test.cc +++ b/test/locale-test.cc @@ -68,6 +68,11 @@ TEST(LocaleTest, Format) { fmt::format(small_grouping_loc, "{:L}", max_value())); } +TEST(LocaleTest, FormatDetaultAlign) { + std::locale special_grouping_loc(std::locale(), new special_grouping()); + EXPECT_EQ(" 12,345", fmt::format(special_grouping_loc, "{:8L}", 12345)); +} + TEST(LocaleTest, WFormat) { std::locale loc(std::locale(), new numpunct()); EXPECT_EQ(L"1234567", fmt::format(std::locale(), L"{:L}", 1234567)); From 72920ba30a81dbaabbad51f19b16f580aa77b6ab Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 6 Aug 2020 07:34:56 -0700 Subject: [PATCH 07/10] Update changelog --- ChangeLog.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ChangeLog.rst b/ChangeLog.rst index aa1b7fe0..4bae496e 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,3 +1,20 @@ +7.0.3 - TBD +----------- + +* Worked around broken ``numeric_limits`` for 128-bit integers + (`#1787 `_). + +* Added error reporting on missing named arguments + (`#1796 `_). + +* Stopped using 128-bit integers with clang-cl + (`#1800 `_). + Thanks `@Kingcom `_. + +* Fixed issues in locale-specific integer formatting (#) + (`#1782 `_, + `#1801 `_) + 7.0.2 - 2020-07-29 ------------------ From f4c997062a3e6ea60539f2570e3cd05c0db89fc8 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 6 Aug 2020 07:40:46 -0700 Subject: [PATCH 08/10] Fix changelog --- ChangeLog.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index 4bae496e..b13ac6d6 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -11,9 +11,9 @@ (`#1800 `_). Thanks `@Kingcom `_. -* Fixed issues in locale-specific integer formatting (#) +* Fixed issues in locale-specific integer formatting (`#1782 `_, - `#1801 `_) + `#1801 `_). 7.0.2 - 2020-07-29 ------------------ From 1ebc2f7cc6b38f93ce5eba7cc72da6b11bb26836 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 6 Aug 2020 07:41:04 -0700 Subject: [PATCH 09/10] Bump version --- include/fmt/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 73f23c91..37799a3a 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -18,7 +18,7 @@ #include // The fmt library version in the form major * 10000 + minor * 100 + patch. -#define FMT_VERSION 70002 +#define FMT_VERSION 70003 #ifdef __clang__ # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) From cd4af11efc9c622896a3e4cb599fa28668ca3d05 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 6 Aug 2020 08:51:01 -0700 Subject: [PATCH 10/10] Update version --- ChangeLog.rst | 4 ++-- doc/build.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index b13ac6d6..97a0a7da 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,5 +1,5 @@ -7.0.3 - TBD ------------ +7.0.3 - 2020-08-06 +------------------ * Worked around broken ``numeric_limits`` for 128-bit integers (`#1787 `_). diff --git a/doc/build.py b/doc/build.py index ba9eea75..06e105aa 100755 --- a/doc/build.py +++ b/doc/build.py @@ -6,7 +6,7 @@ import errno, os, shutil, sys, tempfile from subprocess import check_call, check_output, CalledProcessError, Popen, PIPE from distutils.version import LooseVersion -versions = ['1.0.0', '1.1.0', '2.0.0', '3.0.2', '4.0.0', '4.1.0', '5.0.0', '5.1.0', '5.2.0', '5.2.1', '5.3.0', '6.0.0', '6.1.0', '6.1.1', '6.1.2', '6.2.0', '6.2.1', '7.0.0', '7.0.1', '7.0.2'] +versions = ['1.0.0', '1.1.0', '2.0.0', '3.0.2', '4.0.0', '4.1.0', '5.0.0', '5.1.0', '5.2.0', '5.2.1', '5.3.0', '6.0.0', '6.1.0', '6.1.1', '6.1.2', '6.2.0', '6.2.1', '7.0.0', '7.0.1', '7.0.2', '7.0.3'] def pip_install(package, commit=None, **kwargs): "Install package using pip."