================ @@ -319,188 +353,222 @@ struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container<back_insert_iterato using type = _Container; }; -/// Write policy for inserting the buffer in a container. -template <class _Container> -class _LIBCPP_TEMPLATE_VIS __writer_container { +// A dynamically growing buffer. +template <__fmt_char_type _CharT> +class _LIBCPP_TEMPLATE_VIS __allocating_buffer : public __output_buffer<_CharT> { public: - using _CharT = typename _Container::value_type; + __allocating_buffer(const __allocating_buffer&) = delete; + __allocating_buffer& operator=(const __allocating_buffer&) = delete; - _LIBCPP_HIDE_FROM_ABI explicit __writer_container(back_insert_iterator<_Container> __out_it) - : __container_{__out_it.__get_container()} {} + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __allocating_buffer() : __allocating_buffer{nullptr} {} - _LIBCPP_HIDE_FROM_ABI auto __out_it() { return std::back_inserter(*__container_); } + [[nodiscard]] + _LIBCPP_HIDE_FROM_ABI explicit __allocating_buffer(__max_output_size* __max_output_size) + : __output_buffer<_CharT>{__buffer_, __buffer_size_, __prepare_write, __max_output_size} {} - _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { - __container_->insert(__container_->end(), __ptr, __ptr + __n); + _LIBCPP_HIDE_FROM_ABI ~__allocating_buffer() { + if (__ptr_ != __buffer_) { + ranges::destroy_n(__ptr_, this->__size()); + allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, this->__capacity()); + } } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, this->__size()}; } + private: - _Container* __container_; -}; + // At the moment the allocator is hard-code. There might be reasons to have + // an allocator trait in the future. This ensures forward compatibility. + using _Alloc = allocator<_CharT>; + _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_; -/// Selects the type of the writer used for the output iterator. -template <class _OutIt, class _CharT> -class _LIBCPP_TEMPLATE_VIS __writer_selector { - using _Container = typename __back_insert_iterator_container<_OutIt>::type; + // Since allocating is expensive the class has a small internal buffer. When + // its capacity is exceeded a dynamic buffer will be allocated. + static constexpr size_t __buffer_size_ = 256; + _CharT __buffer_[__buffer_size_]; ---------------- ldionne wrote:
You could rename this to `__small_buffer`, which makes it easier to track that this is basically a SBO. https://github.com/llvm/llvm-project/pull/108990 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits