From f348d1a211bcfa8c6f70195d91ad3ae783b64130 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 7 Jan 2024 17:44:40 -0800 Subject: [PATCH] Reintroduce back_insert_iterator detection --- include/fmt/core.h | 53 ++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 849890ab..f5d27cd3 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -478,6 +478,25 @@ FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, std::size_t n) } return 0; } + +template +struct is_back_insert_iterator : std::false_type {}; +template +struct is_back_insert_iterator< + It, + bool_constant())), + It>::value>> : std::true_type {}; + +// Extracts a reference to the container from *insert_iterator. +template +inline auto get_container(OutputIt it) -> typename OutputIt::container_type& { + struct accessor : OutputIt { + accessor(OutputIt base) : OutputIt(base) {} + using OutputIt::container; + }; + return *accessor(it).container; +} } // namespace detail template @@ -1034,14 +1053,17 @@ template class iterator_buffer : public buffer { }; // A buffer that writes to a container with the contiguous storage. -template -class iterator_buffer, - enable_if_t::value, - typename Container::value_type>> - : public buffer { +template +class iterator_buffer< + OutputIt, + enable_if_t::value && + is_contiguous::value, + typename OutputIt::container_type::value_type>> + : public buffer { private: - using value_type = typename Container::value_type; - Container& container_; + using container_type = typename OutputIt::container_type; + using value_type = typename container_type::value_type; + container_type& container_; static FMT_CONSTEXPR20 void grow(buffer& buf, size_t capacity) { auto& self = static_cast(buf); @@ -1050,14 +1072,12 @@ class iterator_buffer, } public: - explicit iterator_buffer(Container& c) + explicit iterator_buffer(container_type& c) : buffer(grow, c.size()), container_(c) {} - explicit iterator_buffer(back_insert_iterator out, size_t = 0) + explicit iterator_buffer(OutputIt out, size_t = 0) : iterator_buffer(get_container(out)) {} - auto out() -> back_insert_iterator { - return back_inserter(container_); - } + auto out() -> OutputIt { return back_inserter(container_); } }; // A buffer that counts the number of code units written discarding the output. @@ -1557,15 +1577,6 @@ struct is_output_iterator< It, T, void_t()++ = std::declval())>> : std::true_type {}; -template -struct is_back_insert_iterator : std::false_type {}; -template -struct is_back_insert_iterator< - It, bool_constant())), - It>::value>> : std::true_type {}; - // A type-erased reference to an std::locale to avoid a heavy include. class locale_ref { private: