From c953c6160a97bec282b628776058b226252e9a19 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 17 Apr 2021 06:19:53 -0700 Subject: [PATCH 1/9] Fix a severe code bloat issue in --- stl/inc/format | 343 ++++++++++++------ .../test.cpp | 5 +- 2 files changed, 243 insertions(+), 105 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 939581aff94..64f60779478 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2557,8 +2557,202 @@ template <_Format_supported_charT _CharT, class _Traits> struct formatter, _CharT> : _Formatter_base, _CharT, _Basic_format_arg_type::_String_type> {}; -using format_context = basic_format_context, string::value_type>; -using wformat_context = basic_format_context, wstring::value_type>; +template +class _Fmt_buffer { +private: + _Ty* _Ptr = nullptr; + size_t _Size = 0; + size_t _Capacity = 0; + +protected: + explicit _Fmt_buffer(const size_t _Sz) noexcept : _Size(_Sz), _Capacity(_Sz) {} + _Fmt_buffer(_Ty* _Data, const size_t _Sz, const size_t _Cap) noexcept : _Ptr(_Data), _Size(_Sz), _Capacity(_Cap) {} + + void _Set(_Ty* _Buf_data, const size_t _Buf_capacity) noexcept { + _Ptr = _Buf_data; + _Capacity = _Buf_capacity; + } + + virtual void _Grow(size_t _Capacity) = 0; + +public: + using value_type = _Ty; + using const_reference = const _Ty&; + + _Fmt_buffer(const _Fmt_buffer&) = delete; + void operator=(const _Fmt_buffer&) = delete; + + _NODISCARD _Ty* begin() noexcept { + return _Ptr; + } + _NODISCARD _Ty* end() noexcept { + return _Ptr + _Size; + } + + _NODISCARD size_t size() const noexcept { + return _Size; + } + + _NODISCARD size_t capacity() const noexcept { + return _Capacity; + } + + void clear() noexcept { + _Size = 0; + } + + void try_resize(const size_t _Count) { + try_reserve(_Count); + _Size = _Count <= _Capacity ? _Count : _Capacity; + } + + void try_reserve(const size_t _New_capacity) { + if (_New_capacity > _Capacity) { + _Grow(_New_capacity); + } + } + + void push_back(const _Ty _Value) { + try_reserve(_Size + 1); + _Ptr[_Size++] = _Value; + } +}; + +struct _Fmt_buffer_traits { + explicit _Fmt_buffer_traits(ptrdiff_t) {} + _NODISCARD size_t count() const noexcept { + return 0; + } + _NODISCARD size_t limit(const size_t _Size) noexcept { + return _Size; + } +}; + +class _Fmt_fixed_buffer_traits { +private: + size_t _Count = 0; + size_t _Limit; + +public: + explicit _Fmt_fixed_buffer_traits(const ptrdiff_t _Lim) noexcept : _Limit(static_cast(_Lim)) {} + _NODISCARD size_t count() const noexcept { + return _Count; + } + _NODISCARD size_t limit(const size_t _Size) noexcept { + size_t _Avail = _Limit > _Count ? _Limit - _Count : 0; + _Count += _Size; + return _Size < _Avail ? _Size : _Avail; + } +}; + +inline constexpr size_t _Fmt_buffer_size = 256; + +template +class _Fmt_iterator_buffer final : public _Traits, public _Fmt_buffer<_Ty> { +private: + _OutputIt _Out; + _Ty _Data[_Fmt_buffer_size]; + +protected: + void _Grow(size_t) final override { + if (this->size() == _Fmt_buffer_size) { + _Flush(); + } + } + void _Flush() { + auto _Size = this->size(); + this->clear(); + _Out = _STD _Copy_unchecked(_Data, _Data + this->limit(_Size), _STD move(_Out)); + } + +public: + explicit _Fmt_iterator_buffer(_OutputIt _Output, ptrdiff_t _Size = _Fmt_buffer_size) + : _Traits(_Size), _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size), _Out(_STD move(_Output)) {} + ~_Fmt_iterator_buffer() { + if (this->size() != 0) { + _Flush(); + } + } + + _NODISCARD _OutputIt out() { + _Flush(); + return _STD move(_Out); + } + _NODISCARD ptrdiff_t count() const noexcept { + return static_cast(_Traits::count() + this->size()); + } +}; + +template +class _Fmt_iterator_buffer<_Ty*, _Ty> final : public _Fmt_buffer<_Ty> { +protected: + void _Grow(size_t) final override {} + +public: + explicit _Fmt_iterator_buffer(_Ty* _Out, ptrdiff_t = 0) : _Fmt_buffer<_Ty>(_Out, 0, ~size_t()) {} + + _NODISCARD _Ty* out() noexcept { + return this->end(); + } +}; + +template +class _Fmt_iterator_buffer<_STD back_insert_iterator<_Container>, + enable_if_t<_STD contiguous_iterator, typename _Container::value_type>> + final : public _Fmt_buffer { +private: + _Container& _Cont; + + struct _Accessor : _STD back_insert_iterator<_Container> { + _Accessor(_STD back_insert_iterator<_Container> _Iter) : back_insert_iterator<_Container>(_Iter) {} + using _STD back_insert_iterator<_Container>::container; + }; + +protected: + void _Grow(size_t _Capacity) final override { + _Cont.resize(_Capacity); + this->_Set(&_Cont[0], _Capacity); + } + +public: + explicit _Fmt_iterator_buffer(_Container& _C) + : _Fmt_buffer(_C.size()), _Cont(_C) {} + explicit _Fmt_iterator_buffer(_STD back_insert_iterator<_Container> _Out, ptrdiff_t = 0) + : _Fmt_iterator_buffer(*_Accessor(_STD move(_Out)).container) {} + + _NODISCARD auto out() { + return _STD back_inserter(_Cont); + } +}; + +template +class _Fmt_counting_buffer final : public _Fmt_buffer<_Ty> { +private: + _Ty _Data[_Fmt_buffer_size]; + size_t _Count = 0; + +protected: + void _Grow(size_t) final override { + if (this->size() != _Fmt_buffer_size) { + return; + } + _Count += this->size(); + this->clear(); + } + +public: + _Fmt_counting_buffer() : _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size) {} + + _NODISCARD size_t count() const noexcept { + return _Count + this->size(); + } +}; + +using _Fmt_it = back_insert_iterator<_Fmt_buffer>; +using _Fmt_wit = back_insert_iterator<_Fmt_buffer>; + +using format_context = basic_format_context<_Fmt_it, char>; +using wformat_context = basic_format_context<_Fmt_wit, wchar_t>; using format_args = basic_format_args; using wformat_args = basic_format_args; @@ -2613,49 +2807,57 @@ _OutputIt vformat_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const string_view _Fmt, const _Types&... _Args) { - using _Context = basic_format_context<_OutputIt, char>; - return _STD vformat_to(_STD move(_Out), _Fmt, _STD make_format_args<_Context>(_Args...)); + _Fmt_iterator_buffer<_OutputIt, char> _Buf(_STD move(_Out)); + _STD vformat_to(_Fmt_it(_Buf), _Fmt, _STD make_format_args(_Args...)); + return _Buf.out(); } template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const wstring_view _Fmt, const _Types&... _Args) { - using _Context = basic_format_context<_OutputIt, wchar_t>; - return _STD vformat_to(_STD move(_Out), _Fmt, _STD make_format_args<_Context>(_Args...)); + _Fmt_iterator_buffer<_OutputIt, wchar_t> _Buf(_STD move(_Out)); + _STD vformat_to(_Fmt_wit(_Buf), _Fmt, make_wformat_args(_Args...)); + return _Buf.out(); } template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { - using _Context = basic_format_context<_OutputIt, char>; - return _STD vformat_to(_STD move(_Out), _Loc, _Fmt, _STD make_format_args<_Context>(_Args...)); + _Fmt_iterator_buffer<_OutputIt, char> _Buf(_STD move(_Out)); + _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, make_format_args(_Args...)); + return _Buf.out(); } template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { - using _Context = basic_format_context<_OutputIt, wchar_t>; - return _STD vformat_to(_STD move(_Out), _Loc, _Fmt, _STD make_format_args<_Context>(_Args...)); + _Fmt_iterator_buffer<_OutputIt, wchar_t> _Buf(_STD move(_Out)); + _STD vformat_to(_Fmt_wit(_Buf), _Loc, _Fmt, _STD make_wformat_args(_Args...)); + return _Buf.out(); } _NODISCARD inline string vformat(const string_view _Fmt, const format_args _Args) { string _Str; - _STD vformat_to(_STD back_inserter(_Str), _Fmt, _Args); + _Fmt_iterator_buffer, char> _Buf(_STD back_inserter(_Str)); + _STD vformat_to(_Fmt_it(_Buf), _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; - _STD vformat_to(_STD back_inserter(_Str), _Fmt, _Args); + _Fmt_iterator_buffer, wchar_t> _Buf(_STD back_inserter(_Str)); + _STD vformat_to(_Fmt_wit(_Buf), _Fmt, _Args); return _Str; } _NODISCARD inline string vformat(const locale& _Loc, const string_view _Fmt, const format_args _Args) { string _Str; - _STD vformat_to(_STD back_inserter(_Str), _Loc, _Fmt, _Args); + _Fmt_iterator_buffer, char> _Buf(_STD back_inserter(_Str)); + _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const locale& _Loc, const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; - _STD vformat_to(_STD back_inserter(_Str), _Loc, _Fmt, _Args); + _Fmt_iterator_buffer, wchar_t> _Buf(_STD back_inserter(_Str)); + _STD vformat_to(_Fmt_wit(_Buf), _Loc, _Fmt, _Args); return _Str; } @@ -2679,35 +2881,6 @@ _NODISCARD wstring format(const locale& _Loc, const wstring_view _Fmt, const _Ty return _STD vformat(_Loc, _Fmt, _STD make_wformat_args(_Args...)); } -template -struct _Format_to_n_iterator { - _OutputIt _Out; - iter_difference_t<_OutputIt> _Max; - iter_difference_t<_OutputIt> _Count = 0; - - using difference_type = iter_difference_t<_OutputIt>; - - _Format_to_n_iterator& operator=(_CharT _Ch) { - if (_Count < _Max) { - *_Out++ = _Ch; - } - ++_Count; - return *this; - } - - _NODISCARD _Format_to_n_iterator& operator*() { - return *this; - } - - _Format_to_n_iterator& operator++() { - return *this; - } - - _Format_to_n_iterator& operator++(int) { - return *this; - } -}; - template struct format_to_n_result { _OutputIt out; @@ -2717,97 +2890,61 @@ struct format_to_n_result { template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n( _OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const string_view _Fmt, const _Types&... _Args) { - _Format_to_n_iterator<_OutputIt, char> _It{._Out = _STD move(_Out), ._Max = _Max}; - - using _Context = basic_format_context; - auto _Arg_store = _STD make_format_args<_Context>(_Args...); - _It = _STD vformat_to(_STD move(_It), _Fmt, _STD move(_Arg_store)); - return {.out = _STD move(_It._Out), .size = _It._Count}; + _Fmt_iterator_buffer<_OutputIt, char, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); + _STD vformat_to(_Fmt_it(_Buf), _Fmt, _STD make_format_args(_Args...)); + return {.out = _Buf.out(), .size = _Buf.count()}; } template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n( _OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const wstring_view _Fmt, const _Types&... _Args) { - _Format_to_n_iterator<_OutputIt, wchar_t> _It{._Out = _STD move(_Out), ._Max = _Max}; - - using _Context = basic_format_context; - auto _Arg_store = _STD make_format_args<_Context>(_Args...); - _It = _STD vformat_to(_STD move(_It), _Fmt, _STD move(_Arg_store)); - return {.out = _STD move(_It._Out), .size = _It._Count}; + _Fmt_iterator_buffer<_OutputIt, wchar_t, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); + _STD vformat_to(_Fmt_wit(_Buf), _Fmt, _STD make_wformat_args(_Args...)); + return {.out = _Buf.out(), .size = _Buf.count()}; } template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n(_OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { - _Format_to_n_iterator<_OutputIt, char> _It{._Out = _STD move(_Out), ._Max = _Max}; - - using _Context = basic_format_context; - auto _Arg_store = _STD make_format_args<_Context>(_Args...); - _It = _STD vformat_to(_STD move(_It), _Loc, _Fmt, _STD move(_Arg_store)); - return {.out = _STD move(_It._Out), .size = _It._Count}; + _Fmt_iterator_buffer<_OutputIt, char, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); + _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, _STD make_format_args(_Args...)); + return {.out = _Buf.out(), .size = _Buf.count()}; } template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n(_OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { - _Format_to_n_iterator<_OutputIt, wchar_t> _It{._Out = _STD move(_Out), ._Max = _Max}; - - using _Context = basic_format_context; - auto _Arg_store = _STD make_format_args<_Context>(_Args...); - _It = _STD vformat_to(_STD move(_It), _Loc, _Fmt, _STD move(_Arg_store)); - return {.out = _STD move(_It._Out), .size = _It._Count}; + _Fmt_iterator_buffer<_OutputIt, wchar_t, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); + _STD vformat_to(_Fmt_wit(_Buf), _Loc, _Fmt, _STD make_wformat_args(_Args...)); + return {.out = _Buf.out(), .size = _Buf.count()}; } -struct _Counting_iterator { - size_t _Count = 0; - - using difference_type = ptrdiff_t; - - template - _Counting_iterator& operator=(_CharT) { - ++_Count; - return *this; - } - - _NODISCARD _Counting_iterator& operator*() { - return *this; - } - - _Counting_iterator& operator++() { - return *this; - } - - _Counting_iterator& operator++(int) { - return *this; - } -}; - template _NODISCARD size_t formatted_size(const string_view _Fmt, const _Types&... _Args) { - using _Context = basic_format_context<_Counting_iterator, char>; - auto _Arg_store = _STD make_format_args<_Context>(_Args...); - return _STD vformat_to(_Counting_iterator{}, _Fmt, _STD move(_Arg_store))._Count; + _Fmt_counting_buffer _Buf; + _STD vformat_to(_Fmt_it(_Buf), _Fmt, _STD make_format_args(_Args...)); + return _Buf.count(); } template _NODISCARD size_t formatted_size(const wstring_view _Fmt, const _Types&... _Args) { - using _Context = basic_format_context<_Counting_iterator, wchar_t>; - auto _Arg_store = _STD make_format_args<_Context>(_Args...); - return _STD vformat_to(_Counting_iterator{}, _Fmt, _STD move(_Arg_store))._Count; + _Fmt_counting_buffer _Buf; + _STD vformat_to(_Fmt_wit(_Buf), _Fmt, _STD make_wformat_args(_Args...)); + return _Buf.count(); } template _NODISCARD size_t formatted_size(const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { - using _Context = basic_format_context<_Counting_iterator, char>; - auto _Arg_store = _STD make_format_args<_Context>(_Args...); - return _STD vformat_to(_Counting_iterator{}, _Loc, _Fmt, _STD move(_Arg_store))._Count; + _Fmt_counting_buffer _Buf; + _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, _STD make_format_args(_Args...)); + return _Buf.count(); } template _NODISCARD size_t formatted_size(const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { - using _Context = basic_format_context<_Counting_iterator, wchar_t>; - auto _Arg_store = _STD make_format_args<_Context>(_Args...); - return _STD vformat_to(_Counting_iterator{}, _Loc, _Fmt, _STD move(_Arg_store))._Count; + _Fmt_counting_buffer _Buf; + _STD vformat_to(_Fmt_wit(_Buf), _Loc, _Fmt, _STD make_wformat_args(_Args...)); + return _Buf.count(); } _STD_END diff --git a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp index ab37ef41f5c..78fdf60957f 100644 --- a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp @@ -47,10 +47,11 @@ struct choose_literal { template auto make_testing_format_args(Args&&... vals) { + using context = basic_format_context>, charT>; if constexpr (is_same_v) { - return make_wformat_args(forward(vals)...); + return make_wformat_args(forward(vals)...); } else { - return make_format_args(forward(vals)...); + return make_format_args(forward(vals)...); } } From c4be9b76e4a89cdaeda1ec912ac34e32170dfa8e Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 18 Apr 2021 09:03:55 -0700 Subject: [PATCH 2/9] Fix handling of a negative output limit --- stl/inc/format | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 64f60779478..18e405f774c 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2630,16 +2630,16 @@ struct _Fmt_buffer_traits { class _Fmt_fixed_buffer_traits { private: - size_t _Count = 0; - size_t _Limit; + ptrdiff_t _Count = 0; + ptrdiff_t _Limit; public: - explicit _Fmt_fixed_buffer_traits(const ptrdiff_t _Lim) noexcept : _Limit(static_cast(_Lim)) {} + explicit _Fmt_fixed_buffer_traits(const ptrdiff_t _Lim) noexcept : _Limit(_Lim) {} _NODISCARD size_t count() const noexcept { - return _Count; + return static_cast(_Count); } _NODISCARD size_t limit(const size_t _Size) noexcept { - size_t _Avail = _Limit > _Count ? _Limit - _Count : 0; + size_t _Avail = static_cast(_Limit > _Count ? _Limit - _Count : 0); _Count += _Size; return _Size < _Avail ? _Size : _Avail; } From 1ba4868722c2507ccb264aa087926d8ba380763f Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 18 Apr 2021 11:57:44 -0700 Subject: [PATCH 3/9] Formatting, remove redundant override, add noexcept --- stl/inc/format | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 18e405f774c..f4c697c4212 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2566,6 +2566,7 @@ private: protected: explicit _Fmt_buffer(const size_t _Sz) noexcept : _Size(_Sz), _Capacity(_Sz) {} + _Fmt_buffer(_Ty* _Data, const size_t _Sz, const size_t _Cap) noexcept : _Ptr(_Data), _Size(_Sz), _Capacity(_Cap) {} void _Set(_Ty* _Buf_data, const size_t _Buf_capacity) noexcept { @@ -2585,6 +2586,7 @@ public: _NODISCARD _Ty* begin() noexcept { return _Ptr; } + _NODISCARD _Ty* end() noexcept { return _Ptr + _Size; } @@ -2620,9 +2622,11 @@ public: struct _Fmt_buffer_traits { explicit _Fmt_buffer_traits(ptrdiff_t) {} + _NODISCARD size_t count() const noexcept { return 0; } + _NODISCARD size_t limit(const size_t _Size) noexcept { return _Size; } @@ -2635,9 +2639,11 @@ private: public: explicit _Fmt_fixed_buffer_traits(const ptrdiff_t _Lim) noexcept : _Limit(_Lim) {} + _NODISCARD size_t count() const noexcept { return static_cast(_Count); } + _NODISCARD size_t limit(const size_t _Size) noexcept { size_t _Avail = static_cast(_Limit > _Count ? _Limit - _Count : 0); _Count += _Size; @@ -2654,11 +2660,12 @@ private: _Ty _Data[_Fmt_buffer_size]; protected: - void _Grow(size_t) final override { + void _Grow(size_t) final { if (this->size() == _Fmt_buffer_size) { _Flush(); } } + void _Flush() { auto _Size = this->size(); this->clear(); @@ -2668,6 +2675,7 @@ protected: public: explicit _Fmt_iterator_buffer(_OutputIt _Output, ptrdiff_t _Size = _Fmt_buffer_size) : _Traits(_Size), _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size), _Out(_STD move(_Output)) {} + ~_Fmt_iterator_buffer() { if (this->size() != 0) { _Flush(); @@ -2678,6 +2686,7 @@ public: _Flush(); return _STD move(_Out); } + _NODISCARD ptrdiff_t count() const noexcept { return static_cast(_Traits::count() + this->size()); } @@ -2686,7 +2695,7 @@ public: template class _Fmt_iterator_buffer<_Ty*, _Ty> final : public _Fmt_buffer<_Ty> { protected: - void _Grow(size_t) final override {} + void _Grow(size_t) final {} public: explicit _Fmt_iterator_buffer(_Ty* _Out, ptrdiff_t = 0) : _Fmt_buffer<_Ty>(_Out, 0, ~size_t()) {} @@ -2705,11 +2714,12 @@ private: struct _Accessor : _STD back_insert_iterator<_Container> { _Accessor(_STD back_insert_iterator<_Container> _Iter) : back_insert_iterator<_Container>(_Iter) {} + using _STD back_insert_iterator<_Container>::container; }; protected: - void _Grow(size_t _Capacity) final override { + void _Grow(size_t _Capacity) final { _Cont.resize(_Capacity); this->_Set(&_Cont[0], _Capacity); } @@ -2717,10 +2727,11 @@ protected: public: explicit _Fmt_iterator_buffer(_Container& _C) : _Fmt_buffer(_C.size()), _Cont(_C) {} + explicit _Fmt_iterator_buffer(_STD back_insert_iterator<_Container> _Out, ptrdiff_t = 0) : _Fmt_iterator_buffer(*_Accessor(_STD move(_Out)).container) {} - _NODISCARD auto out() { + _NODISCARD auto out() noexcept { return _STD back_inserter(_Cont); } }; @@ -2732,7 +2743,7 @@ private: size_t _Count = 0; protected: - void _Grow(size_t) final override { + void _Grow(size_t) final { if (this->size() != _Fmt_buffer_size) { return; } From 43d081bd05a8717b9f07bd3de2632a52e1ef6cf4 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 18 Apr 2021 18:07:52 -0700 Subject: [PATCH 4/9] Add missing _STD and move buffer code next to format context where it belongs --- stl/inc/format | 423 +++++++++++++++++++++++++------------------------ 1 file changed, 212 insertions(+), 211 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index f4c697c4212..94cac56b8f8 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1496,6 +1496,214 @@ public: } }; +template +class _Fmt_buffer { +private: + _Ty* _Ptr = nullptr; + size_t _Size = 0; + size_t _Capacity = 0; + +protected: + explicit _Fmt_buffer(const size_t _Sz) noexcept : _Size(_Sz), _Capacity(_Sz) {} + + _Fmt_buffer(_Ty* _Data, const size_t _Sz, const size_t _Cap) noexcept : _Ptr(_Data), _Size(_Sz), _Capacity(_Cap) {} + + void _Set(_Ty* _Buf_data, const size_t _Buf_capacity) noexcept { + _Ptr = _Buf_data; + _Capacity = _Buf_capacity; + } + + virtual void _Grow(size_t _Capacity) = 0; + +public: + using value_type = _Ty; + using const_reference = const _Ty&; + + _Fmt_buffer(const _Fmt_buffer&) = delete; + void operator=(const _Fmt_buffer&) = delete; + + _NODISCARD _Ty* begin() noexcept { + return _Ptr; + } + + _NODISCARD _Ty* end() noexcept { + return _Ptr + _Size; + } + + _NODISCARD size_t size() const noexcept { + return _Size; + } + + _NODISCARD size_t capacity() const noexcept { + return _Capacity; + } + + void clear() noexcept { + _Size = 0; + } + + void try_resize(const size_t _Count) { + try_reserve(_Count); + _Size = _Count <= _Capacity ? _Count : _Capacity; + } + + void try_reserve(const size_t _New_capacity) { + if (_New_capacity > _Capacity) { + _Grow(_New_capacity); + } + } + + void push_back(const _Ty _Value) { + try_reserve(_Size + 1); + _Ptr[_Size++] = _Value; + } +}; + +struct _Fmt_buffer_traits { + explicit _Fmt_buffer_traits(ptrdiff_t) {} + + _NODISCARD size_t count() const noexcept { + return 0; + } + + _NODISCARD size_t limit(const size_t _Size) noexcept { + return _Size; + } +}; + +class _Fmt_fixed_buffer_traits { +private: + ptrdiff_t _Count = 0; + ptrdiff_t _Limit; + +public: + explicit _Fmt_fixed_buffer_traits(const ptrdiff_t _Lim) noexcept : _Limit(_Lim) {} + + _NODISCARD size_t count() const noexcept { + return static_cast(_Count); + } + + _NODISCARD size_t limit(const size_t _Size) noexcept { + size_t _Avail = static_cast(_Limit > _Count ? _Limit - _Count : 0); + _Count += _Size; + return _Size < _Avail ? _Size : _Avail; + } +}; + +inline constexpr size_t _Fmt_buffer_size = 256; + +template +class _Fmt_iterator_buffer final : public _Traits, public _Fmt_buffer<_Ty> { +private: + _OutputIt _Out; + _Ty _Data[_Fmt_buffer_size]; + +protected: + void _Grow(size_t) final { + if (this->size() == _Fmt_buffer_size) { + _Flush(); + } + } + + void _Flush() { + auto _Size = this->size(); + this->clear(); + _Out = _STD _Copy_unchecked(_Data, _Data + this->limit(_Size), _STD move(_Out)); + } + +public: + explicit _Fmt_iterator_buffer(_OutputIt _Output, ptrdiff_t _Size = _Fmt_buffer_size) + : _Traits(_Size), _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size), _Out(_STD move(_Output)) {} + + ~_Fmt_iterator_buffer() { + if (this->size() != 0) { + _Flush(); + } + } + + _NODISCARD _OutputIt out() { + _Flush(); + return _STD move(_Out); + } + + _NODISCARD ptrdiff_t count() const noexcept { + return static_cast(_Traits::count() + this->size()); + } +}; + +template +class _Fmt_iterator_buffer<_Ty*, _Ty> final : public _Fmt_buffer<_Ty> { +protected: + void _Grow(size_t) final {} + +public: + explicit _Fmt_iterator_buffer(_Ty* _Out, ptrdiff_t = 0) : _Fmt_buffer<_Ty>(_Out, 0, ~size_t()) {} + + _NODISCARD _Ty* out() noexcept { + return this->end(); + } +}; + +template +class _Fmt_iterator_buffer<_STD back_insert_iterator<_Container>, + enable_if_t<_STD contiguous_iterator, typename _Container::value_type>> + final : public _Fmt_buffer { +private: + _Container& _Cont; + + struct _Accessor : _STD back_insert_iterator<_Container> { + _Accessor(_STD back_insert_iterator<_Container> _Iter) : back_insert_iterator<_Container>(_Iter) {} + + using _STD back_insert_iterator<_Container>::container; + }; + +protected: + void _Grow(size_t _Capacity) final { + _Cont.resize(_Capacity); + this->_Set(&_Cont[0], _Capacity); + } + +public: + explicit _Fmt_iterator_buffer(_Container& _C) + : _Fmt_buffer(_C.size()), _Cont(_C) {} + + explicit _Fmt_iterator_buffer(_STD back_insert_iterator<_Container> _Out, ptrdiff_t = 0) + : _Fmt_iterator_buffer(*_Accessor(_STD move(_Out)).container) {} + + _NODISCARD auto out() noexcept { + return _STD back_inserter(_Cont); + } +}; + +template +class _Fmt_counting_buffer final : public _Fmt_buffer<_Ty> { +private: + _Ty _Data[_Fmt_buffer_size]; + size_t _Count = 0; + +protected: + void _Grow(size_t) final { + if (this->size() != _Fmt_buffer_size) { + return; + } + _Count += this->size(); + this->clear(); + } + +public: + _Fmt_counting_buffer() : _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size) {} + + _NODISCARD size_t count() const noexcept { + return _Count + this->size(); + } +}; + +using _Fmt_it = back_insert_iterator<_Fmt_buffer>; +using _Fmt_wit = back_insert_iterator<_Fmt_buffer>; + +using format_context = basic_format_context<_Fmt_it, char>; +using wformat_context = basic_format_context<_Fmt_wit, wchar_t>; + template _NODISCARD _OutputIt _Fmt_write(_OutputIt _Out, monostate) { _STL_INTERNAL_CHECK(false); @@ -2557,215 +2765,8 @@ template <_Format_supported_charT _CharT, class _Traits> struct formatter, _CharT> : _Formatter_base, _CharT, _Basic_format_arg_type::_String_type> {}; -template -class _Fmt_buffer { -private: - _Ty* _Ptr = nullptr; - size_t _Size = 0; - size_t _Capacity = 0; - -protected: - explicit _Fmt_buffer(const size_t _Sz) noexcept : _Size(_Sz), _Capacity(_Sz) {} - - _Fmt_buffer(_Ty* _Data, const size_t _Sz, const size_t _Cap) noexcept : _Ptr(_Data), _Size(_Sz), _Capacity(_Cap) {} - - void _Set(_Ty* _Buf_data, const size_t _Buf_capacity) noexcept { - _Ptr = _Buf_data; - _Capacity = _Buf_capacity; - } - - virtual void _Grow(size_t _Capacity) = 0; - -public: - using value_type = _Ty; - using const_reference = const _Ty&; - - _Fmt_buffer(const _Fmt_buffer&) = delete; - void operator=(const _Fmt_buffer&) = delete; - - _NODISCARD _Ty* begin() noexcept { - return _Ptr; - } - - _NODISCARD _Ty* end() noexcept { - return _Ptr + _Size; - } - - _NODISCARD size_t size() const noexcept { - return _Size; - } - - _NODISCARD size_t capacity() const noexcept { - return _Capacity; - } - - void clear() noexcept { - _Size = 0; - } - - void try_resize(const size_t _Count) { - try_reserve(_Count); - _Size = _Count <= _Capacity ? _Count : _Capacity; - } - - void try_reserve(const size_t _New_capacity) { - if (_New_capacity > _Capacity) { - _Grow(_New_capacity); - } - } - - void push_back(const _Ty _Value) { - try_reserve(_Size + 1); - _Ptr[_Size++] = _Value; - } -}; - -struct _Fmt_buffer_traits { - explicit _Fmt_buffer_traits(ptrdiff_t) {} - - _NODISCARD size_t count() const noexcept { - return 0; - } - - _NODISCARD size_t limit(const size_t _Size) noexcept { - return _Size; - } -}; - -class _Fmt_fixed_buffer_traits { -private: - ptrdiff_t _Count = 0; - ptrdiff_t _Limit; - -public: - explicit _Fmt_fixed_buffer_traits(const ptrdiff_t _Lim) noexcept : _Limit(_Lim) {} - - _NODISCARD size_t count() const noexcept { - return static_cast(_Count); - } - - _NODISCARD size_t limit(const size_t _Size) noexcept { - size_t _Avail = static_cast(_Limit > _Count ? _Limit - _Count : 0); - _Count += _Size; - return _Size < _Avail ? _Size : _Avail; - } -}; - -inline constexpr size_t _Fmt_buffer_size = 256; - -template -class _Fmt_iterator_buffer final : public _Traits, public _Fmt_buffer<_Ty> { -private: - _OutputIt _Out; - _Ty _Data[_Fmt_buffer_size]; - -protected: - void _Grow(size_t) final { - if (this->size() == _Fmt_buffer_size) { - _Flush(); - } - } - - void _Flush() { - auto _Size = this->size(); - this->clear(); - _Out = _STD _Copy_unchecked(_Data, _Data + this->limit(_Size), _STD move(_Out)); - } - -public: - explicit _Fmt_iterator_buffer(_OutputIt _Output, ptrdiff_t _Size = _Fmt_buffer_size) - : _Traits(_Size), _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size), _Out(_STD move(_Output)) {} - - ~_Fmt_iterator_buffer() { - if (this->size() != 0) { - _Flush(); - } - } - - _NODISCARD _OutputIt out() { - _Flush(); - return _STD move(_Out); - } - - _NODISCARD ptrdiff_t count() const noexcept { - return static_cast(_Traits::count() + this->size()); - } -}; - -template -class _Fmt_iterator_buffer<_Ty*, _Ty> final : public _Fmt_buffer<_Ty> { -protected: - void _Grow(size_t) final {} - -public: - explicit _Fmt_iterator_buffer(_Ty* _Out, ptrdiff_t = 0) : _Fmt_buffer<_Ty>(_Out, 0, ~size_t()) {} - - _NODISCARD _Ty* out() noexcept { - return this->end(); - } -}; - -template -class _Fmt_iterator_buffer<_STD back_insert_iterator<_Container>, - enable_if_t<_STD contiguous_iterator, typename _Container::value_type>> - final : public _Fmt_buffer { -private: - _Container& _Cont; - - struct _Accessor : _STD back_insert_iterator<_Container> { - _Accessor(_STD back_insert_iterator<_Container> _Iter) : back_insert_iterator<_Container>(_Iter) {} - - using _STD back_insert_iterator<_Container>::container; - }; - -protected: - void _Grow(size_t _Capacity) final { - _Cont.resize(_Capacity); - this->_Set(&_Cont[0], _Capacity); - } - -public: - explicit _Fmt_iterator_buffer(_Container& _C) - : _Fmt_buffer(_C.size()), _Cont(_C) {} - - explicit _Fmt_iterator_buffer(_STD back_insert_iterator<_Container> _Out, ptrdiff_t = 0) - : _Fmt_iterator_buffer(*_Accessor(_STD move(_Out)).container) {} - - _NODISCARD auto out() noexcept { - return _STD back_inserter(_Cont); - } -}; - -template -class _Fmt_counting_buffer final : public _Fmt_buffer<_Ty> { -private: - _Ty _Data[_Fmt_buffer_size]; - size_t _Count = 0; - -protected: - void _Grow(size_t) final { - if (this->size() != _Fmt_buffer_size) { - return; - } - _Count += this->size(); - this->clear(); - } - -public: - _Fmt_counting_buffer() : _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size) {} - - _NODISCARD size_t count() const noexcept { - return _Count + this->size(); - } -}; - -using _Fmt_it = back_insert_iterator<_Fmt_buffer>; -using _Fmt_wit = back_insert_iterator<_Fmt_buffer>; - -using format_context = basic_format_context<_Fmt_it, char>; -using wformat_context = basic_format_context<_Fmt_wit, wchar_t>; -using format_args = basic_format_args; -using wformat_args = basic_format_args; +using format_args = basic_format_args; +using wformat_args = basic_format_args; template _NODISCARD auto make_format_args(const _Args&... _Vals) { @@ -2826,14 +2827,14 @@ _OutputIt format_to(_OutputIt _Out, const string_view _Fmt, const _Types&... _Ar template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const wstring_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, wchar_t> _Buf(_STD move(_Out)); - _STD vformat_to(_Fmt_wit(_Buf), _Fmt, make_wformat_args(_Args...)); + _STD vformat_to(_Fmt_wit(_Buf), _Fmt, _STD make_wformat_args(_Args...)); return _Buf.out(); } template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, char> _Buf(_STD move(_Out)); - _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, make_format_args(_Args...)); + _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, _STD make_format_args(_Args...)); return _Buf.out(); } From d6601e46082c0d364b4266d56ef8e8cb38fc957a Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 19 Apr 2021 06:26:28 -0700 Subject: [PATCH 5/9] Suppress C4265, more _Uglification, use ranges data --- stl/inc/format | 192 ++++++++++++++++++++++++------------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 94cac56b8f8..29d0f37ae16 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1496,96 +1496,99 @@ public: } }; +#pragma warning(push) +#pragma warning(disable : 4265) // non-virtual destructor in base class template class _Fmt_buffer { private: - _Ty* _Ptr = nullptr; - size_t _Size = 0; - size_t _Capacity = 0; + _Ty* _Ptr_ = nullptr; + size_t _Size_ = 0; + size_t _Capacity_ = 0; protected: - explicit _Fmt_buffer(const size_t _Sz) noexcept : _Size(_Sz), _Capacity(_Sz) {} + explicit _Fmt_buffer(const size_t _Size) noexcept : _Size_(_Size), _Capacity_(_Size) {} - _Fmt_buffer(_Ty* _Data, const size_t _Sz, const size_t _Cap) noexcept : _Ptr(_Data), _Size(_Sz), _Capacity(_Cap) {} + _Fmt_buffer(_Ty* _Data, const size_t _Size, const size_t _Capacity) noexcept + : _Ptr_(_Data), _Size_(_Size), _Capacity_(_Capacity) {} void _Set(_Ty* _Buf_data, const size_t _Buf_capacity) noexcept { - _Ptr = _Buf_data; - _Capacity = _Buf_capacity; + _Ptr_ = _Buf_data; + _Capacity_ = _Buf_capacity; } virtual void _Grow(size_t _Capacity) = 0; public: - using value_type = _Ty; - using const_reference = const _Ty&; + using value_type = _Ty; _Fmt_buffer(const _Fmt_buffer&) = delete; void operator=(const _Fmt_buffer&) = delete; _NODISCARD _Ty* begin() noexcept { - return _Ptr; + return _Ptr_; } _NODISCARD _Ty* end() noexcept { - return _Ptr + _Size; + return _Ptr_ + _Size_; } - _NODISCARD size_t size() const noexcept { - return _Size; + _NODISCARD size_t _Size() const noexcept { + return _Size_; } - _NODISCARD size_t capacity() const noexcept { - return _Capacity; + _NODISCARD size_t _Capacity() const noexcept { + return _Capacity_; } - void clear() noexcept { - _Size = 0; + void _Clear() noexcept { + _Size_ = 0; } - void try_resize(const size_t _Count) { - try_reserve(_Count); - _Size = _Count <= _Capacity ? _Count : _Capacity; + void _Try_resize(const size_t _Count) { + _Try_reserve(_Count); + _Size_ = _Count <= _Capacity_ ? _Count : _Capacity_; } - void try_reserve(const size_t _New_capacity) { - if (_New_capacity > _Capacity) { + void _Try_reserve(const size_t _New_capacity) { + if (_New_capacity > _Capacity_) { _Grow(_New_capacity); } } void push_back(const _Ty _Value) { - try_reserve(_Size + 1); - _Ptr[_Size++] = _Value; + _Try_reserve(_Size_ + 1); + _Ptr_[_Size_++] = _Value; } }; +#pragma warning(pop) struct _Fmt_buffer_traits { explicit _Fmt_buffer_traits(ptrdiff_t) {} - _NODISCARD size_t count() const noexcept { + _NODISCARD size_t _Count() const noexcept { return 0; } - _NODISCARD size_t limit(const size_t _Size) noexcept { + _NODISCARD size_t _Limit(const size_t _Size) noexcept { return _Size; } }; class _Fmt_fixed_buffer_traits { private: - ptrdiff_t _Count = 0; - ptrdiff_t _Limit; + ptrdiff_t _Count_ = 0; + ptrdiff_t _Limit_; public: - explicit _Fmt_fixed_buffer_traits(const ptrdiff_t _Lim) noexcept : _Limit(_Lim) {} + explicit _Fmt_fixed_buffer_traits(const ptrdiff_t _Limit) noexcept : _Limit_(_Limit) {} - _NODISCARD size_t count() const noexcept { - return static_cast(_Count); + _NODISCARD size_t _Count() const noexcept { + return static_cast(_Count_); } - _NODISCARD size_t limit(const size_t _Size) noexcept { - size_t _Avail = static_cast(_Limit > _Count ? _Limit - _Count : 0); - _Count += _Size; + _NODISCARD size_t _Limit(const size_t _Size) noexcept { + size_t _Avail = static_cast(_Limit_ > _Count_ ? _Limit_ - _Count_ : 0); + _Count_ += _Size; return _Size < _Avail ? _Size : _Avail; } }; @@ -1595,51 +1598,50 @@ inline constexpr size_t _Fmt_buffer_size = 256; template class _Fmt_iterator_buffer final : public _Traits, public _Fmt_buffer<_Ty> { private: - _OutputIt _Out; + _OutputIt _Output; _Ty _Data[_Fmt_buffer_size]; -protected: void _Grow(size_t) final { - if (this->size() == _Fmt_buffer_size) { + if (this->_Size() == _Fmt_buffer_size) { _Flush(); } } void _Flush() { - auto _Size = this->size(); - this->clear(); - _Out = _STD _Copy_unchecked(_Data, _Data + this->limit(_Size), _STD move(_Out)); + auto _Size = this->_Size(); + this->_Clear(); + _Output = _STD _Copy_unchecked(_Data, _Data + this->_Limit(_Size), _STD move(_Output)); } public: - explicit _Fmt_iterator_buffer(_OutputIt _Output, ptrdiff_t _Size = _Fmt_buffer_size) - : _Traits(_Size), _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size), _Out(_STD move(_Output)) {} + explicit _Fmt_iterator_buffer(_OutputIt _Out, ptrdiff_t _Size = _Fmt_buffer_size) + : _Traits(_Size), _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size), _Output(_STD move(_Out)) {} ~_Fmt_iterator_buffer() { - if (this->size() != 0) { + if (this->_Size() != 0) { _Flush(); } } - _NODISCARD _OutputIt out() { + _NODISCARD _OutputIt _Out() { _Flush(); - return _STD move(_Out); + return _STD move(_Output); } - _NODISCARD ptrdiff_t count() const noexcept { - return static_cast(_Traits::count() + this->size()); + _NODISCARD ptrdiff_t _Count() const noexcept { + return static_cast(_Traits::_Count() + this->_Size()); } }; template class _Fmt_iterator_buffer<_Ty*, _Ty> final : public _Fmt_buffer<_Ty> { -protected: +private: void _Grow(size_t) final {} public: - explicit _Fmt_iterator_buffer(_Ty* _Out, ptrdiff_t = 0) : _Fmt_buffer<_Ty>(_Out, 0, ~size_t()) {} + explicit _Fmt_iterator_buffer(_Ty* _Out, ptrdiff_t = 0) : _Fmt_buffer<_Ty>(_Out, 0, ~size_t{}) {} - _NODISCARD _Ty* out() noexcept { + _NODISCARD _Ty* _Out() noexcept { return this->end(); } }; @@ -1657,21 +1659,20 @@ private: using _STD back_insert_iterator<_Container>::container; }; -protected: void _Grow(size_t _Capacity) final { _Cont.resize(_Capacity); - this->_Set(&_Cont[0], _Capacity); + this->_Set(_RANGES data(_Cont), _Capacity); } public: - explicit _Fmt_iterator_buffer(_Container& _C) - : _Fmt_buffer(_C.size()), _Cont(_C) {} + explicit _Fmt_iterator_buffer(_Container& _Cont_) + : _Fmt_buffer(_Cont_.size()), _Cont(_Cont_) {} explicit _Fmt_iterator_buffer(_STD back_insert_iterator<_Container> _Out, ptrdiff_t = 0) - : _Fmt_iterator_buffer(*_Accessor(_STD move(_Out)).container) {} + : _Fmt_iterator_buffer(*_Accessor{_Out}.container) {} - _NODISCARD auto out() noexcept { - return _STD back_inserter(_Cont); + _NODISCARD auto _Out() noexcept { + return back_insert_iterator{_Cont}; } }; @@ -1679,22 +1680,21 @@ template class _Fmt_counting_buffer final : public _Fmt_buffer<_Ty> { private: _Ty _Data[_Fmt_buffer_size]; - size_t _Count = 0; + size_t _Count_ = 0; -protected: void _Grow(size_t) final { - if (this->size() != _Fmt_buffer_size) { + if (this->_Size() != _Fmt_buffer_size) { return; } - _Count += this->size(); - this->clear(); + _Count_ += this->_Size(); + this->_Clear(); } public: _Fmt_counting_buffer() : _Fmt_buffer<_Ty>(_Data, 0, _Fmt_buffer_size) {} - _NODISCARD size_t count() const noexcept { - return _Count + this->size(); + _NODISCARD size_t _Count() const noexcept { + return _Count_ + this->_Size(); } }; @@ -2820,56 +2820,56 @@ _OutputIt vformat_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const string_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, char> _Buf(_STD move(_Out)); - _STD vformat_to(_Fmt_it(_Buf), _Fmt, _STD make_format_args(_Args...)); - return _Buf.out(); + _STD vformat_to(_Fmt_it{_Buf}, _Fmt, _STD make_format_args(_Args...)); + return _Buf._Out(); } template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const wstring_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, wchar_t> _Buf(_STD move(_Out)); - _STD vformat_to(_Fmt_wit(_Buf), _Fmt, _STD make_wformat_args(_Args...)); - return _Buf.out(); + _STD vformat_to(_Fmt_wit{_Buf}, _Fmt, _STD make_wformat_args(_Args...)); + return _Buf._Out(); } template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, char> _Buf(_STD move(_Out)); - _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, _STD make_format_args(_Args...)); - return _Buf.out(); + _STD vformat_to(_Fmt_it{_Buf}, _Loc, _Fmt, _STD make_format_args(_Args...)); + return _Buf._Out(); } template _OutputIt, class... _Types> _OutputIt format_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, wchar_t> _Buf(_STD move(_Out)); - _STD vformat_to(_Fmt_wit(_Buf), _Loc, _Fmt, _STD make_wformat_args(_Args...)); - return _Buf.out(); + _STD vformat_to(_Fmt_wit{_Buf}, _Loc, _Fmt, _STD make_wformat_args(_Args...)); + return _Buf._Out(); } _NODISCARD inline string vformat(const string_view _Fmt, const format_args _Args) { string _Str; - _Fmt_iterator_buffer, char> _Buf(_STD back_inserter(_Str)); - _STD vformat_to(_Fmt_it(_Buf), _Fmt, _Args); + _Fmt_iterator_buffer, char> _Buf(back_insert_iterator{_Str}); + _STD vformat_to(_Fmt_it{_Buf}, _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; - _Fmt_iterator_buffer, wchar_t> _Buf(_STD back_inserter(_Str)); - _STD vformat_to(_Fmt_wit(_Buf), _Fmt, _Args); + _Fmt_iterator_buffer, wchar_t> _Buf(back_insert_iterator{_Str}); + _STD vformat_to(_Fmt_wit{_Buf}, _Fmt, _Args); return _Str; } _NODISCARD inline string vformat(const locale& _Loc, const string_view _Fmt, const format_args _Args) { string _Str; - _Fmt_iterator_buffer, char> _Buf(_STD back_inserter(_Str)); - _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, _Args); + _Fmt_iterator_buffer, char> _Buf(back_insert_iterator{_Str}); + _STD vformat_to(_Fmt_it{_Buf}, _Loc, _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const locale& _Loc, const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; - _Fmt_iterator_buffer, wchar_t> _Buf(_STD back_inserter(_Str)); - _STD vformat_to(_Fmt_wit(_Buf), _Loc, _Fmt, _Args); + _Fmt_iterator_buffer, wchar_t> _Buf(back_insert_iterator{_Str}); + _STD vformat_to(_Fmt_wit{_Buf}, _Loc, _Fmt, _Args); return _Str; } @@ -2903,60 +2903,60 @@ template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n( _OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const string_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, char, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); - _STD vformat_to(_Fmt_it(_Buf), _Fmt, _STD make_format_args(_Args...)); - return {.out = _Buf.out(), .size = _Buf.count()}; + _STD vformat_to(_Fmt_it{_Buf}, _Fmt, _STD make_format_args(_Args...)); + return {.out = _Buf._Out(), .size = _Buf._Count()}; } template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n( _OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const wstring_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, wchar_t, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); - _STD vformat_to(_Fmt_wit(_Buf), _Fmt, _STD make_wformat_args(_Args...)); - return {.out = _Buf.out(), .size = _Buf.count()}; + _STD vformat_to(_Fmt_wit{_Buf}, _Fmt, _STD make_wformat_args(_Args...)); + return {.out = _Buf._Out(), .size = _Buf._Count()}; } template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n(_OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, char, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); - _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, _STD make_format_args(_Args...)); - return {.out = _Buf.out(), .size = _Buf.count()}; + _STD vformat_to(_Fmt_it{_Buf}, _Loc, _Fmt, _STD make_format_args(_Args...)); + return {.out = _Buf._Out(), .size = _Buf._Count()}; } template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n(_OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, wchar_t, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); - _STD vformat_to(_Fmt_wit(_Buf), _Loc, _Fmt, _STD make_wformat_args(_Args...)); - return {.out = _Buf.out(), .size = _Buf.count()}; + _STD vformat_to(_Fmt_wit{_Buf}, _Loc, _Fmt, _STD make_wformat_args(_Args...)); + return {.out = _Buf._Out(), .size = _Buf._Count()}; } template _NODISCARD size_t formatted_size(const string_view _Fmt, const _Types&... _Args) { _Fmt_counting_buffer _Buf; - _STD vformat_to(_Fmt_it(_Buf), _Fmt, _STD make_format_args(_Args...)); - return _Buf.count(); + _STD vformat_to(_Fmt_it{_Buf}, _Fmt, _STD make_format_args(_Args...)); + return _Buf._Count(); } template _NODISCARD size_t formatted_size(const wstring_view _Fmt, const _Types&... _Args) { _Fmt_counting_buffer _Buf; - _STD vformat_to(_Fmt_wit(_Buf), _Fmt, _STD make_wformat_args(_Args...)); - return _Buf.count(); + _STD vformat_to(_Fmt_wit{_Buf}, _Fmt, _STD make_wformat_args(_Args...)); + return _Buf._Count(); } template _NODISCARD size_t formatted_size(const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { _Fmt_counting_buffer _Buf; - _STD vformat_to(_Fmt_it(_Buf), _Loc, _Fmt, _STD make_format_args(_Args...)); - return _Buf.count(); + _STD vformat_to(_Fmt_it{_Buf}, _Loc, _Fmt, _STD make_format_args(_Args...)); + return _Buf._Count(); } template _NODISCARD size_t formatted_size(const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { _Fmt_counting_buffer _Buf; - _STD vformat_to(_Fmt_wit(_Buf), _Loc, _Fmt, _STD make_wformat_args(_Args...)); - return _Buf.count(); + _STD vformat_to(_Fmt_wit{_Buf}, _Loc, _Fmt, _STD make_wformat_args(_Args...)); + return _Buf._Count(); } _STD_END From 82556b836c4df94fa599f474a4544f050413b5d2 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 19 Apr 2021 06:57:07 -0700 Subject: [PATCH 6/9] Remove unnecessary _STD, add explicit --- stl/inc/format | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 29d0f37ae16..c2f17949497 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1647,16 +1647,16 @@ public: }; template -class _Fmt_iterator_buffer<_STD back_insert_iterator<_Container>, - enable_if_t<_STD contiguous_iterator, typename _Container::value_type>> +class _Fmt_iterator_buffer, + enable_if_t, typename _Container::value_type>> final : public _Fmt_buffer { private: _Container& _Cont; - struct _Accessor : _STD back_insert_iterator<_Container> { - _Accessor(_STD back_insert_iterator<_Container> _Iter) : back_insert_iterator<_Container>(_Iter) {} + struct _Accessor : back_insert_iterator<_Container> { + explicit _Accessor(back_insert_iterator<_Container> _Iter) : back_insert_iterator<_Container>(_Iter) {} - using _STD back_insert_iterator<_Container>::container; + using back_insert_iterator<_Container>::container; }; void _Grow(size_t _Capacity) final { @@ -1668,7 +1668,7 @@ public: explicit _Fmt_iterator_buffer(_Container& _Cont_) : _Fmt_buffer(_Cont_.size()), _Cont(_Cont_) {} - explicit _Fmt_iterator_buffer(_STD back_insert_iterator<_Container> _Out, ptrdiff_t = 0) + explicit _Fmt_iterator_buffer(back_insert_iterator<_Container> _Out, ptrdiff_t = 0) : _Fmt_iterator_buffer(*_Accessor{_Out}.container) {} _NODISCARD auto _Out() noexcept { From 25f796a0d8a4c25477e49e5e0f9ea8011c1c574a Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 19 Apr 2021 10:12:12 -0700 Subject: [PATCH 7/9] Conceptualize _Fmt_iterator_buffer --- stl/inc/format | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index c2f17949497..01c17948bbd 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1646,10 +1646,15 @@ public: } }; +// clang-format off template -class _Fmt_iterator_buffer, - enable_if_t, typename _Container::value_type>> - final : public _Fmt_buffer { + requires _RANGES contiguous_range<_Container> && _RANGES sized_range<_Container> + && requires(_Container& _Cont, const _RANGES range_value_t<_Container>& _Val) { + _Cont.push_back(_Val); + } +// clang-format on +class _Fmt_iterator_buffer, _RANGES range_value_t<_Container>> final + : public _Fmt_buffer<_RANGES range_value_t<_Container>> { private: _Container& _Cont; @@ -1666,7 +1671,7 @@ private: public: explicit _Fmt_iterator_buffer(_Container& _Cont_) - : _Fmt_buffer(_Cont_.size()), _Cont(_Cont_) {} + : _Fmt_buffer<_RANGES range_value_t<_Container>>(_RANGES size(_Cont_)), _Cont(_Cont_) {} explicit _Fmt_iterator_buffer(back_insert_iterator<_Container> _Out, ptrdiff_t = 0) : _Fmt_iterator_buffer(*_Accessor{_Out}.container) {} From 2f2dda02c3eb5bfa84138380e8592300d8c83515 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 19 Apr 2021 10:27:29 -0700 Subject: [PATCH 8/9] Replace warning suppression with a defaulted dtor --- stl/inc/format | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 01c17948bbd..69b79b47c02 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1496,8 +1496,6 @@ public: } }; -#pragma warning(push) -#pragma warning(disable : 4265) // non-virtual destructor in base class template class _Fmt_buffer { private: @@ -1508,6 +1506,8 @@ private: protected: explicit _Fmt_buffer(const size_t _Size) noexcept : _Size_(_Size), _Capacity_(_Size) {} + ~_Fmt_buffer() = default; + _Fmt_buffer(_Ty* _Data, const size_t _Size, const size_t _Capacity) noexcept : _Ptr_(_Data), _Size_(_Size), _Capacity_(_Capacity) {} @@ -1560,7 +1560,6 @@ public: _Ptr_[_Size_++] = _Value; } }; -#pragma warning(pop) struct _Fmt_buffer_traits { explicit _Fmt_buffer_traits(ptrdiff_t) {} From 94ac4e2773b94b8c0d4e046a484ece07b41abba6 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 19 Apr 2021 11:04:50 -0700 Subject: [PATCH 9/9] Simplify make_testing_format_args --- .../std/tests/P0645R10_text_formatting_formatting/test.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp index 78fdf60957f..3bddcd7ad48 100644 --- a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp @@ -48,11 +48,7 @@ struct choose_literal { template auto make_testing_format_args(Args&&... vals) { using context = basic_format_context>, charT>; - if constexpr (is_same_v) { - return make_wformat_args(forward(vals)...); - } else { - return make_format_args(forward(vals)...); - } + return make_format_args(forward(vals)...); } template