Compare commits

...

27 Commits
7.0.0 ... 7.0.3

Author SHA1 Message Date
Victor Zverovich
cd4af11efc Update version 2020-08-06 08:51:01 -07:00
Victor Zverovich
1ebc2f7cc6 Bump version 2020-08-06 07:41:04 -07:00
Victor Zverovich
f4c997062a Fix changelog 2020-08-06 07:40:46 -07:00
Victor Zverovich
72920ba30a Update changelog 2020-08-06 07:39:37 -07:00
Victor Zverovich
0907c08ae5 Fix handling of default alignmment with locale (#1801) 2020-08-06 07:39:09 -07:00
Kingcom
37c8f4eaf3 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
2020-08-06 07:38:57 -07:00
Victor Zverovich
eaaaec9992 Workaround a bug in msvc 2020-08-06 07:38:51 -07:00
Victor Zverovich
ccf8561cb3 Workaround broken numeric_limites, part 2 (#1787) 2020-08-06 07:38:32 -07:00
Victor Zverovich
0cc73ebf79 Report error on missing named argument (#1796) 2020-08-06 07:38:18 -07:00
Victor Zverovich
33efc3c94f Fix handling of iterators in locale-specific formatting (#1782) 2020-08-06 07:38:08 -07:00
Victor Zverovich
b9d749095e Update version 2020-07-29 07:30:55 -07:00
Victor Zverovich
86b63bb71a Bump version 2020-07-29 07:14:25 -07:00
Victor Zverovich
cbf6be9604 Update changelog 2020-07-29 07:07:56 -07:00
Victor Zverovich
229ee9b469 Workaround broken numeric_limits (#1725) 2020-07-29 07:06:45 -07:00
Victor Zverovich
2b7a146fa1 Fix a regression in handling digit separators (#1782) 2020-07-29 07:04:11 -07:00
Victor Zverovich
89d0c7124b Fix compatibility with CMake 3.4 (#1779) 2020-07-29 07:03:59 -07:00
Victor Zverovich
f19b1a521e Update version 2020-07-07 07:47:44 -07:00
Victor Zverovich
5c67fefb26 Fix a changelog entry 2020-07-07 06:58:44 -07:00
Dmitriy Kurkin
1d2a556e1b Fix undefined reference error 2020-07-07 06:37:17 -07:00
Victor Zverovich
04c9b62fb4 Merge release branch 2020-07-07 06:34:39 -07:00
Victor Zverovich
6be6762e57 Fix date 2020-07-07 06:32:19 -07:00
Victor Zverovich
f1dd2eb3c0 Bump version 2020-07-07 06:24:32 -07:00
Victor Zverovich
fbf3b943cc Workaround a bug in gcc 2020-07-07 06:06:50 -07:00
Victor Zverovich
a29a01d304 Fix docs 2020-07-07 06:05:00 -07:00
Victor Zverovich
9f0b3afb79 Bump version in namespace 2020-07-06 09:47:27 -07:00
Victor Zverovich
86b2f99f8c Fix the docs 2020-07-06 07:53:07 -07:00
Victor Zverovich
c472ff12d8 Update version 2020-07-06 06:45:20 -07:00
10 changed files with 136 additions and 32 deletions

View File

@@ -24,15 +24,23 @@ function(join result_var)
set(${result_var} "${result}" PARENT_SCOPE)
endfunction()
include(CMakeParseArguments)
# Sets a cache variable with a docstring joined from multiple arguments:
# set(<variable> <value>... CACHE <type> <docstring>...)
# This allows splitting a long docstring for readability.
function(set_verbose)
cmake_parse_arguments(SET_VERBOSE "" "" "CACHE" ${ARGN})
list(GET SET_VERBOSE_CACHE 0 type)
list(REMOVE_AT SET_VERBOSE_CACHE 0)
join(doc ${SET_VERBOSE_CACHE})
set(${SET_VERBOSE_UNPARSED_ARGUMENTS} CACHE ${type} ${doc})
# cmake_parse_arguments is broken in CMake 3.4 (cannot parse CACHE) so use
# list instead.
list(GET ARGN 0 var)
list(REMOVE_AT ARGN 0)
list(GET ARGN 0 val)
list(REMOVE_AT ARGN 0)
list(REMOVE_AT ARGN 0)
list(GET ARGN 0 type)
list(REMOVE_AT ARGN 0)
join(doc ${ARGN})
set(${var} ${val} CACHE ${type} ${doc})
endfunction()
# Set the default CMAKE_BUILD_TYPE to Release.

View File

@@ -1,3 +1,46 @@
7.0.3 - 2020-08-06
------------------
* Worked around broken ``numeric_limits`` for 128-bit integers
(`#1787 <https://github.com/fmtlib/fmt/issues/1787>`_).
* Added error reporting on missing named arguments
(`#1796 <https://github.com/fmtlib/fmt/issues/1796>`_).
* Stopped using 128-bit integers with clang-cl
(`#1800 <https://github.com/fmtlib/fmt/pull/1800>`_).
Thanks `@Kingcom <https://github.com/Kingcom>`_.
* Fixed issues in locale-specific integer formatting
(`#1782 <https://github.com/fmtlib/fmt/issues/1782>`_,
`#1801 <https://github.com/fmtlib/fmt/issues/1801>`_).
7.0.2 - 2020-07-29
------------------
* Worked around broken ``numeric_limits`` for 128-bit integers
(`#1725 <https://github.com/fmtlib/fmt/issues/1725>`_).
* Fixed compatibility with CMake 3.4
(`#1779 <https://github.com/fmtlib/fmt/issues/1779>`_).
* Fixed handling of digit separators in locale-specific formatting
(`#1782 <https://github.com/fmtlib/fmt/issues/1782>`_).
7.0.1 - 2020-07-07
------------------
* Updated the inline version namespace name.
* Worked around a gcc bug in mangling of alias templates
(`#1753 <https://github.com/fmtlib/fmt/issues/1753>`_).
* Fixed a linkage error on Windows
(`#1757 <https://github.com/fmtlib/fmt/issues/1757>`_).
Thanks `@Kurkin (Dmitry Kurkin) <https://github.com/Kurkin>`_.
* Fixed minor issues with the documentation.
7.0.0 - 2020-07-05
------------------
@@ -126,7 +169,7 @@
^
* Added sentinel support to ``fmt::join``
(`#1689 <https://github.com/fmtlib/fmt/pull/1689>`_))
(`#1689 <https://github.com/fmtlib/fmt/pull/1689>`_)
.. code:: c++
@@ -279,7 +322,7 @@
Thanks `@gsjaardema (Greg Sjaardema) <https://github.com/gsjaardema>`_,
`@gabime (Gabi Melman) <https://github.com/gabime>`_,
`@johnor (Johan) <https://github.com/johnor>`_,
`@gabime (Dmitry Kurkin) <https://github.com/Kurkin>`_,
`@Kurkin (Dmitry Kurkin) <https://github.com/Kurkin>`_,
`@invexed (James Beach) <https://github.com/invexed>`_,
`@peterbell10 <https://github.com/peterbell10>`_,
`@daixtrose (Markus Werle) <https://github.com/daixtrose>`_,

View File

@@ -244,7 +244,7 @@ Output Iterator Support
-----------------------
.. doxygenfunction:: fmt::format_to(OutputIt, const S&, Args&&...)
.. doxygenfunction:: fmt::format_to_n(OutputIt, std::size_t, string_view, Args&&...)
.. doxygenfunction:: fmt::format_to_n(OutputIt, size_t, const S&, const Args&...)
.. doxygenstruct:: fmt::format_to_n_result
:members:
@@ -274,7 +274,7 @@ Utilities
.. doxygenfunction:: fmt::join(const Range&, string_view)
.. doxygenfunction:: fmt::join(It, It, string_view)
.. doxygenfunction:: fmt::join(It, Sentinel, string_view)
.. doxygenclass:: fmt::detail::buffer
:members:

View File

@@ -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']
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."

View File

@@ -18,7 +18,7 @@
#include <vector>
// The fmt library version in the form major * 10000 + minor * 100 + patch.
#define FMT_VERSION 70000
#define FMT_VERSION 70003
#ifdef __clang__
# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
@@ -188,12 +188,12 @@
# define FMT_INLINE_NAMESPACE namespace
# define FMT_END_NAMESPACE \
} \
using namespace v6; \
using namespace v7; \
}
# endif
# define FMT_BEGIN_NAMESPACE \
namespace fmt { \
FMT_INLINE_NAMESPACE v6 {
FMT_INLINE_NAMESPACE v7 {
#endif
#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
@@ -299,7 +299,7 @@ template <typename T> 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;
@@ -491,7 +491,7 @@ constexpr basic_string_view<typename S::char_type> to_string_view(const S& s) {
namespace detail {
void to_string_view(...);
using fmt::v6::to_string_view;
using fmt::v7::to_string_view;
// Specifies whether S is a string type convertible to fmt::basic_string_view.
// It should be a constexpr function but MSVC 2017 fails to compile it in
@@ -1360,6 +1360,10 @@ using buffer_context =
using format_context = buffer_context<char>;
using wformat_context = buffer_context<wchar_t>;
// Workaround a bug in gcc: https://stackoverflow.com/q/62767544/471164.
#define FMT_BUFFER_CONTEXT(Char) \
basic_format_context<std::back_insert_iterator<detail::buffer<Char>>, Char>
/**
\rst
An array of references to arguments. It can be implicitly converted into
@@ -1709,7 +1713,7 @@ template <typename Context> class basic_format_args {
}
template <typename Char> int get_id(basic_string_view<Char> 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) {
@@ -1765,12 +1769,12 @@ std::basic_string<Char> vformat(
basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args);
std::string vformat(string_view format_str, format_args args);
FMT_API std::string vformat(string_view format_str, format_args args);
template <typename Char>
typename buffer_context<Char>::iterator vformat_to(
typename FMT_BUFFER_CONTEXT(Char)::iterator vformat_to(
buffer<Char>& buf, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args);
basic_format_args<FMT_BUFFER_CONTEXT(type_identity_t<Char>)> args);
template <typename Char, typename Args,
FMT_ENABLE_IF(!std::is_same<Char, char>::value)>

View File

@@ -283,6 +283,9 @@ template <typename T> constexpr T max_value() {
template <typename T> constexpr int num_bits() {
return std::numeric_limits<T>::digits;
}
// std::numeric_limits<T>::digits may return 0 for 128-bit ints.
template <> constexpr int num_bits<int128_t>() { return 128; }
template <> constexpr int num_bits<uint128_t>() { return 128; }
template <> constexpr int num_bits<fallback_uintptr>() {
return static_cast<int>(sizeof(void*) *
std::numeric_limits<unsigned char>::digits);
@@ -721,13 +724,18 @@ class FMT_API format_error : public std::runtime_error {
namespace detail {
template <typename T>
using is_signed =
std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
std::is_same<T, int128_t>::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 <typename T, FMT_ENABLE_IF(std::numeric_limits<T>::is_signed)>
template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
FMT_CONSTEXPR bool is_negative(T value) {
return value < 0;
}
template <typename T, FMT_ENABLE_IF(!std::numeric_limits<T>::is_signed)>
template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
FMT_CONSTEXPR bool is_negative(T) {
return false;
}
@@ -742,9 +750,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 <typename T>
using uint32_or_64_or_128_t = conditional_t<
std::numeric_limits<T>::digits <= 32, uint32_t,
conditional_t<std::numeric_limits<T>::digits <= 64, uint64_t, uint128_t>>;
using uint32_or_64_or_128_t =
conditional_t<num_bits<T>() <= 32, uint32_t,
conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
// Static data is placed in this class template for the header-only config.
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
@@ -1559,7 +1567,7 @@ template <typename OutputIt, typename Char, typename UInt> struct int_writer {
int num_digits = count_digits(abs_value);
int size = num_digits, n = num_digits;
std::string::const_iterator group = groups.cbegin();
while (group != groups.cend() && num_digits > *group && *group > 0 &&
while (group != groups.cend() && n > *group && *group > 0 &&
*group != max_value<char>()) {
size += sep_size;
n -= *group;
@@ -1590,7 +1598,11 @@ template <typename OutputIt, typename Char, typename UInt> struct int_writer {
make_checked(p, s.size()));
}
if (prefix_size != 0) p[-1] = static_cast<Char>('-');
write(out, basic_string_view<Char>(buffer.data(), buffer.size()), specs);
using iterator = remove_reference_t<decltype(reserve(out, 0))>;
auto data = buffer.data();
out = write_padded<align::right>(out, specs, size, size, [=](iterator it) {
return copy_str<Char>(data, data + size, it);
});
}
void on_chr() { *out++ = static_cast<Char>(abs_value); }
@@ -3482,9 +3494,9 @@ extern template int snprintf_float<long double>(long double value,
template <typename S, typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_string<S>::value)>
inline typename buffer_context<Char>::iterator vformat_to(
inline typename FMT_BUFFER_CONTEXT(Char)::iterator vformat_to(
detail::buffer<Char>& buf, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_format_args<FMT_BUFFER_CONTEXT(type_identity_t<Char>)> args) {
return detail::vformat_to(buf, to_string_view(format_str), args);
}

View File

@@ -44,8 +44,9 @@ template FMT_API char detail::decimal_point_impl(locale_ref);
template FMT_API void detail::buffer<char>::append(const char*, const char*);
template FMT_API format_context::iterator detail::vformat_to(
detail::buffer<char>&, string_view, basic_format_args<format_context>);
template FMT_API FMT_BUFFER_CONTEXT(char)::iterator detail::vformat_to(
detail::buffer<char>&, string_view,
basic_format_args<FMT_BUFFER_CONTEXT(char)>);
template FMT_API int detail::snprintf_float(double, int, detail::float_specs,
detail::buffer<char>&);

View File

@@ -145,7 +145,24 @@ def update_site(env):
b.data = b.data.replace('std::FILE*', 'std::FILE *')
b.data = b.data.replace('unsigned int', 'unsigned')
#b.data = b.data.replace('operator""_', 'operator"" _')
b.data = b.data.replace(', size_t', ', std::size_t')
b.data = b.data.replace(
'format_to_n(OutputIt, size_t, string_view, Args&&',
'format_to_n(OutputIt, size_t, const S&, const Args&')
b.data = b.data.replace(
'format_to_n(OutputIt, std::size_t, string_view, Args&&',
'format_to_n(OutputIt, std::size_t, const S&, const Args&')
if version == ('3.0.2'):
b.data = b.data.replace(
'fprintf(std::ostream&', 'fprintf(std::ostream &')
if version == ('5.3.0'):
b.data = b.data.replace(
'format_to(OutputIt, const S&, const Args&...)',
'format_to(OutputIt, const S &, const Args &...)')
if version.startswith('5.') or version.startswith('6.'):
b.data = b.data.replace(', size_t', ', std::size_t')
if version.startswith('7.'):
b.data = b.data.replace(', std::size_t', ', size_t')
b.data = b.data.replace('join(It, It', 'join(It, Sentinel')
b.data = b.data.replace('aa long', 'a long')
b.data = b.data.replace('serveral', 'several')
if version.startswith('6.2.'):

View File

@@ -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) {

View File

@@ -61,12 +61,18 @@ TEST(LocaleTest, Format) {
std::locale special_grouping_loc(std::locale(), new special_grouping<char>());
EXPECT_EQ("1,23,45,678", fmt::format(special_grouping_loc, "{:L}", 12345678));
EXPECT_EQ("12,345", fmt::format(special_grouping_loc, "{:L}", 12345));
std::locale small_grouping_loc(std::locale(), new small_grouping<char>());
EXPECT_EQ("4,2,9,4,9,6,7,2,9,5",
fmt::format(small_grouping_loc, "{:L}", max_value<uint32_t>()));
}
TEST(LocaleTest, FormatDetaultAlign) {
std::locale special_grouping_loc(std::locale(), new special_grouping<char>());
EXPECT_EQ(" 12,345", fmt::format(special_grouping_loc, "{:8L}", 12345));
}
TEST(LocaleTest, WFormat) {
std::locale loc(std::locale(), new numpunct<wchar_t>());
EXPECT_EQ(L"1234567", fmt::format(std::locale(), L"{:L}", 1234567));
@@ -88,4 +94,16 @@ TEST(LocaleTest, WFormat) {
fmt::format(small_grouping_loc, L"{:L}", max_value<uint32_t>()));
}
TEST(LocaleTest, DoubleFormatter) {
auto loc = std::locale(std::locale(), new special_grouping<char>());
auto f = fmt::formatter<int>();
auto parse_ctx = fmt::format_parse_context("L");
f.parse(parse_ctx);
char buf[10] = {};
fmt::basic_format_context<char*, char> format_ctx(
buf, {}, fmt::detail::locale_ref(loc));
*f.format(12345, format_ctx) = 0;
EXPECT_STREQ("12,345", buf);
}
#endif // FMT_STATIC_THOUSANDS_SEPARATOR