aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2020-11-04 04:09:37 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-11-04 04:09:37 +0000
commitdeff1e2c4aa7e06ab5eea4e7e49a0a3040011218 (patch)
treec513114915b28cfc2fdd4468fbdf804a7f516371
parentc56f1d1115ef3356f0d440dc685dd31c5d43f5dd (diff)
parente55a01879d812c2d33ddf13705323208d5ca6a91 (diff)
downloadfmtlib-deff1e2c4aa7e06ab5eea4e7e49a0a3040011218.tar.gz
Merge "Upgrade fmtlib to 7.1.1" am: 04c647ae50 am: 5cd77b66f2 am: 1020608874 am: e55a01879d
Original change: https://android-review.googlesource.com/c/platform/external/fmtlib/+/1485256 Change-Id: I895df10b5a8cf44f84f9c51d5e585ac0fe97bbf1
-rw-r--r--ChangeLog.rst24
-rw-r--r--METADATA6
-rwxr-xr-xdoc/build.py2
-rw-r--r--include/fmt/color.h9
-rw-r--r--include/fmt/compile.h17
-rw-r--r--include/fmt/core.h28
-rw-r--r--include/fmt/format-inl.h16
-rw-r--r--include/fmt/format.h28
-rw-r--r--include/fmt/locale.h8
-rw-r--r--src/format.cc30
10 files changed, 122 insertions, 46 deletions
diff --git a/ChangeLog.rst b/ChangeLog.rst
index f9a2d8eb..a5b776cf 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -1,3 +1,27 @@
+7.1.1 - 2020-11-01
+------------------
+
+* Fixed ABI compatibility with 7.0.x
+ (`#1961 <https://github.com/fmtlib/fmt/issues/1961>`_).
+
+* Added the ``FMT_ARM_ABI_COMPATIBILITY`` macro to work around ABI
+ incompatibility between GCC and Clang on ARM
+ (`#1919 <https://github.com/fmtlib/fmt/issues/1919>`_).
+
+* Worked around a SFINAE bug in GCC 8
+ (`#1957 <https://github.com/fmtlib/fmt/issues/1957>`_).
+
+* Fixed linkage errors when building with GCC's LTO
+ (`#1955 <https://github.com/fmtlib/fmt/issues/1955>`_).
+
+* Fixed a compilation error when building without ``__builtin_clz`` or equivalent
+ (`#1968 <https://github.com/fmtlib/fmt/pull/1968>`_).
+ Thanks `@tohammer (Tobias Hammer) <https://github.com/tohammer>`_.
+
+* Fixed a sign conversion warning
+ (`#1964 <https://github.com/fmtlib/fmt/pull/1964>`_).
+ Thanks `@OptoCloud <https://github.com/OptoCloud>`_.
+
7.1.0 - 2020-10-25
------------------
diff --git a/METADATA b/METADATA
index c9052184..60ce712c 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/fmtlib/fmt.git"
}
- version: "7.1.0"
+ version: "7.1.1"
license_type: NOTICE
last_upgrade_date {
year: 2020
- month: 10
- day: 28
+ month: 11
+ day: 2
}
}
diff --git a/doc/build.py b/doc/build.py
index 7152638b..85eaaa81 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', '7.0.3', '7.1.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', '7.1.0', '7.1.1']
def pip_install(package, commit=None, **kwargs):
"Install package using pip."
diff --git a/include/fmt/color.h b/include/fmt/color.h
index 78910589..94e3419d 100644
--- a/include/fmt/color.h
+++ b/include/fmt/color.h
@@ -589,10 +589,11 @@ OutputIt vformat_to(
\endrst
*/
template <typename OutputIt, typename S, typename... Args,
- FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char_t<S>>::value&&
- detail::is_string<S>::value)>
-inline OutputIt format_to(OutputIt out, const text_style& ts,
- const S& format_str, Args&&... args) {
+ bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value&&
+ detail::is_string<S>::value>
+inline auto format_to(OutputIt out, const text_style& ts, const S& format_str,
+ Args&&... args) ->
+ typename std::enable_if<enable, OutputIt>::type {
return vformat_to(out, ts, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
diff --git a/include/fmt/compile.h b/include/fmt/compile.h
index 7db610d9..3a33b020 100644
--- a/include/fmt/compile.h
+++ b/include/fmt/compile.h
@@ -667,14 +667,15 @@ OutputIt format_to(OutputIt out, const S&, const Args&... args) {
return format_to(out, compiled, args...);
}
-template <typename OutputIt, typename CompiledFormat, typename... Args,
- FMT_ENABLE_IF(detail::is_output_iterator<
- OutputIt, typename CompiledFormat::char_type>::value&&
- std::is_base_of<detail::basic_compiled_format,
- CompiledFormat>::value)>
-format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
- const CompiledFormat& cf,
- const Args&... args) {
+template <typename OutputIt, typename CompiledFormat, typename... Args>
+auto format_to_n(OutputIt out, size_t n, const CompiledFormat& cf,
+ const Args&... args) ->
+ typename std::enable_if<
+ detail::is_output_iterator<OutputIt,
+ typename CompiledFormat::char_type>::value &&
+ std::is_base_of<detail::basic_compiled_format,
+ CompiledFormat>::value,
+ format_to_n_result<OutputIt>>::type {
auto it =
format_to(detail::truncating_iterator<OutputIt>(out, n), cf, args...);
return {it.base(), it.count()};
diff --git a/include/fmt/core.h b/include/fmt/core.h
index 2903be5a..60e49425 100644
--- a/include/fmt/core.h
+++ b/include/fmt/core.h
@@ -18,7 +18,7 @@
#include <vector>
// The fmt library version in the form major * 10000 + minor * 100 + patch.
-#define FMT_VERSION 70100
+#define FMT_VERSION 70101
#ifdef __clang__
# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
@@ -1929,7 +1929,14 @@ template <typename Context> class basic_format_args {
}
};
-/** An alias to ``basic_format_args<context>``. */
+#ifdef FMT_ARM_ABI_COMPATIBILITY
+/** An alias to ``basic_format_args<format_context>``. */
+// Separate types would result in shorter symbols but break ABI compatibility
+// between clang and gcc on ARM (#1919).
+using format_args = basic_format_args<format_context>;
+using wformat_args = basic_format_args<wformat_context>;
+#else
+// DEPRECATED! These are kept for ABI compatibility.
// It is a separate type rather than an alias to make symbols readable.
struct format_args : basic_format_args<format_context> {
template <typename... Args>
@@ -1938,6 +1945,7 @@ struct format_args : basic_format_args<format_context> {
struct wformat_args : basic_format_args<wformat_context> {
using basic_format_args::basic_format_args;
};
+#endif
namespace detail {
@@ -1968,10 +1976,10 @@ inline void vprint_mojibake(std::FILE*, string_view, format_args) {}
// GCC 8 and earlier cannot handle std::back_insert_iterator<Container> with
// vformat_to<ArgFormatter>(...) overload, so SFINAE on iterator type instead.
template <typename OutputIt, typename S, typename Char = char_t<S>,
- FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
-OutputIt vformat_to(
- OutputIt out, const S& format_str,
- basic_format_args<buffer_context<type_identity_t<Char>>> args) {
+ bool enable = detail::is_output_iterator<OutputIt, Char>::value>
+auto vformat_to(OutputIt out, const S& format_str,
+ basic_format_args<buffer_context<type_identity_t<Char>>> args)
+ -> typename std::enable_if<enable, OutputIt>::type {
decltype(detail::get_buffer<Char>(out)) buf(detail::get_buffer_init(out));
detail::vformat_to(buf, to_string_view(format_str), args);
return detail::get_iterator(buf);
@@ -2023,10 +2031,10 @@ inline format_to_n_result<OutputIt> vformat_to_n(
\endrst
*/
template <typename OutputIt, typename S, typename... Args,
- FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char_t<S>>::value)>
-inline format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
- const S& format_str,
- const Args&... args) {
+ bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value>
+inline auto format_to_n(OutputIt out, size_t n, const S& format_str,
+ const Args&... args) ->
+ typename std::enable_if<enable, format_to_n_result<OutputIt>>::type {
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
return vformat_to_n(out, n, to_string_view(format_str), vargs);
}
diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h
index b7cb3209..5d466eeb 100644
--- a/include/fmt/format-inl.h
+++ b/include/fmt/format-inl.h
@@ -261,11 +261,19 @@ const uint64_t basic_data<T>::powers_of_10_64[] = {
10000000000000000000ULL};
template <typename T>
-const uint32_t basic_data<T>::zero_or_powers_of_10_32[] = {0, 0,
+const uint32_t basic_data<T>::zero_or_powers_of_10_32[] = {0,
FMT_POWERS_OF_10(1)};
-
template <typename T>
const uint64_t basic_data<T>::zero_or_powers_of_10_64[] = {
+ 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
+ 10000000000000000000ULL};
+
+template <typename T>
+const uint32_t basic_data<T>::zero_or_powers_of_10_32_new[] = {
+ 0, 0, FMT_POWERS_OF_10(1)};
+
+template <typename T>
+const uint64_t basic_data<T>::zero_or_powers_of_10_64_new[] = {
0, 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL),
10000000000000000000ULL};
@@ -1756,7 +1764,7 @@ inline bool divisible_by_power_of_2(uint64_t x, int exp) FMT_NOEXCEPT {
#ifdef FMT_BUILTIN_CTZLL
return FMT_BUILTIN_CTZLL(x) >= exp;
#else
- return exp < num_bits<uint64_t>()) && x == ((x >> exp) << exp);
+ return exp < num_bits<uint64_t>() && x == ((x >> exp) << exp);
#endif
}
@@ -1901,7 +1909,7 @@ template <> struct cache_accessor<double> {
uint64_t pow5 = data::powers_of_5_64[offset];
uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5);
uint128_wrapper middle_low =
- umul128(base_cache.low() - (kb < 0 ? 1 : 0), pow5);
+ umul128(base_cache.low() - (kb < 0 ? 1u : 0u), pow5);
recovered_cache += middle_low.high();
diff --git a/include/fmt/format.h b/include/fmt/format.h
index fbe50450..13b8da30 100644
--- a/include/fmt/format.h
+++ b/include/fmt/format.h
@@ -866,8 +866,8 @@ template <typename T> struct FMT_EXTERN_TEMPLATE_API divtest_table_entry {
// Static data is placed in this class template for the header-only config.
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
static const uint64_t powers_of_10_64[];
- static const uint32_t zero_or_powers_of_10_32[];
- static const uint64_t zero_or_powers_of_10_64[];
+ static const uint32_t zero_or_powers_of_10_32_new[];
+ static const uint64_t zero_or_powers_of_10_64_new[];
static const uint64_t grisu_pow10_significands[];
static const int16_t grisu_pow10_exponents[];
static const divtest_table_entry<uint32_t> divtest_table_for_pow5_32[];
@@ -891,6 +891,10 @@ template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
static const char signs[];
static const char left_padding_shifts[5];
static const char right_padding_shifts[5];
+
+ // DEPRECATED! These are for ABI compatibility.
+ static const uint32_t zero_or_powers_of_10_32[];
+ static const uint64_t zero_or_powers_of_10_64[];
};
// Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
@@ -917,7 +921,7 @@ struct data : basic_data<> {};
inline int count_digits(uint64_t n) {
// https://github.com/fmtlib/format-benchmark/blob/master/digits10
auto t = bsr2log10(FMT_BUILTIN_CLZLL(n | 1) ^ 63);
- return t - (n < data::zero_or_powers_of_10_64[t]);
+ return t - (n < data::zero_or_powers_of_10_64_new[t]);
}
#else
// Fallback version of count_digits used when __builtin_clz is not available.
@@ -984,7 +988,7 @@ template <> int count_digits<4>(detail::fallback_uintptr n);
// Optional version of count_digits for better performance on 32-bit platforms.
inline int count_digits(uint32_t n) {
auto t = bsr2log10(FMT_BUILTIN_CLZ(n | 1) ^ 31);
- return t - (n < data::zero_or_powers_of_10_32[t]);
+ return t - (n < data::zero_or_powers_of_10_32_new[t]);
}
#endif
@@ -3056,8 +3060,7 @@ struct format_handler : detail::error_handler {
basic_format_parse_context<Char> parse_context;
Context context;
- format_handler(OutputIt out,
- basic_string_view<Char> str,
+ format_handler(OutputIt out, basic_string_view<Char> str,
basic_format_args<Context> format_args, detail::locale_ref loc)
: parse_context(str), context(out, format_args, loc) {}
@@ -3080,8 +3083,8 @@ struct format_handler : detail::error_handler {
FMT_INLINE void on_replacement_field(int id, const Char*) {
auto arg = get_arg(context, id);
context.advance_to(visit_format_arg(
- default_arg_formatter<OutputIt, Char>{
- context.out(), context.args(), context.locale()},
+ default_arg_formatter<OutputIt, Char>{context.out(), context.args(),
+ context.locale()},
arg));
}
@@ -3105,8 +3108,8 @@ struct format_handler : detail::error_handler {
if (begin == end || *begin != '}')
on_error("missing '}' in format string");
}
- context.advance_to(
- visit_format_arg(arg_formatter<OutputIt, Char>(context, &parse_context, &specs), arg));
+ context.advance_to(visit_format_arg(
+ arg_formatter<OutputIt, Char>(context, &parse_context, &specs), arg));
return begin;
}
};
@@ -3776,8 +3779,8 @@ void detail::vformat_to(
arg);
return;
}
- format_handler<iterator, Char, buffer_context<Char>> h(
- out, format_str, args, loc);
+ format_handler<iterator, Char, buffer_context<Char>> h(out, format_str, args,
+ loc);
parse_format_string<false>(format_str, h);
}
@@ -3786,6 +3789,7 @@ extern template void detail::vformat_to(detail::buffer<char>&, string_view,
basic_format_args<format_context>,
detail::locale_ref);
namespace detail {
+
extern template FMT_API std::string grouping_impl<char>(locale_ref loc);
extern template FMT_API std::string grouping_impl<wchar_t>(locale_ref loc);
extern template FMT_API char thousands_sep_impl<char>(locale_ref loc);
diff --git a/include/fmt/locale.h b/include/fmt/locale.h
index 517f6505..7301bf92 100644
--- a/include/fmt/locale.h
+++ b/include/fmt/locale.h
@@ -51,10 +51,10 @@ inline OutputIt vformat_to(
}
template <typename OutputIt, typename S, typename... Args,
- typename Char = char_t<S>,
- FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
-inline OutputIt format_to(OutputIt out, const std::locale& loc,
- const S& format_str, Args&&... args) {
+ bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value>
+inline auto format_to(OutputIt out, const std::locale& loc,
+ const S& format_str, Args&&... args) ->
+ typename std::enable_if<enable, OutputIt>::type {
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
return vformat_to(out, loc, to_string_view(format_str), vargs);
}
diff --git a/src/format.cc b/src/format.cc
index 72713416..bca87b03 100644
--- a/src/format.cc
+++ b/src/format.cc
@@ -23,6 +23,36 @@ int format_float(char* buf, std::size_t size, const char* format, int precision,
return precision < 0 ? snprintf_ptr(buf, size, format, value)
: snprintf_ptr(buf, size, format, precision, value);
}
+
+template dragonbox::decimal_fp<float> dragonbox::to_decimal(float x)
+ FMT_NOEXCEPT;
+template dragonbox::decimal_fp<double> dragonbox::to_decimal(double x)
+ FMT_NOEXCEPT;
+
+// DEPRECATED! This function exists for ABI compatibility.
+template <typename Char>
+typename basic_format_context<std::back_insert_iterator<buffer<Char>>,
+ Char>::iterator
+vformat_to(buffer<Char>& buf, basic_string_view<Char> format_str,
+ basic_format_args<basic_format_context<
+ std::back_insert_iterator<buffer<type_identity_t<Char>>>,
+ type_identity_t<Char>>>
+ args) {
+ using iterator = std::back_insert_iterator<buffer<char>>;
+ using context = basic_format_context<
+ std::back_insert_iterator<buffer<type_identity_t<Char>>>,
+ type_identity_t<Char>>;
+ auto out = iterator(buf);
+ format_handler<iterator, Char, context> h(out, format_str, args, {});
+ parse_format_string<false>(format_str, h);
+ return out;
+}
+template basic_format_context<std::back_insert_iterator<buffer<char>>,
+ char>::iterator
+vformat_to(buffer<char>&, string_view,
+ basic_format_args<basic_format_context<
+ std::back_insert_iterator<buffer<type_identity_t<char>>>,
+ type_identity_t<char>>>);
} // namespace detail
template struct FMT_INSTANTIATION_DEF_API detail::basic_data<void>;