On Tue, 20 May 2025 at 10:08, Jonathan Wakely <jwakely....@gmail.com> wrote: > > On Tue, 20 May 2025 at 09:10, Tomasz Kaminski <tkami...@redhat.com> wrote: > > > > > > > > On Mon, May 19, 2025 at 11:28 PM Nathan Myers <n...@cantrip.org> wrote: > > In the title, we usually put link to bugzilla PR119741 in your case, not > > the paper. > > Then link the paper in commit descritpion. > > Right. When there's no bugzilla I'll sometimes put the paper number in > parens, e.g. in https://gcc.gnu.org/g:91f4550e1700 which has this > summary: > libstdc++: Move std::monostate to <utility> for C++26 (P0472R2) > > But the paper number should not be in square brackets, that should be > reserved for a bugzilla PR number if there is one (and for this > feature, we do have a bugzilla PR). > > > > > >> Add constructors to stringbuf, stringstream, istringstream, > >> and ostringstream, and a matching overload of str(sv) in each, > >> that take anything convertible to a string_view where the > >> existing functions take a string. > > > > > > After you put bugzilla number, git gcc-verify will suggest you to add > > following node: > > <tab>PR libstdc++/119741 > > > >> > >> > >> libstdc++-v3/ChangeLog: > >> > >> P2495R3 stringstream to init from string_view-ish > > > > We usually put only the change files here. Did git gcc-verify accepted it. > >> > >> * include/std/sstream: full implementation, really just > >> decls, requires clause and plumbing. > >> * include/std/bits/version.def, .h: new preprocessor symbol > >> __cpp_lib_sstream_from_string_view. > >> * testsuite/27_io/basic_stringbuf/cons/char/3.cc: New tests. > >> * testsuite/27_io/basic_istringstream/cons/char/2.cc: New tests. > >> * testsuite/27_io/basic_ostringstream/cons/char/4.cc: New tests. > >> * testsuite/27_io/basic_stringstream/cons/char/2.cc: New tests. > >> --- > >> libstdc++-v3/ChangeLog | 11 + > >> libstdc++-v3/include/bits/version.def | 11 +- > >> libstdc++-v3/include/bits/version.h | 10 + > >> libstdc++-v3/include/std/sstream | 181 +++++++++++++-- > >> .../27_io/basic_istringstream/cons/char/2.cc | 193 ++++++++++++++++ > >> .../27_io/basic_ostringstream/cons/char/4.cc | 193 ++++++++++++++++ > >> .../27_io/basic_stringbuf/cons/char/3.cc | 216 ++++++++++++++++++ > >> .../27_io/basic_stringstream/cons/char/2.cc | 194 ++++++++++++++++ > >> 8 files changed, 990 insertions(+), 19 deletions(-) > >> create mode 100644 > >> libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/2.cc > >> create mode 100644 > >> libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/4.cc > >> create mode 100644 > >> libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/3.cc > >> create mode 100644 > >> libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/2.cc > >> > >> diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog > >> index b45f8c2c7a5..ac0ff4a386f 100644 > >> --- a/libstdc++-v3/ChangeLog > >> +++ b/libstdc++-v3/ChangeLog > >> @@ -41,6 +41,17 @@ > >> PR libstdc++/119246 > >> * include/std/format: Updated check for _GLIBCXX_FORMAT_F128. > >> > >> +2025-05-14 Nathan Myers <nmy...@redhat.com> > >> + P2495R3 stringstream to init from string_view-ish > >> + * include/std/sstream: full implementation, really just > >> + decls, requires clause and plumbing. > >> + * include/std/bits/version.def, .h: new preprocessor symbol > >> + __cpp_lib_sstream_from_string_view. > >> + * testsuite/27_io/basic_stringbuf/cons/char/3.cc: New tests. > >> + * testsuite/27_io/basic_istringstream/cons/char/2.cc: New tests. > >> + * testsuite/27_io/basic_ostringstream/cons/char/4.cc: New tests. > >> + * testsuite/27_io/basic_stringstream/cons/char/2.cc: New tests. > >> + > > > > Changelogs are now automatically generated from commit messages, so you do > > not > > need to edit this file. > >> > >> 2025-05-14 Tomasz Kamiński <tkami...@redhat.com> > >> > >> PR libstdc++/119125 > >> diff --git a/libstdc++-v3/include/bits/version.def > >> b/libstdc++-v3/include/bits/version.def > >> index 6ca148f0488..567c56b4117 100644 > >> --- a/libstdc++-v3/include/bits/version.def > >> +++ b/libstdc++-v3/include/bits/version.def > >> @@ -649,7 +649,7 @@ ftms = { > >> }; > >> values = { > >> v = 1; > >> - /* For when there's no gthread. */ > >> + // For when there is no gthread. > >> cxxmin = 17; > >> hosted = yes; > >> gthread = no; > >> @@ -1961,6 +1961,15 @@ ftms = { > >> }; > >> }; > >> > >> +ftms = { > >> + name = sstream_from_string_view; > >> + values = { > >> + v = 202302; > >> + cxxmin = 26; > >> + hosted = yes; > >> + }; > >> +}; > >> + > >> // Standard test specifications. > >> stds[97] = ">= 199711L"; > >> stds[03] = ">= 199711L"; > >> diff --git a/libstdc++-v3/include/bits/version.h > >> b/libstdc++-v3/include/bits/version.h > >> index 48a090c14a3..5d1beb83a25 100644 > >> --- a/libstdc++-v3/include/bits/version.h > >> +++ b/libstdc++-v3/include/bits/version.h > >> @@ -2193,4 +2193,14 @@ > >> #endif /* !defined(__cpp_lib_modules) && defined(__glibcxx_want_modules) > >> */ > >> #undef __glibcxx_want_modules > >> > >> +#if !defined(__cpp_lib_sstream_from_string_view) > >> +# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED > >> +# define __glibcxx_sstream_from_string_view 202302L > >> +# if defined(__glibcxx_want_all) || > >> defined(__glibcxx_want_sstream_from_string_view) > >> +# define __cpp_lib_sstream_from_string_view 202302L > >> +# endif > >> +# endif > >> +#endif /* !defined(__cpp_lib_sstream_from_string_view) && > >> defined(__glibcxx_want_sstream_from_string_view) */ > >> +#undef __glibcxx_want_sstream_from_string_view > >> + > >> #undef __glibcxx_want_all > >> diff --git a/libstdc++-v3/include/std/sstream > >> b/libstdc++-v3/include/std/sstream > >> index ad0c16a91e8..9b2b0eb53fc 100644 > >> --- a/libstdc++-v3/include/std/sstream > >> +++ b/libstdc++-v3/include/std/sstream > >> @@ -38,9 +38,14 @@ > >> #endif > >> > >> #include <bits/requires_hosted.h> // iostream > >> +#include <bits/version.h> > >> > >> #include <istream> > >> #include <ostream> > >> +#ifdef __cpp_lib_sstream_from_string_view > >> +# include <type_traits> // is_convertible_v > >> +#endif > >> + > >> #include <bits/alloc_traits.h> // allocator_traits, __allocator_like > >> > >> #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI > >> @@ -52,8 +57,6 @@ > >> # define _GLIBCXX_SSTREAM_ALWAYS_INLINE [[__gnu__::__always_inline__]] > >> #endif > >> > >> - > >> - > >> namespace std _GLIBCXX_VISIBILITY(default) > >> { > >> _GLIBCXX_BEGIN_NAMESPACE_VERSION > >> @@ -159,6 +162,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, > >> 0); } > >> > >> #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI > >> + // P0408 Efficient access to basic_stringbuf buffer > >> explicit > >> basic_stringbuf(const allocator_type& __a) > >> : basic_stringbuf(ios_base::in | std::ios_base::out, __a) > >> @@ -197,7 +201,35 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> | ios_base::out) > >> : basic_stringbuf(__s, __mode, allocator_type{}) > >> { } > >> +#endif > >> + > >> +#ifdef __cpp_lib_sstream_from_string_view > >> + template<typename _Tp> > >> + explicit > >> + basic_stringbuf(const _Tp& __t, ios_base::openmode __mode = > >> ios_base::in | ios_base::out) > >> + requires (is_convertible_v<const _Tp&, basic_string_view<_CharT, > >> _Traits>>) > >> + : basic_stringbuf(__t, __mode, allocator_type{}) > >> + { } > >> + > >> + template<typename _Tp> > >> + basic_stringbuf(const _Tp& __t, const allocator_type& __a) > >> + requires (is_convertible_v<const _Tp&, basic_string_view<_CharT, > >> _Traits>>) > >> + : basic_stringbuf(__t, ios_base::in | ios_base::out, __a) > >> + { } > >> > >> + template<typename _Tp> > >> + basic_stringbuf(const _Tp& __t, ios_base::openmode __mode, const > >> allocator_type& __a) > >> + requires (is_convertible_v<const _Tp&, basic_string_view<_CharT, > >> _Traits>>) > >> + : basic_stringbuf(__mode, __a) > > > > Any reason for not initializing _M_string(t, __a) directly here, string has > > string_view constructor. > > More importantly, it has a "convertible to string_view" constructor, > which matches the constraint on _Tp here. So it does look like we can > just construct _M_string directly from __t and __a. > > >> > >> + { > >> + basic_string_view<_CharT, _Traits> __sv{__t}; > >> + _M_string = __sv; > >> + _M_stringbuf_init(__mode); > >> + } > >> +#endif // C++26 > >> + > >> +#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI > >> + // P0408 Efficient access to basic_stringbuf buffer > >> basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a) > >> : basic_stringbuf(std::move(__rhs), __a, __xfer_bufptrs(__rhs, > >> this)) > >> { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, > >> 0); } > >> @@ -262,6 +294,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> #if __cplusplus > 201703L > >> #if _GLIBCXX_USE_CXX11_ABI > >> #if __cpp_concepts > >> + // P0407 Allocator-aware basic_streambuf > >> template<__allocator_like _SAlloc> > >> _GLIBCXX_NODISCARD > >> basic_string<_CharT, _Traits, _SAlloc> > >> @@ -317,6 +350,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> > >> #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI > >> #if __cpp_concepts > >> + // P0407 Allocator-aware basic_streambuf > >> template<__allocator_like _SAlloc> > >> requires (!is_same_v<_SAlloc, _Alloc>) > >> void > >> @@ -335,6 +369,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> } > >> #endif > >> > >> +#ifdef __cpp_lib_sstream_from_string_view > >> + template <typename _Tp> > >> + void > >> + str(const _Tp& __t) > >> + requires (is_convertible_v<const _Tp&, basic_string_view<_CharT, > >> _Traits>>) > >> + { > >> + basic_string_view<_CharT, _Traits> __sv{__t}; > >> + _M_string = __sv; > >> + _M_stringbuf_init(_M_mode); > >> + } > >> +#endif // C++26 > >> + > >> protected: > >> // Common initialization code goes here. > >> void > >> @@ -521,6 +567,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> { } > >> > >> #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI > >> + // P0408 Efficient access to basic_stringbuf buffer > >> + > >> // The move constructor initializes an __xfer_bufptrs temporary then > >> // delegates to this constructor to performs moves during its > >> lifetime. > >> basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a, > >> @@ -584,7 +632,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> */ > >> basic_istringstream() > >> : __istream_type(), _M_stringbuf(ios_base::in) > >> - { this->init(&_M_stringbuf); } > >> + { this->init(std::__addressof(_M_stringbuf)); } > >> > >> /** > >> * @brief Starts with an empty string buffer. > >> @@ -601,7 +649,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> explicit > >> basic_istringstream(ios_base::openmode __mode) > >> : __istream_type(), _M_stringbuf(__mode | ios_base::in) > >> - { this->init(&_M_stringbuf); } > >> + { this->init(std::__addressof(_M_stringbuf)); } > >> > >> /** > >> * @brief Starts with an existing string buffer. > >> @@ -620,7 +668,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> basic_istringstream(const __string_type& __str, > >> ios_base::openmode __mode = ios_base::in) > >> : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) > >> - { this->init(&_M_stringbuf); } > >> + { this->init(std::__addressof(_M_stringbuf)); } > >> > >> /** > >> * @brief The destructor does nothing. > >> @@ -637,9 +685,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> basic_istringstream(basic_istringstream&& __rhs) > >> : __istream_type(std::move(__rhs)), > >> _M_stringbuf(std::move(__rhs._M_stringbuf)) > >> - { __istream_type::set_rdbuf(&_M_stringbuf); } > >> + { __istream_type::set_rdbuf(std::__addressof(_M_stringbuf)); } > >> > >> #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI > >> + // P0408 Efficient access to basic_stringbuf buffer > >> basic_istringstream(ios_base::openmode __mode, const > >> allocator_type& __a) > >> : __istream_type(), _M_stringbuf(__mode | ios_base::in, __a) > >> { this->init(std::__addressof(_M_stringbuf)); } > >> @@ -667,10 +716,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 > >> explicit > >> basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& > >> __str, > >> ios_base::openmode __mode = ios_base::in) > >> +#ifdef __cpp_lib_sstream_from_string_view > >> + requires (!is_same_v<_SAlloc, allocator_type>) > >> +#endif // C++26 > > > > Standard have same constraint of ostringstream > > (https://eel.is/c++draft/string.streams#ostringstream.cons-6): > > Constraints: is_same_v<SAlloc,Allocator> is false. > > Do we miss some library issue? > > P2495R3 adds this to basic_istringstream with this note: > > [DRAFTING NOTE: Drive-by fix, this adds a missing constraint present > in stringstream and ostringstream.] > > The constraints were added elsewhere by P0408 so I missed adding those > constraints in https://gcc.gnu.org/g:95cb0fc8c51841 > Nathan, could you please add that same !is_same_v constraint to the > basic_stringbuf, basic_ostringstream and basic_stringstream > constructors as part of this patch?
Do those constrains actually do anything, except slow down compilation? We have: explicit basic_stringbuf( const basic_string<charT, traits, Allocator>& s, ios_base::openmode which = ios_base::in | ios_base::out); And: template<class SAlloc> explicit basic_stringbuf( const basic_string<charT, traits, SAlloc>& s, ios_base::openmode which = ios_base::in | ios_base::out); Constraints: is_same_v<SAlloc, Allocator> is false. If Salloc is Allocator then the first one is a better match anyway, so what's the constraint for?