From 48d7fb265bc0c51a7bf8282b41536853182a8c21 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 7 Jan 2024 18:43:27 -0800 Subject: [PATCH] Merge back_insert_iterator and appender --- include/fmt/core.h | 61 ++++++++++++-------------------------------- include/fmt/format.h | 12 +++------ include/fmt/xchar.h | 6 ++--- 3 files changed, 24 insertions(+), 55 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index f5d27cd3..a9a5527e 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -331,31 +331,6 @@ struct monostate { constexpr monostate() {} }; -// An implementation of back_insert_iterator to avoid dependency on . -template class back_insert_iterator { - private: - Container* container_; - - friend auto get_container(back_insert_iterator it) -> Container& { - return *it.container_; - } - - public: - using difference_type = ptrdiff_t; - FMT_UNCHECKED_ITERATOR(back_insert_iterator); - - explicit back_insert_iterator(Container& c) : container_(&c) {} - - auto operator=(const typename Container::value_type& value) - -> back_insert_iterator& { - container_->push_back(value); - return *this; - } - auto operator*() -> back_insert_iterator& { return *this; } - auto operator++() -> back_insert_iterator& { return *this; } - auto operator++(int) -> back_insert_iterator { return *this; } -}; - // An enable_if helper to be used in template parameters which results in much // shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed // to workaround a bug in MSVC 2019 (see #1140 and #1186). @@ -1141,30 +1116,32 @@ using has_formatter = std::is_constructible>; // An output iterator that appends to a buffer. It is used instead of -// back_insert_iterator to reduce symbol sizes for the common case. -class appender { +// back_insert_iterator to reduce symbol sizes and avoid dependency. +template class basic_appender { private: - detail::buffer* buffer_; + detail::buffer* buffer_; - friend auto get_container(appender app) -> detail::buffer& { + friend auto get_container(basic_appender app) -> detail::buffer& { return *app.buffer_; } public: using difference_type = ptrdiff_t; - FMT_UNCHECKED_ITERATOR(appender); + FMT_UNCHECKED_ITERATOR(basic_appender); - appender(detail::buffer& buf) : buffer_(&buf) {} + basic_appender(detail::buffer& buf) : buffer_(&buf) {} - auto operator=(char c) -> appender& { + auto operator=(T c) -> basic_appender& { buffer_->push_back(c); return *this; } - auto operator*() -> appender& { return *this; } - auto operator++() -> appender& { return *this; } - auto operator++(int) -> appender { return *this; } + auto operator*() -> basic_appender& { return *this; } + auto operator++() -> basic_appender& { return *this; } + auto operator++(int) -> basic_appender { return *this; } }; +using appender = basic_appender; + namespace detail { template @@ -1183,18 +1160,14 @@ constexpr auto has_const_formatter() -> bool { return has_const_formatter_impl(static_cast(nullptr)); } -template -using buffer_appender = conditional_t::value, appender, - back_insert_iterator>>; +template using buffer_appender = basic_appender; // Maps an output iterator to a buffer. template auto get_buffer(OutputIt out) -> iterator_buffer { return iterator_buffer(out); } -template , Buf>::value)> -auto get_buffer(back_insert_iterator out) -> buffer& { +template auto get_buffer(basic_appender out) -> buffer& { return get_container(out); } @@ -1816,7 +1789,7 @@ template class basic_format_context { template using buffer_context = basic_format_context, Char>; -using format_context = buffer_context; +using format_context = basic_format_context; template using is_formattable = bool_constant struct vformat_args { - using type = basic_format_args< - basic_format_context>, Char>>; + using type = + basic_format_args, Char>>; }; template <> struct vformat_args { using type = format_args; diff --git a/include/fmt/format.h b/include/fmt/format.h index 2fdd18fb..7a0c3ca6 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -271,12 +271,7 @@ FMT_END_NAMESPACE #endif namespace std { -template <> struct iterator_traits { - using value_type = void; - using iterator_category = std::output_iterator_tag; -}; -template -struct iterator_traits> { +template struct iterator_traits> { using value_type = void; using iterator_category = std::output_iterator_tag; }; @@ -556,8 +551,9 @@ auto copy_str(InputIt begin, InputIt end, appender out) -> appender { return out; } template -auto copy_str(InputIt begin, InputIt end, back_insert_iterator out) - -> back_insert_iterator { +auto copy_str(InputIt begin, InputIt end, + std::back_insert_iterator out) + -> std::back_insert_iterator { get_container(out).append(begin, end); return out; } diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index 01d2fda7..df5ad2af 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -46,9 +46,9 @@ struct format_string_char::value>> { template using format_string_char_t = typename format_string_char::type; -inline auto write_loc(back_insert_iterator> out, - loc_value value, const format_specs& specs, - locale_ref loc) -> bool { +inline auto write_loc(basic_appender out, loc_value value, + const format_specs& specs, locale_ref loc) + -> bool { #ifndef FMT_STATIC_THOUSANDS_SEPARATOR auto& numpunct = std::use_facet>(loc.get());