Update changelog and disable internal

This commit is contained in:
Victor Zverovich 2020-06-26 17:24:03 -07:00
parent 3135d95fd9
commit 98a7a8b405
6 changed files with 126 additions and 58 deletions

View File

@ -1,3 +1,69 @@
7.0.0 - TBD
* Reduced the library size. For example, on macOS the stripped binary
statically linked with {fmt} shrinked from ~368k to less than 100k:
http://www.zverovich.net/2020/05/21/reducing-library-size.html
* Named arguments are now stored on stack (no dynamic memory allocations) and
the generated binary code is more compact and efficient. For example
.. code:: c++
#include <fmt/core.h>
int main() {
fmt::print("The answer is {answer}\n", fmt::arg("answer", 42));
}
compiles to just (`godbolt <https://godbolt.org/z/NcfEp_>`__)
.. code:: asm
.LC0:
.string "answer"
.LC1:
.string "The answer is {answer}\n"
main:
sub rsp, 56
mov edi, OFFSET FLAT:.LC1
mov esi, 23
movabs rdx, 4611686018427387905
lea rax, [rsp+32]
lea rcx, [rsp+16]
mov QWORD PTR [rsp+8], 1
mov QWORD PTR [rsp], rax
mov DWORD PTR [rsp+16], 42
mov QWORD PTR [rsp+32], OFFSET FLAT:.LC0
mov DWORD PTR [rsp+40], 0
call fmt::v6::vprint(fmt::v6::basic_string_view<char>, fmt::v6::format_args)
xor eax, eax
add rsp, 56
ret
.L.str.1:
.asciz "answer"
* Implemented the ``'L'`` specifier for locale-specific formatting of
floating-point numbers to improve compatibility with ``std::format``
(`#1624 <https://github.com/fmtlib/fmt/issues/1624>`_).
* Improved documentation
(`#1643 <https://github.com/fmtlib/fmt/pull/1643>`_).
Thanks `@senior7515 (Alexander Gallego) <https://github.com/senior7515>`_,
* Fixed various warnings and compilation issues
(`#1616 <https://github.com/fmtlib/fmt/pull/1616>`_,
`#1622 <https://github.com/fmtlib/fmt/issues/1622>`_,
`#1627 <https://github.com/fmtlib/fmt/pull/1627>`_,
`#1628 <https://github.com/fmtlib/fmt/issues/1628>`_,
`#1629 <https://github.com/fmtlib/fmt/pull/1629>`_
`#1631 <https://github.com/fmtlib/fmt/issues/1631>`_,
`#1633 <https://github.com/fmtlib/fmt/pull/1633>`_).
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>`_.
6.2.1 - 2020-05-09
------------------

View File

@ -332,7 +332,9 @@ enum char8_type : unsigned char {};
#endif
} // namespace detail
#ifdef FMT_USE_INTERNAL
namespace internal = detail; // DEPRECATED
#endif
/**
An implementation of ``std::basic_string_view`` for pre-C++17. It provides a
@ -1592,7 +1594,7 @@ class dynamic_format_arg_store
void clear() {
data_.clear();
named_info_.clear();
dynamic_args_ = internal::dynamic_arg_list();
dynamic_args_ = detail::dynamic_arg_list();
}
/**

View File

@ -1373,7 +1373,7 @@ struct stringifier {
}
std::string operator()(basic_format_arg<format_context>::handle h) const {
memory_buffer buf;
internal::buffer<char>& base = buf;
detail::buffer<char>& base = buf;
format_parse_context parse_ctx({});
format_context format_ctx(std::back_inserter(base), {}, {});
h.format(parse_ctx, format_ctx);

View File

@ -39,7 +39,7 @@ class custom_arg_formatter
std::string custom_vformat(fmt::string_view format_str, fmt::format_args args) {
fmt::memory_buffer buffer;
fmt::internal::buffer<char>& base = buffer;
fmt::detail::buffer<char>& base = buffer;
// Pass custom argument formatter as a template arg to vwrite.
fmt::vformat_to<custom_arg_formatter>(std::back_inserter(base), format_str,
args);

View File

@ -38,9 +38,9 @@ namespace std {
template<class Out, class charT> class basic_format_context;
using format_context = basic_format_context<
/* unspecified */ std::back_insert_iterator<fmt::internal::buffer<char>>, char>;
/* unspecified */ std::back_insert_iterator<fmt::detail::buffer<char>>, char>;
using wformat_context = basic_format_context<
/* unspecified */ std::back_insert_iterator<fmt::internal::buffer<wchar_t>>, wchar_t>;
/* unspecified */ std::back_insert_iterator<fmt::detail::buffer<wchar_t>>, wchar_t>;
template<class T, class charT = char> struct formatter {
formatter() = delete;
@ -219,7 +219,7 @@ namespace std {
// Implementation details:
using format_arg = basic_format_arg<basic_format_context>;
basic_format_context(Out out, basic_format_args<basic_format_context> args, fmt::internal::locale_ref)
basic_format_context(Out out, basic_format_args<basic_format_context> args, fmt::detail::locale_ref)
: args_(args), out_(out) {}
detail::error_handler error_handler() const { return {}; }
basic_format_arg<basic_format_context> arg(fmt::basic_string_view<charT>) const {
@ -490,10 +490,10 @@ namespace detail {
template <typename OutputIt, typename Char>
class arg_formatter
: public fmt::internal::arg_formatter_base<OutputIt, Char, error_handler> {
: public fmt::detail::arg_formatter_base<OutputIt, Char, error_handler> {
private:
using char_type = Char;
using base = fmt::internal::arg_formatter_base<OutputIt, Char, error_handler>;
using base = fmt::detail::arg_formatter_base<OutputIt, Char, error_handler>;
using format_context = std::basic_format_context<OutputIt, Char>;
using parse_context = basic_format_parse_context<Char>;
@ -528,36 +528,36 @@ class arg_formatter
};
template <typename Context>
inline fmt::internal::type get_type(basic_format_arg<Context> arg) {
inline fmt::detail::type get_type(basic_format_arg<Context> arg) {
return visit_format_arg([&] (auto val) {
using char_type = typename Context::char_type;
using T = decltype(val);
if (std::is_same_v<T, monostate>)
return fmt::internal::type::none_type;
return fmt::detail::type::none_type;
if (std::is_same_v<T, bool>)
return fmt::internal::type::bool_type;
return fmt::detail::type::bool_type;
if (std::is_same_v<T, char_type>)
return fmt::internal::type::char_type;
return fmt::detail::type::char_type;
if (std::is_same_v<T, int>)
return fmt::internal::type::int_type;
return fmt::detail::type::int_type;
if (std::is_same_v<T, unsigned int>)
return fmt::internal::type::uint_type;
return fmt::detail::type::uint_type;
if (std::is_same_v<T, long long int>)
return fmt::internal::type::long_long_type;
return fmt::detail::type::long_long_type;
if (std::is_same_v<T, unsigned long long int>)
return fmt::internal::type::ulong_long_type;
return fmt::detail::type::ulong_long_type;
if (std::is_same_v<T, double>)
return fmt::internal::type::double_type;
return fmt::detail::type::double_type;
if (std::is_same_v<T, long double>)
return fmt::internal::type::long_double_type;
return fmt::detail::type::long_double_type;
if (std::is_same_v<T, const char_type*>)
return fmt::internal::type::cstring_type;
return fmt::detail::type::cstring_type;
if (std::is_same_v<T, basic_string_view<char_type>>)
return fmt::internal::type::string_type;
return fmt::detail::type::string_type;
if (std::is_same_v<T, const void*>)
return fmt::internal::type::pointer_type;
return fmt::detail::type::pointer_type;
assert(get_value(arg).index() == 12);
return fmt::internal::type::custom_type;
return fmt::detail::type::custom_type;
}, arg);
}
@ -585,13 +585,13 @@ struct format_handler : detail::error_handler {
format_handler(iterator out, basic_string_view<Char> str,
basic_format_args<Context> format_args,
fmt::internal::locale_ref loc)
fmt::detail::locale_ref loc)
: parse_ctx(str), context(out, format_args, loc) {}
void on_text(const Char* begin, const Char* end) {
auto size = fmt::internal::to_unsigned(end - begin);
auto size = fmt::detail::to_unsigned(end - begin);
auto out = context.out();
auto&& it = fmt::internal::reserve(out, size);
auto&& it = fmt::detail::reserve(out, size);
it = std::copy_n(begin, size, it);
context.advance_to(out);
}
@ -614,9 +614,9 @@ struct format_handler : detail::error_handler {
custom_formatter<Context> f(parse_ctx, context);
if (visit_format_arg(f, arg)) return &*parse_ctx.begin();
fmt::basic_format_specs<Char> specs;
using fmt::internal::specs_handler;
using fmt::detail::specs_handler;
using parse_context = basic_format_parse_context<Char>;
fmt::internal::specs_checker<specs_handler<parse_context, Context>> handler(
fmt::detail::specs_checker<specs_handler<parse_context, Context>> handler(
specs_handler<parse_context, Context>(specs, parse_ctx, context), get_type(arg));
begin = parse_format_specs(begin, end, handler);
if (begin == end || *begin != '}') on_error("missing '}' in format string");
@ -635,45 +635,45 @@ struct formatter {
// terminating '}'.
template <typename ParseContext>
FMT_CONSTEXPR typename ParseContext::iterator parse(ParseContext& ctx) {
namespace internal = fmt::internal;
typedef internal::dynamic_specs_handler<ParseContext> handler_type;
auto type = internal::mapped_type_constant<T, fmt::buffer_context<Char>>::value;
internal::specs_checker<handler_type> handler(handler_type(specs_, ctx),
namespace detail = fmt::detail;
typedef detail::dynamic_specs_handler<ParseContext> handler_type;
auto type = detail::mapped_type_constant<T, fmt::buffer_context<Char>>::value;
detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
type);
auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
auto type_spec = specs_.type;
auto eh = ctx.error_handler();
switch (type) {
case internal::type::none_type:
case detail::type::none_type:
FMT_ASSERT(false, "invalid argument type");
break;
case internal::type::int_type:
case internal::type::uint_type:
case internal::type::long_long_type:
case internal::type::ulong_long_type:
case internal::type::bool_type:
case detail::type::int_type:
case detail::type::uint_type:
case detail::type::long_long_type:
case detail::type::ulong_long_type:
case detail::type::bool_type:
handle_int_type_spec(type_spec,
internal::int_type_checker<decltype(eh)>(eh));
detail::int_type_checker<decltype(eh)>(eh));
break;
case internal::type::char_type:
case detail::type::char_type:
handle_char_specs(
&specs_, internal::char_specs_checker<decltype(eh)>(type_spec, eh));
&specs_, detail::char_specs_checker<decltype(eh)>(type_spec, eh));
break;
case internal::type::double_type:
case internal::type::long_double_type:
internal::parse_float_type_spec(specs_, eh);
case detail::type::double_type:
case detail::type::long_double_type:
detail::parse_float_type_spec(specs_, eh);
break;
case internal::type::cstring_type:
internal::handle_cstring_type_spec(
type_spec, internal::cstring_type_checker<decltype(eh)>(eh));
case detail::type::cstring_type:
detail::handle_cstring_type_spec(
type_spec, detail::cstring_type_checker<decltype(eh)>(eh));
break;
case internal::type::string_type:
internal::check_string_type_spec(type_spec, eh);
case detail::type::string_type:
detail::check_string_type_spec(type_spec, eh);
break;
case internal::type::pointer_type:
internal::check_pointer_type_spec(type_spec, eh);
case detail::type::pointer_type:
detail::check_pointer_type_spec(type_spec, eh);
break;
case internal::type::custom_type:
case detail::type::custom_type:
// Custom format specifiers should be checked in parse functions of
// formatter specializations.
break;
@ -683,9 +683,9 @@ struct formatter {
template <typename FormatContext>
auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
fmt::internal::handle_dynamic_spec<fmt::internal::width_checker>(
fmt::detail::handle_dynamic_spec<fmt::detail::width_checker>(
specs_.width, specs_.width_ref, ctx);
fmt::internal::handle_dynamic_spec<fmt::internal::precision_checker>(
fmt::detail::handle_dynamic_spec<fmt::detail::precision_checker>(
specs_.precision, specs_.precision_ref, ctx);
using af = arg_formatter<typename FormatContext::iterator,
typename FormatContext::char_type>;
@ -694,7 +694,7 @@ struct formatter {
}
private:
fmt::internal::dynamic_format_specs<Char> specs_;
fmt::detail::dynamic_format_specs<Char> specs_;
};
} // namespace detail
@ -711,11 +711,11 @@ template<class... Args>
string vformat(string_view fmt, format_args args) {
fmt::memory_buffer mbuf;
fmt::internal::buffer<char>& buf = mbuf;
fmt::detail::buffer<char>& buf = mbuf;
using af = detail::arg_formatter<fmt::format_context::iterator, char>;
detail::format_handler<af, char, format_context>
h(std::back_inserter(buf), fmt, args, {});
fmt::internal::parse_format_string<false>(fmt::to_string_view(fmt), h);
fmt::detail::parse_format_string<false>(fmt::to_string_view(fmt), h);
return to_string(mbuf);
}
@ -738,7 +738,7 @@ template<class Out>
using af = detail::arg_formatter<Out, char>;
detail::format_handler<af, char, basic_format_context<Out, char>>
h(out, fmt, args, {});
fmt::internal::parse_format_string<false>(fmt::to_string_view(fmt), h);
fmt::detail::parse_format_string<false>(fmt::to_string_view(fmt), h);
return h.context.out();
}

View File

@ -1846,7 +1846,7 @@ class mock_arg_formatter
static void custom_vformat(fmt::string_view format_str, fmt::format_args args) {
fmt::memory_buffer buffer;
fmt::internal::buffer<char>& base = buffer;
fmt::detail::buffer<char>& base = buffer;
fmt::vformat_to<mock_arg_formatter>(std::back_inserter(base), format_str,
args);
}