On Thu, 5 Jun 2025 at 07:39, Jonathan Wakely <jwakely....@gmail.com> wrote:
>
> There was no need to revert this, it wasn't breaking bootstrap, only causing 
> a handful of test failures.
>
> The new wchar_t tests just need the same { dg-do run { target c++26 } } 
> directives as the char tests.
>
> Dejagnu only looks for directives in the main file, not in included files.


Pre-approved to re-push it with the dg-do lines added to the wchar_t
tests, assuming that a 'make check' (with the default options) works.


>
>
>
> On Thu, 5 Jun 2025, 04:23 Nathan Myers, <n...@cantrip.org> wrote:
>>
>> On 6/4/25 20:30, H.J. Lu wrote:
>> > On Wed, Jun 4, 2025 at 8:02 PM Jonathan Wakely <jwak...@redhat.com> wrote:
>> >>
>> >> On Thu, 29 May 2025 at 20:30, Nathan Myers <n...@cantrip.org> wrote:
>> >>>
>> >>> Change in V4:
>> >>>   * Rename tests to string_view.cc
>> >>>   * Adapt tests to cons/wchar_t directories
>> >>>   * Define symbol __cpp_lib_sstream_from_string_view as 202406
>> >>>   * Define symbol __glibcxx_want_sstream_from_string_view before 
>> >>> version.h
>> >>>   * Include version.h after other includes
>> >>>   * No include type_traits
>> >>>   * Drive-by comment moved to commit message
>> >>>   * Each `explicit` on its own line
>> >>>   * Run tests even when using old COW string
>> >>>
>> >>> Change in V3:
>> >>>   * Comment that p2495 specifies a drive-by constraint omitted as 
>> >>> redundant
>> >>>   * Adjust whitespace to fit in 80 columns
>> >>>
>> >>> Change in V2:
>> >>>   * Apply all review comments
>> >>>   * Remove redundant drive-by "requires" on ctor from string allocator 
>> >>> arg
>> >>>   * Check allocators are plumbed through
>> >>
>> >> Looks great now, thanks for iterating on it.
>> >>
>> >> Please push to trunk (you'll probably need to rebase first, which will
>> >> have a merge conflict in bits/version.h but just regenerating it again
>> >> will resolve that).
>> >
>> > On Fedora 42/x86-64, I got
>> >
>> > FAIL: 27_io/basic_istringstream/cons/wchar_t/string_view.cc
>> > -std=gnu++17 (test for excess errors)
>> > Excess errors:
>> > /export/gnu/import/git/gitlab/x86-gcc-test/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/../char/string_view.cc:39:
>> > error: 'requires' only available with '-std=c++20' or '-fconcepts'
>> > [-Wtemplate-body]
>> > /export/gnu/import/git/gitlab/x86-gcc-test/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/../char/string_view.cc:39:
>> > error: expected ',' before '{' token [-Wtemplate-body]
>> > /export/gnu/import/git/gitlab/x86-gcc-test/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/../char/string_view.cc:39:
>> > warning: 'static_assert' with non-string message only available with
>> > '-std=c++2c' or '-std=gnu++2c' [-Wc++26-extensions]
>> > /export/gnu/import/git/gitlab/x86-gcc-test/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/../char/string_view.cc:39:
>> > error: expected primary-expression before '{' token [-Wtemplate-body]
>> > /export/gnu/import/git/gitlab/x86-gcc-test/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/../char/string_view.cc:39:
>> > error: expected ')' before '{' token [-Wtemplate-body]
>> > /export/gnu/import/git/gitlab/x86-gcc-test/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/../char/string_view.cc:41:
>> > error: 'requires' only available with '-std=c++20' or '-fconcepts'
>> > [-Wtemplate-body]
>> > /export/gnu/import/git/gitlab/x86-gcc-test/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/../char/string_view.cc:41:
>> > error: expected ',' before '{' token [-Wtemplate-body]
>>
>> Reverted a31e76a2643.
>>
>> >>> -- >8 --
>> >>>
>> >>> Implement PR libstdc++/119741 (P2495R3).
>> >>> 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 in places where the existing ctors and function take a 
>> >>> string.
>> >>> Note this change omits the constraint applied to the istringstream 
>> >>> constructor
>> >>> from string cited as a "drive-by" in P2495R3, as we have determined it is
>> >>> redundant.
>> >>>
>> >>> libstdc++-v3/ChangeLog:
>> >>>
>> >>>          PR libstdc++/119741
>> >>>          * include/std/sstream: full implementation, really just
>> >>>          decls, requires clause and plumbing.
>> >>>          * include/bits/version.def, include/bits/version.h:
>> >>>          new preprocessor symbol
>> >>>          __cpp_lib_sstream_from_string_view.
>> >>>          * testsuite/27_io/basic_stringbuf/cons/char/string_view.cc:
>> >>>          New tests.
>> >>>          * testsuite/27_io/basic_istringstream/cons/char/string_view.cc:
>> >>>          New tests.
>> >>>          * testsuite/27_io/basic_ostringstream/cons/char/string_view.cc:
>> >>>          New tests.
>> >>>          * testsuite/27_io/basic_stringstream/cons/char/string_view.cc:
>> >>>          New tests.
>> >>>          * testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc:
>> >>>          New tests.
>> >>>          * 
>> >>> testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc:
>> >>>          New tests.
>> >>>          * 
>> >>> testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc:
>> >>>          New tests.
>> >>>          * 
>> >>> testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc:
>> >>>          New tests.
>> >>> ---
>> >>>   libstdc++-v3/include/bits/version.def         |  11 +-
>> >>>   libstdc++-v3/include/bits/version.h           |  10 +
>> >>>   libstdc++-v3/include/std/sstream              | 198 +++++++++++++++--
>> >>>   .../cons/char/string_view.cc                  | 195 +++++++++++++++++
>> >>>   .../cons/wchar_t/string_view.cc               |   3 +
>> >>>   .../cons/char/string_view.cc                  | 194 +++++++++++++++++
>> >>>   .../cons/wchar_t/string_view.cc               |   3 +
>> >>>   .../basic_stringbuf/cons/char/string_view.cc  | 205 ++++++++++++++++++
>> >>>   .../cons/wchar_t/string_view.cc               |   3 +
>> >>>   .../cons/char/string_view.cc                  | 204 +++++++++++++++++
>> >>>   .../cons/wchar_t/string_view.cc               |   3 +
>> >>>   11 files changed, 1010 insertions(+), 19 deletions(-)
>> >>>   create mode 100644 
>> >>> libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc
>> >>>   create mode 100644 
>> >>> libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc
>> >>>   create mode 100644 
>> >>> libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc
>> >>>   create mode 100644 
>> >>> libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc
>> >>>   create mode 100644 
>> >>> libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc
>> >>>   create mode 100644 
>> >>> libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc
>> >>>   create mode 100644 
>> >>> libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc
>> >>>   create mode 100644 
>> >>> libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc
>> >>>
>> >>> diff --git a/libstdc++-v3/include/bits/version.def 
>> >>> b/libstdc++-v3/include/bits/version.def
>> >>> index 282667eabda..53bf72d95c2 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;
>> >>> @@ -1945,6 +1945,15 @@ ftms = {
>> >>>     };
>> >>>   };
>> >>>
>> >>> +ftms = {
>> >>> +  name = sstream_from_string_view;
>> >>> +  values = {
>> >>> +    v = 202306;
>> >>> +    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 bb7c0479c72..0b932183e5b 100644
>> >>> --- a/libstdc++-v3/include/bits/version.h
>> >>> +++ b/libstdc++-v3/include/bits/version.h
>> >>> @@ -2174,4 +2174,14 @@
>> >>>   #endif /* !defined(__cpp_lib_modules) && 
>> >>> defined(__glibcxx_want_modules) */
>> >>>   #undef __glibcxx_want_modules
>> >>>
>> >>> +#if !defined(__cpp_lib_sstream_from_string_view)
>> >>> +# if (__cplusplus >=  202306L) && _GLIBCXX_HOSTED
>> >>> +#  define __glibcxx_sstream_from_string_view 202306L
>> >>> +#  if defined(__glibcxx_want_all) || 
>> >>> defined(__glibcxx_want_sstream_from_string_view)
>> >>> +#   define __cpp_lib_sstream_from_string_view 202306L
>> >>> +#  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..edef599bd6f 100644
>> >>> --- a/libstdc++-v3/include/std/sstream
>> >>> +++ b/libstdc++-v3/include/std/sstream
>> >>> @@ -41,8 +41,12 @@
>> >>>
>> >>>   #include <istream>
>> >>>   #include <ostream>
>> >>> +
>> >>>   #include <bits/alloc_traits.h> // allocator_traits, __allocator_like
>> >>>
>> >>> +#define __glibcxx_want_sstream_from_string_view
>> >>> +#include <bits/version.h>
>> >>> +
>> >>>   #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
>> >>>   # define _GLIBCXX_LVAL_REF_QUAL &
>> >>>   # define _GLIBCXX_SSTREAM_ALWAYS_INLINE
>> >>> @@ -52,8 +56,6 @@
>> >>>   # define _GLIBCXX_SSTREAM_ALWAYS_INLINE [[__gnu__::__always_inline__]]
>> >>>   #endif
>> >>>
>> >>> -
>> >>> -
>> >>>   namespace std _GLIBCXX_VISIBILITY(default)
>> >>>   {
>> >>>   _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> >>> @@ -159,6 +161,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 +200,36 @@ _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>>)
>> >>> +       : _M_string(__t, __a)
>> >>> +       { _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,19 @@ _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 +568,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 +633,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 +650,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 +669,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 +686,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)); }
>> >>> @@ -671,6 +721,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>          { }
>> >>>   #endif // C++20
>> >>>
>> >>> +#ifdef __cpp_lib_sstream_from_string_view
>> >>> +      template <typename _Tp>
>> >>> +       explicit
>> >>> +       basic_istringstream(const _Tp& __t,
>> >>> +           ios_base::openmode __mode = ios_base::in)
>> >>> +         requires (is_convertible_v<const _Tp&,
>> >>> +                   basic_string_view<_CharT, _Traits>>)
>> >>> +       : basic_istringstream(__t, __mode, allocator_type{})
>> >>> +       { }
>> >>> +
>> >>> +      template <typename _Tp>
>> >>> +       basic_istringstream(const _Tp& __t, const allocator_type& __a)
>> >>> +         requires (is_convertible_v<const _Tp&,
>> >>> +                   basic_string_view<_CharT, _Traits>>)
>> >>> +       : basic_istringstream(__t, ios_base::in, __a)
>> >>> +       { }
>> >>> +
>> >>> +      template <typename _Tp>
>> >>> +       basic_istringstream(const _Tp& __t, ios_base::openmode __mode,
>> >>> +           const allocator_type& __a)
>> >>> +         requires (is_convertible_v<const _Tp&,
>> >>> +                   basic_string_view<_CharT, _Traits>>)
>> >>> +         : __istream_type(), _M_stringbuf(__t, __mode | ios_base::in, 
>> >>> __a)
>> >>> +       { this->init(std::__addressof(_M_stringbuf)); }
>> >>> +#endif // C++26
>> >>> +
>> >>>         // 27.8.3.2 Assign and swap:
>> >>>
>> >>>         basic_istringstream&
>> >>> @@ -702,7 +778,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         _GLIBCXX_NODISCARD
>> >>>         __stringbuf_type*
>> >>>         rdbuf() const
>> >>> -      { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
>> >>> +      { return 
>> >>> const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  Copying out the string buffer.
>> >>> @@ -716,6 +792,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>
>> >>> @@ -747,6 +824,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
>> >>> @@ -758,6 +836,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         str(__string_type&& __s)
>> >>>         { _M_stringbuf.str(std::move(__s)); }
>> >>>   #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>>)
>> >>> +       { _M_stringbuf.str(__t); }
>> >>> +#endif // C++26
>> >>>       };
>> >>>
>> >>>
>> >>> @@ -812,7 +899,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         */
>> >>>         basic_ostringstream()
>> >>>         : __ostream_type(), _M_stringbuf(ios_base::out)
>> >>> -      { this->init(&_M_stringbuf); }
>> >>> +      { this->init(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  Starts with an empty string buffer.
>> >>> @@ -829,7 +916,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         explicit
>> >>>         basic_ostringstream(ios_base::openmode __mode)
>> >>>         : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
>> >>> -      { this->init(&_M_stringbuf); }
>> >>> +      { this->init(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  Starts with an existing string buffer.
>> >>> @@ -848,7 +935,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         basic_ostringstream(const __string_type& __str,
>> >>>                            ios_base::openmode __mode = ios_base::out)
>> >>>         : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
>> >>> -      { this->init(&_M_stringbuf); }
>> >>> +      { this->init(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  The destructor does nothing.
>> >>> @@ -865,9 +952,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         basic_ostringstream(basic_ostringstream&& __rhs)
>> >>>         : __ostream_type(std::move(__rhs)),
>> >>>         _M_stringbuf(std::move(__rhs._M_stringbuf))
>> >>> -      { __ostream_type::set_rdbuf(&_M_stringbuf); }
>> >>> +      { __ostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>   #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
>> >>> +       // P0408 Efficient access to basic_stringbuf buffer
>> >>>         basic_ostringstream(ios_base::openmode __mode, const 
>> >>> allocator_type& __a)
>> >>>         : __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a)
>> >>>         { this->init(std::__addressof(_M_stringbuf)); }
>> >>> @@ -899,6 +987,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>          { }
>> >>>   #endif // C++20
>> >>>
>> >>> +#ifdef __cpp_lib_sstream_from_string_view
>> >>> +      template <typename _Tp>
>> >>> +       explicit
>> >>> +       basic_ostringstream(
>> >>> +           const _Tp& __t, ios_base::openmode __mode = ios_base::out)
>> >>> +         requires (is_convertible_v<const _Tp&,
>> >>> +                   basic_string_view<_CharT, _Traits>>)
>> >>> +       : basic_ostringstream(__t, __mode, allocator_type{})
>> >>> +       { }
>> >>> +
>> >>> +      template <typename _Tp>
>> >>> +       basic_ostringstream(const _Tp& __t, const allocator_type& __a)
>> >>> +         requires (is_convertible_v<const _Tp&,
>> >>> +                   basic_string_view<_CharT, _Traits>>)
>> >>> +       : basic_ostringstream(__t, ios_base::out, __a)
>> >>> +       { }
>> >>> +
>> >>> +      template <typename _Tp>
>> >>> +       basic_ostringstream(const _Tp& __t, ios_base::openmode __mode,
>> >>> +           const allocator_type& __a)
>> >>> +         requires (is_convertible_v<const _Tp&,
>> >>> +                   basic_string_view<_CharT, _Traits>>)
>> >>> +       : __ostream_type(), _M_stringbuf(__t, __mode | ios_base::out, 
>> >>> __a)
>> >>> +       { this->init(std::__addressof(_M_stringbuf)); }
>> >>> +#endif // C++26
>> >>> +
>> >>>         // 27.8.3.2 Assign and swap:
>> >>>
>> >>>         basic_ostringstream&
>> >>> @@ -930,7 +1044,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         _GLIBCXX_NODISCARD
>> >>>         __stringbuf_type*
>> >>>         rdbuf() const
>> >>> -      { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
>> >>> +      { return 
>> >>> const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  Copying out the string buffer.
>> >>> @@ -944,6 +1058,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>
>> >>> @@ -975,6 +1090,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
>> >>> @@ -986,6 +1102,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         str(__string_type&& __s)
>> >>>         { _M_stringbuf.str(std::move(__s)); }
>> >>>   #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>>)
>> >>> +       { _M_stringbuf.str(__t); }
>> >>> +#endif // C++26
>> >>>       };
>> >>>
>> >>>
>> >>> @@ -1040,7 +1165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         */
>> >>>         basic_stringstream()
>> >>>         : __iostream_type(), _M_stringbuf(ios_base::out | ios_base::in)
>> >>> -      { this->init(&_M_stringbuf); }
>> >>> +      { this->init(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  Starts with an empty string buffer.
>> >>> @@ -1055,7 +1180,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         explicit
>> >>>         basic_stringstream(ios_base::openmode __m)
>> >>>         : __iostream_type(), _M_stringbuf(__m)
>> >>> -      { this->init(&_M_stringbuf); }
>> >>> +      { this->init(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  Starts with an existing string buffer.
>> >>> @@ -1072,7 +1197,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         basic_stringstream(const __string_type& __str,
>> >>>                           ios_base::openmode __m = ios_base::out | 
>> >>> ios_base::in)
>> >>>         : __iostream_type(), _M_stringbuf(__str, __m)
>> >>> -      { this->init(&_M_stringbuf); }
>> >>> +      { this->init(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  The destructor does nothing.
>> >>> @@ -1089,12 +1214,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         basic_stringstream(basic_stringstream&& __rhs)
>> >>>         : __iostream_type(std::move(__rhs)),
>> >>>         _M_stringbuf(std::move(__rhs._M_stringbuf))
>> >>> -      { __iostream_type::set_rdbuf(&_M_stringbuf); }
>> >>> +      { __iostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>   #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
>> >>> +       // P0408 Efficient access to basic_stringbuf buffer
>> >>>         basic_stringstream(ios_base::openmode __mode, const 
>> >>> allocator_type& __a)
>> >>>         : __iostream_type(), _M_stringbuf(__mode, __a)
>> >>> -      { this->init(&_M_stringbuf); }
>> >>> +      { this->init(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         explicit
>> >>>         basic_stringstream(__string_type&& __str,
>> >>> @@ -1125,6 +1251,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>          { }
>> >>>   #endif // C++20
>> >>>
>> >>> +#ifdef __cpp_lib_sstream_from_string_view
>> >>> +      template <typename _Tp>
>> >>> +       explicit
>> >>> +       basic_stringstream(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_stringstream(__t, __mode, allocator_type{})
>> >>> +       { }
>> >>> +
>> >>> +      template <typename _Tp>
>> >>> +       basic_stringstream(const _Tp& __t, const allocator_type& __a)
>> >>> +         requires (is_convertible_v<const _Tp&,
>> >>> +                   basic_string_view<_CharT, _Traits>>)
>> >>> +       : basic_stringstream(__t, ios_base::in | ios_base::out, __a)
>> >>> +       { }
>> >>> +
>> >>> +      template <typename _Tp>
>> >>> +       basic_stringstream(const _Tp& __t, ios_base::openmode __mode,
>> >>> +           const allocator_type& __a)
>> >>> +         requires (is_convertible_v<const _Tp&, 
>> >>> basic_string_view<_CharT, _Traits>>)
>> >>> +       : __iostream_type(), _M_stringbuf(__t, __mode, __a)
>> >>> +       { this->init(std::__addressof(_M_stringbuf)); }
>> >>> +#endif // C++26
>> >>> +
>> >>>         // 27.8.3.2 Assign and swap:
>> >>>
>> >>>         basic_stringstream&
>> >>> @@ -1156,7 +1307,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         _GLIBCXX_NODISCARD
>> >>>         __stringbuf_type*
>> >>>         rdbuf() const
>> >>> -      { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
>> >>> +      { return 
>> >>> const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); }
>> >>>
>> >>>         /**
>> >>>          *  @brief  Copying out the string buffer.
>> >>> @@ -1170,6 +1321,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>
>> >>> @@ -1201,6 +1353,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
>> >>> @@ -1212,6 +1365,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
>> >>>         str(__string_type&& __s)
>> >>>         { _M_stringbuf.str(std::move(__s)); }
>> >>>   #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>>)
>> >>> +       { _M_stringbuf.str(__t); }
>> >>> +#endif // C++26
>> >>>       };
>> >>>
>> >>>   #if __cplusplus >= 201103L
>> >>> diff --git 
>> >>> a/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc
>> >>>  
>> >>> b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc
>> >>> new file mode 100644
>> >>> index 00000000000..27f65aa9437
>> >>> --- /dev/null
>> >>> +++ 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc
>> >>> @@ -0,0 +1,195 @@
>> >>> +// C++26 [istringstream.general]
>> >>> +
>> >>> +// { dg-do run { target c++26 } }
>> >>> +
>> >>> +#include <sstream>
>> >>> +#include <string>
>> >>> +#include <string_view>
>> >>> +#include <testsuite_allocator.h>
>> >>> +#include <testsuite_hooks.h>
>> >>> +
>> >>> +// Check C++26 P2495 istringstream ctors and members str(s) that accept 
>> >>> a
>> >>> +// string_view, or anything convertible to a string_view, in place of a
>> >>> +// string object. Mostly just verify plumbing.
>> >>> +
>> >>> +#ifndef C
>> >>> +# define C char
>> >>> +# define L(a) a
>> >>> +#endif
>> >>> +
>> >>> +using string = std::basic_string<C>;
>> >>> +using string_view = std::basic_string_view<C>;
>> >>> +using istringstream = std::basic_istringstream<C>;
>> >>> +
>> >>> +struct convertible_to_string_view {
>> >>> +  string s;
>> >>> +  operator string_view() const { return s; }
>> >>> +};
>> >>> +
>> >>> +const string str(L("This is a test string"));
>> >>> +convertible_to_string_view cstr{str};  // a copy
>> >>> +const convertible_to_string_view ccstr{str};  // another copy
>> >>> +
>> >>> +template <typename istringstream = std::basic_istringstream<C>>
>> >>> +void
>> >>> +test01()
>> >>> +{
>> >>> +  // Test C++26 constructor and str(s) taking a generalized string_view
>> >>> +
>> >>> +  static_assert(! requires { istringstream(1); },
>> >>> +      "istringstream ctor should reject what cannot be converted to a 
>> >>> string_view");
>> >>> +  static_assert(! requires { istringstream().str(1); },
>> >>> +      "istringstream::str(s) should reject what cannot be converted to 
>> >>> a string_view");
>> >>> +
>> >>> +  static_assert(!std::is_convertible_v<string_view, istringstream>,
>> >>> +      "istringstream(string_view, ios::openmode) is explicit");
>> >>> +  static_assert(!std::is_convertible_v<const string_view, 
>> >>> istringstream>,
>> >>> +      "istringstream(string_view, ios::openmode) is explicit");
>> >>> +  static_assert(!std::is_convertible_v<convertible_to_string_view, 
>> >>> istringstream>,
>> >>> +      "istringstream(convertible_to_string_view, ios::openmode) is 
>> >>> explicit");
>> >>> +  static_assert(!std::is_convertible_v<const 
>> >>> convertible_to_string_view, istringstream>,
>> >>> +      "istringstream(convertible_to_string_view, ios::openmode) is 
>> >>> explicit");
>> >>> +
>> >>> +  {
>> >>> +    istringstream istr(cstr);
>> >>> +    VERIFY( istr.str() == cstr.s );
>> >>> +    VERIFY( istr.get() == cstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    istringstream istr(ccstr);
>> >>> +    VERIFY( istr.str() == ccstr.s );
>> >>> +    VERIFY( istr.get() == ccstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    istringstream istr(cstr, std::ios_base::in);
>> >>> +    VERIFY( istr.str() == cstr.s );
>> >>> +    VERIFY( istr.get() == cstr.s[0] );
>> >>> +    VERIFY( istr.rdbuf()->sputc('X') != 'X' );
>> >>> +  }
>> >>> +  {
>> >>> +    istringstream istr(cstr, std::ios_base::out);
>> >>> +    VERIFY( istr.str() == cstr.s );
>> >>> +    VERIFY( istr.get() == cstr.s[0] );
>> >>> +    VERIFY( istr.rdbuf()->sputc('X') == 'X' );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +void
>> >>> +test02()
>> >>> +{
>> >>> +  // Test various C++26 constructors taking string views
>> >>> +  // and mix of other arguments
>> >>> +
>> >>> +  auto const mode = std::ios_base::in | std::ios_base::out;
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // basic_istringstream(const T&, ios_base::openmode, const 
>> >>> allocator_type&)
>> >>> +
>> >>> +    istringstream::allocator_type a;
>> >>> +    {
>> >>> +      istringstream istr(cstr, mode, a); // ={} checks for non-explicit 
>> >>> ctor
>> >>> +      VERIFY( istr.str() == cstr.s );
>> >>> +    }
>> >>> +    {
>> >>> +      istringstream istr(cstr, std::ios::in, a);
>> >>> +      VERIFY( istr.str() == cstr.s );
>> >>> +      VERIFY( istr.get() == cstr.s[0] );
>> >>> +      VERIFY( istr.rdbuf()->sputc('X') != 'X' );
>> >>> +    }
>> >>> +    {
>> >>> +      istringstream istr(cstr, std::ios::out, a);
>> >>> +      VERIFY( istr.str() == cstr.s );
>> >>> +      VERIFY( istr.get() == cstr.s[0] );
>> >>> +      VERIFY( istr.rdbuf()->sputc('X') == 'X' );
>> >>> +    }
>> >>> +  }
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // basic_istringstream(const T&, ios_base::openmode)
>> >>> +    {
>> >>> +      istringstream istr(cstr, mode);
>> >>> +      VERIFY( istr.str() == cstr.s );
>> >>> +      VERIFY( istr.get() == cstr.s[0] );
>> >>> +      VERIFY( istr.rdbuf()->sputc('X') == 'X' );
>> >>> +    }
>> >>> +    {
>> >>> +      istringstream istr(cstr, std::ios::in);
>> >>> +      VERIFY( istr.str() == cstr.s );
>> >>> +      VERIFY( istr.get() == cstr.s[0] );
>> >>> +      VERIFY( istr.rdbuf()->sputc('X') != 'X' );
>> >>> +    }
>> >>> +    {
>> >>> +      istringstream istr(cstr, std::ios::out);
>> >>> +      VERIFY( istr.str() == cstr.s );
>> >>> +      VERIFY( istr.get() == cstr.s[0] );
>> >>> +      VERIFY( istr.rdbuf()->sputc('X') == 'X' );
>> >>> +    }
>> >>> +  }
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // explicit
>> >>> +    // basic_istringstream(const T&, ios_base::openmode = ios_base::in)
>> >>> +
>> >>> +    istringstream istr(cstr);
>> >>> +    VERIFY( istr.str() == cstr.s );
>> >>> +    VERIFY( istr.get() == cstr.s[0] );
>> >>> +    VERIFY( istr.rdbuf()->sputc('X') != 'X' );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +using alloc_type = __gnu_test::uneq_allocator<C>;
>> >>> +
>> >>> +template<typename Alloc, typename CC = typename Alloc::value_type>
>> >>> +  using istringstream_with_alloc
>> >>> +    = std::basic_istringstream<CC, std::char_traits<CC>, Alloc>;
>> >>> +
>> >>> +void test03()
>> >>> +{
>> >>> +  alloc_type a{1};
>> >>> +  {
>> >>> +    istringstream_with_alloc<alloc_type> istr(cstr, a);
>> >>> +    VERIFY( istr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{istr.str()} == cstr );
>> >>> +    VERIFY( istr.get() == cstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    istringstream_with_alloc<alloc_type> istr(cstr, std::ios::in, a);
>> >>> +    VERIFY( istr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{istr.str()} == cstr );
>> >>> +    VERIFY( istr.get() == cstr.s[0] );
>> >>> +    VERIFY( istr.rdbuf()->sputc('X') != 'X' );
>> >>> +  }
>> >>> +  {
>> >>> +    istringstream_with_alloc<alloc_type> istr(cstr, std::ios::out, a);
>> >>> +    VERIFY( istr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{istr.str()} == cstr );
>> >>> +    VERIFY( istr.get() == cstr.s[0] );
>> >>> +    VERIFY( istr.rdbuf()->sputc('X') == 'X' );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +void test04()
>> >>> +{
>> >>> +  {
>> >>> +    istringstream istr;
>> >>> +    istr.str( cstr );
>> >>> +    VERIFY( istr.str() == cstr.s );
>> >>> +  }
>> >>> +  {
>> >>> +    istringstream istr;
>> >>> +    istr.str( ccstr );
>> >>> +    VERIFY( istr.str() == ccstr.s );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +int
>> >>> +main()
>> >>> +{
>> >>> +  test01();
>> >>> +  test02();
>> >>> +  test03();
>> >>> +  test04();
>> >>> +}
>> >>> diff --git 
>> >>> a/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc
>> >>>  
>> >>> b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc
>> >>> new file mode 100644
>> >>> index 00000000000..cfb73c4c510
>> >>> --- /dev/null
>> >>> +++ 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc
>> >>> @@ -0,0 +1,3 @@
>> >>> +#define C wchar_t
>> >>> +#define L(a) L##a
>> >>> +#include "../char/string_view.cc"
>> >>> diff --git 
>> >>> a/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc
>> >>>  
>> >>> b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc
>> >>> new file mode 100644
>> >>> index 00000000000..731e97e4aa2
>> >>> --- /dev/null
>> >>> +++ 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc
>> >>> @@ -0,0 +1,194 @@
>> >>> +// C++26 [ostringstream.general]
>> >>> +
>> >>> +// { dg-do run { target c++26 } }
>> >>> +
>> >>> +#include <sstream>
>> >>> +#include <string>
>> >>> +#include <string_view>
>> >>> +#include <testsuite_allocator.h>
>> >>> +#include <testsuite_hooks.h>
>> >>> +
>> >>> +// Check C++26 P2495 ostringstream ctors and members str(s) that accept 
>> >>> a
>> >>> +// string_view, or anything convertible to a string_view, in place of a
>> >>> +// string object. Mostly just verify plumbing.
>> >>> +
>> >>> +#ifndef C
>> >>> +# define C char
>> >>> +# define L(a) a
>> >>> +#endif
>> >>> +
>> >>> +using string = std::basic_string<C>;
>> >>> +using string_view = std::basic_string_view<C>;
>> >>> +using ostringstream = std::basic_ostringstream<C>;
>> >>> +
>> >>> +struct convertible_to_string_view {
>> >>> +  string s;
>> >>> +  operator string_view() const { return s; }
>> >>> +};
>> >>> +
>> >>> +const string str(L("This is a test string"));
>> >>> +convertible_to_string_view cstr{str};  // a copy
>> >>> +const convertible_to_string_view ccstr{str};  // another copy
>> >>> +
>> >>> +template <typename ostringstream = std::basic_ostringstream<C>>
>> >>> +void
>> >>> +test01()
>> >>> +{
>> >>> +  // Test C++26 constructor and str(s) taking a generalized string_view
>> >>> +
>> >>> +  static_assert(! requires { ostringstream(1); },
>> >>> +      "ostringstream ctor should reject what cannot be converted to a 
>> >>> string_view");
>> >>> +  static_assert(! requires { ostringstream().str(1); },
>> >>> +      "ostringstream::str(s) should reject what cannot be converted to 
>> >>> a string_view");
>> >>> +
>> >>> +  static_assert(!std::is_convertible_v<string_view, ostringstream>,
>> >>> +      "ostringstream(string_view, ios::openmode) is explicit");
>> >>> +  static_assert(!std::is_convertible_v<const string_view, 
>> >>> ostringstream>,
>> >>> +      "ostringstream(string_view, ios::openmode) is explicit");
>> >>> +  static_assert(!std::is_convertible_v<convertible_to_string_view, 
>> >>> ostringstream>,
>> >>> +      "ostringstream(convertible_to_string_view, ios::openmode) is 
>> >>> explicit");
>> >>> +  static_assert(!std::is_convertible_v<const 
>> >>> convertible_to_string_view, ostringstream>,
>> >>> +      "ostringstream(convertible_to_string_view, ios::openmode) is 
>> >>> explicit");
>> >>> +
>> >>> +  {
>> >>> +    ostringstream ostrstr(cstr);
>> >>> +    VERIFY( ostrstr.str() == cstr.s );
>> >>> +    VERIFY( ostrstr.rdbuf()->sgetc() == 
>> >>> ostringstream::traits_type::eof() );
>> >>> +  }
>> >>> +  {
>> >>> +    ostringstream ostrstr(ccstr);
>> >>> +    VERIFY( ostrstr.str() == ccstr.s );
>> >>> +    VERIFY( ostrstr.rdbuf()->sgetc() == 
>> >>> ostringstream::traits_type::eof() );
>> >>> +  }
>> >>> +  {
>> >>> +    ostringstream ostrstr(cstr, std::ios_base::in);
>> >>> +    VERIFY( ostrstr.str() == cstr.s );
>> >>> +    VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
>> >>> +    VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
>> >>> +  }
>> >>> +  {
>> >>> +    ostringstream ostrstr(cstr, std::ios_base::out);
>> >>> +    VERIFY( ostrstr.str() == cstr.s );
>> >>> +    VERIFY( ostrstr.rdbuf()->sgetc() == 
>> >>> ostringstream::traits_type::eof() );
>> >>> +    VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +void
>> >>> +test02()
>> >>> +{
>> >>> +  // Test plumbing of C++26 various constructors taking string views
>> >>> +
>> >>> +  auto const mode = std::ios_base::in | std::ios_base::out;
>> >>> +
>> >>> +  {
>> >>> +    ostringstream::allocator_type a;
>> >>> +    // template <typename T>
>> >>> +    // basic_ostringstream(const T&, ios_base::openmode, const 
>> >>> allocator_type&)
>> >>> +    {
>> >>> +      ostringstream ostrstr(cstr, mode, a); // ={} checks for 
>> >>> non-explicit ctor
>> >>> +      VERIFY( ostrstr.str() == cstr.s );
>> >>> +    }
>> >>> +    {
>> >>> +      ostringstream ostrstr(cstr, std::ios::in, a);
>> >>> +      VERIFY( ostrstr.str() == cstr.s );
>> >>> +      VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
>> >>> +      VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
>> >>> +    }
>> >>> +    {
>> >>> +      ostringstream ostrstr(cstr, std::ios::out, a);
>> >>> +      VERIFY( ostrstr.str() == cstr.s );
>> >>> +      VERIFY( ostrstr.rdbuf()->sgetc() == 
>> >>> ostringstream::traits_type::eof() );
>> >>> +      VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
>> >>> +    }
>> >>> +  }
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // basic_ostringstream(const T&, ios_base::openmode)
>> >>> +    {
>> >>> +      ostringstream ostrstr(cstr, mode);
>> >>> +      VERIFY( ostrstr.str() == cstr.s );
>> >>> +      VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
>> >>> +      VERIFY( ostrstr.put('Y').good() );
>> >>> +    }
>> >>> +    {
>> >>> +      ostringstream ostrstr(cstr, std::ios::in);
>> >>> +      VERIFY( ostrstr.str() == cstr.s );
>> >>> +      VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
>> >>> +      VERIFY( ostrstr.put('X').good() );
>> >>> +    }
>> >>> +    {
>> >>> +      ostringstream ostrstr(cstr, std::ios::out);
>> >>> +      VERIFY( ostrstr.str() == cstr.s );
>> >>> +      VERIFY( ostrstr.rdbuf()->sgetc() == 
>> >>> ostringstream::traits_type::eof() );
>> >>> +      VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
>> >>> +    }
>> >>> +  }
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // explicit
>> >>> +    // basic_ostringstream(const T&, ios_base::openmode = ios_base::out)
>> >>> +
>> >>> +    ostringstream ostrstr(cstr);
>> >>> +    VERIFY( ostrstr.str() == cstr.s );
>> >>> +    VERIFY( ostrstr.rdbuf()->sgetc() == 
>> >>> ostringstream::traits_type::eof() );
>> >>> +    VERIFY( ostrstr.put('Y').good() );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +using alloc_type = __gnu_test::uneq_allocator<C>;
>> >>> +
>> >>> +template<typename Alloc, typename CC = typename Alloc::value_type>
>> >>> +  using ostringstream_with_alloc
>> >>> +    = std::basic_ostringstream<CC, std::char_traits<CC>, Alloc>;
>> >>> +
>> >>> +void test03()
>> >>> +{
>> >>> +  alloc_type a{1};
>> >>> +  {
>> >>> +    ostringstream_with_alloc<alloc_type> ostrstr(cstr, a);
>> >>> +    VERIFY( ostrstr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{ostrstr.str()} == cstr );
>> >>> +    VERIFY( ostrstr.rdbuf()->sgetc() == 
>> >>> ostringstream::traits_type::eof() );
>> >>> +    VERIFY( ostrstr.put('X').good() );
>> >>> +  }
>> >>> +  {
>> >>> +    ostringstream_with_alloc<alloc_type> ostrstr(cstr, std::ios::in, a);
>> >>> +    VERIFY( ostrstr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{ostrstr.str()} == cstr );
>> >>> +    VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
>> >>> +    VERIFY( ostrstr.put('X').good() );
>> >>> +  }
>> >>> +  {
>> >>> +    ostringstream_with_alloc<alloc_type> ostrstr(cstr, std::ios::out, 
>> >>> a);
>> >>> +    VERIFY( ostrstr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{ostrstr.str()} == cstr );
>> >>> +    VERIFY( ostrstr.rdbuf()->sgetc() == 
>> >>> ostringstream::traits_type::eof() );
>> >>> +    VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +void test04()
>> >>> +{
>> >>> +  {
>> >>> +    ostringstream ostrstr;
>> >>> +    ostrstr.str(cstr);
>> >>> +    VERIFY( ostrstr.str() == cstr.s );
>> >>> +  }
>> >>> +  {
>> >>> +    ostringstream ostrstr;
>> >>> +    ostrstr.str(ccstr);
>> >>> +    VERIFY( ostrstr.str() == ccstr.s );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +int
>> >>> +main()
>> >>> +{
>> >>> +  test01();
>> >>> +  test02();
>> >>> +  test03();
>> >>> +  test04();
>> >>> +}
>> >>> diff --git 
>> >>> a/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc
>> >>>  
>> >>> b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc
>> >>> new file mode 100644
>> >>> index 00000000000..cfb73c4c510
>> >>> --- /dev/null
>> >>> +++ 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc
>> >>> @@ -0,0 +1,3 @@
>> >>> +#define C wchar_t
>> >>> +#define L(a) L##a
>> >>> +#include "../char/string_view.cc"
>> >>> diff --git 
>> >>> a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc
>> >>> new file mode 100644
>> >>> index 00000000000..7843269c48f
>> >>> --- /dev/null
>> >>> +++ 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc
>> >>> @@ -0,0 +1,205 @@
>> >>> +// C++26 31.8.2.1 [stringbuf.general]
>> >>> +
>> >>> +// { dg-do run { target c++26 } }
>> >>> +
>> >>> +#include <sstream>
>> >>> +#include <string>
>> >>> +#include <string_view>
>> >>> +#include <testsuite_allocator.h>
>> >>> +#include <testsuite_hooks.h>
>> >>> +
>> >>> +// Check C++26 P2495 stringbuf ctors and members str(s) that accept a
>> >>> +// string_view, or anything convertible to a string_view, in place of a
>> >>> +// string object.
>> >>> +
>> >>> +#ifndef C
>> >>> +# define C char
>> >>> +# define L(a) a
>> >>> +#endif
>> >>> +
>> >>> +using string = std::basic_string<C>;
>> >>> +using string_view = std::basic_string_view<C>;
>> >>> +using stringbuf = std::basic_stringbuf<C>;
>> >>> +
>> >>> +struct convertible_to_string_view {
>> >>> +  string s;
>> >>> +  operator string_view() const { return s; }
>> >>> +};
>> >>> +
>> >>> +const string str(L("This is a test string"));
>> >>> +convertible_to_string_view cstr{str};  // a copy
>> >>> +const convertible_to_string_view ccstr{str};  // another copy
>> >>> +
>> >>> +template <typename stringbuf = std::basic_stringbuf<C>>
>> >>> +void
>> >>> +test01()
>> >>> +{
>> >>> +  // Test C++26 constructor and str(s) taking a generalized string_view
>> >>> +
>> >>> +  static_assert(! requires { stringbuf(1); },
>> >>> +      "stringbuf ctor should reject what cannot be converted to a 
>> >>> string_view");
>> >>> +  static_assert(! requires { stringbuf().str(1); },
>> >>> +      "stringbuf::str(s) should reject what cannot be converted to a 
>> >>> string_view");
>> >>> +
>> >>> +  static_assert(!std::is_convertible_v<string_view, stringbuf>,
>> >>> +      "stringbuf(string_view, ios::openmode) is explicit");
>> >>> +  static_assert(!std::is_convertible_v<const string_view, stringbuf>,
>> >>> +      "stringbuf(string_view, ios::openmode) is explicit");
>> >>> +  static_assert(!std::is_convertible_v<convertible_to_string_view, 
>> >>> stringbuf>,
>> >>> +      "stringbuf(convertible_to_string_view, ios::openmode) is 
>> >>> explicit");
>> >>> +  static_assert(
>> >>> +      !std::is_convertible_v<const convertible_to_string_view, 
>> >>> stringbuf>,
>> >>> +      "stringbuf(convertible_to_string_view, ios::openmode) is 
>> >>> explicit");
>> >>> +
>> >>> +  {
>> >>> +    stringbuf sbuf(cstr);
>> >>> +    VERIFY( sbuf.str() == cstr.s );
>> >>> +    VERIFY( sbuf.sgetc() == cstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    stringbuf sbuf(ccstr);
>> >>> +    VERIFY( sbuf.str() == ccstr.s );
>> >>> +    VERIFY( sbuf.sgetc() == ccstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    stringbuf sbuf(cstr, std::ios_base::in);
>> >>> +    VERIFY( sbuf.str() == cstr.s );
>> >>> +    VERIFY( sbuf.sgetc() == cstr.s[0] );
>> >>> +    VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
>> >>> +  }
>> >>> +  {
>> >>> +    stringbuf sbuf(ccstr, std::ios_base::in);
>> >>> +    VERIFY( sbuf.str() == ccstr.s );
>> >>> +    VERIFY( sbuf.sgetc() == ccstr.s[0] );
>> >>> +    VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
>> >>> +  }
>> >>> +  {
>> >>> +    stringbuf sbuf(cstr, std::ios_base::out);
>> >>> +    VERIFY( sbuf.str() == cstr.s );
>> >>> +    VERIFY( sbuf.sputc('Y') == 'Y' );
>> >>> +    VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
>> >>> +  }
>> >>> +  {
>> >>> +    stringbuf sbuf(ccstr, std::ios_base::out);
>> >>> +    VERIFY( sbuf.str() == ccstr.s );
>> >>> +    VERIFY( sbuf.sputc('Y') == 'Y' );
>> >>> +    VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +void
>> >>> +test02()
>> >>> +{
>> >>> +  // Test C++26 constructors taking string views using different 
>> >>> allocators
>> >>> +
>> >>> +  auto const mode = std::ios_base::in | std::ios_base::out;
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // basic_stringbuf(const T&, ios_base::openmode, const 
>> >>> allocator_type&)
>> >>> +
>> >>> +    stringbuf::allocator_type a;
>> >>> +    {
>> >>> +      stringbuf sbuf(cstr, mode, a); // ={} checks for non-explicit ctor
>> >>> +      VERIFY( sbuf.str() == cstr.s );
>> >>> +    }
>> >>> +    {
>> >>> +      stringbuf sbuf(cstr, std::ios::in, a);
>> >>> +      VERIFY( sbuf.str() == cstr.s );
>> >>> +      VERIFY( sbuf.sgetc() == cstr.s[0] );
>> >>> +      VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
>> >>> +    }
>> >>> +
>> >>> +    {
>> >>> +      stringbuf sbuf(cstr, std::ios::out, a);
>> >>> +      VERIFY( sbuf.str() == cstr.s );
>> >>> +      VERIFY( sbuf.sputc('X') == 'X' );
>> >>> +      VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
>> >>> +    }
>> >>> +  }
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // basic_stringbuf(const T&, ios_base::openmode)
>> >>> +    {
>> >>> +      stringbuf sbuf(cstr, mode);
>> >>> +      VERIFY( sbuf.str() == cstr.s );
>> >>> +    }
>> >>> +    {
>> >>> +      stringbuf sbuf(cstr, std::ios::in);
>> >>> +      VERIFY( sbuf.str() == cstr.s );
>> >>> +      VERIFY( sbuf.sgetc() == cstr.s[0] );
>> >>> +      VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
>> >>> +    }
>> >>> +    {
>> >>> +      stringbuf sbuf(cstr, std::ios::out);
>> >>> +      VERIFY( sbuf.str() == cstr.s );
>> >>> +      VERIFY( sbuf.sputc('X') == 'X' );
>> >>> +      VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
>> >>> +    }
>> >>> +  }
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // explicit
>> >>> +    // basic_stringbuf(const T&, ios_base::openmode = 
>> >>> ios_base::in|ios_base::out)
>> >>> +
>> >>> +    stringbuf sbuf(cstr);
>> >>> +    VERIFY( sbuf.str() == cstr.s );
>> >>> +    VERIFY( sbuf.sgetc() == cstr.s[0] );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +using alloc_type = __gnu_test::uneq_allocator<C>;
>> >>> +
>> >>> +template<typename Alloc, typename CC = typename Alloc::value_type>
>> >>> +  using stringbuf_with_alloc
>> >>> +    = std::basic_stringbuf<CC, std::char_traits<CC>, Alloc>;
>> >>> +
>> >>> +void test03()
>> >>> +{
>> >>> +  alloc_type a{1};
>> >>> +  {
>> >>> +    stringbuf_with_alloc<alloc_type> sbuf(cstr, a);
>> >>> +    VERIFY( sbuf.get_allocator() == a );
>> >>> +    VERIFY( string_view{sbuf.str()} == cstr );
>> >>> +    VERIFY( sbuf.sgetc() == cstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    stringbuf_with_alloc<alloc_type> sbuf(cstr, std::ios::in, a);
>> >>> +    VERIFY( sbuf.get_allocator() == a );
>> >>> +    VERIFY( string_view{sbuf.str()} == cstr );
>> >>> +    VERIFY( sbuf.sgetc() == cstr.s[0] );
>> >>> +    VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
>> >>> +  }
>> >>> +  {
>> >>> +    stringbuf_with_alloc<alloc_type> sbuf(cstr, std::ios::out, a);
>> >>> +    VERIFY( sbuf.get_allocator() == a );
>> >>> +    VERIFY( string_view{sbuf.str()} == cstr );
>> >>> +    VERIFY( sbuf.sputc('X') == 'X' );
>> >>> +    VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +void test04()
>> >>> +{
>> >>> +  {
>> >>> +    stringbuf sbuf;
>> >>> +    sbuf.str(cstr);
>> >>> +    VERIFY( sbuf.str() == cstr.s );
>> >>> +  }
>> >>> +  {
>> >>> +    stringbuf sbuf;
>> >>> +    sbuf.str(ccstr);
>> >>> +    VERIFY( sbuf.str() == ccstr.s );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +int
>> >>> +main()
>> >>> +{
>> >>> +  test01();
>> >>> +  test02();
>> >>> +  test03();
>> >>> +  test04();
>> >>> +}
>> >>> diff --git 
>> >>> a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc
>> >>>  
>> >>> b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc
>> >>> new file mode 100644
>> >>> index 00000000000..cfb73c4c510
>> >>> --- /dev/null
>> >>> +++ 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc
>> >>> @@ -0,0 +1,3 @@
>> >>> +#define C wchar_t
>> >>> +#define L(a) L##a
>> >>> +#include "../char/string_view.cc"
>> >>> diff --git 
>> >>> a/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc
>> >>>  
>> >>> b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc
>> >>> new file mode 100644
>> >>> index 00000000000..72085230442
>> >>> --- /dev/null
>> >>> +++ 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc
>> >>> @@ -0,0 +1,204 @@
>> >>> +// C++26 31.8.2.1 [stringstream.general]
>> >>> +
>> >>> +// { dg-do run { target c++26 } }
>> >>> +
>> >>> +#include <sstream>
>> >>> +#include <string>
>> >>> +#include <string_view>
>> >>> +#include <testsuite_allocator.h>
>> >>> +#include <testsuite_hooks.h>
>> >>> +
>> >>> +// Check C++26 P2495 stringstream ctors and members str(s) that accept a
>> >>> +// string_view, or anything convertible to a string_view, in place of a
>> >>> +// string object. Mostly just verify plumbing.
>> >>> +
>> >>> +#ifndef C
>> >>> +# define C char
>> >>> +# define L(a) a
>> >>> +#endif
>> >>> +
>> >>> +using string = std::basic_string<C>;
>> >>> +using string_view = std::basic_string_view<C>;
>> >>> +using stringstream = std::basic_stringstream<C>;
>> >>> +
>> >>> +struct convertible_to_string_view {
>> >>> +  string s;
>> >>> +  operator string_view() const { return s; }
>> >>> +};
>> >>> +
>> >>> +const string str(L("This is a test string"));
>> >>> +convertible_to_string_view cstr{str};  // a copy
>> >>> +const convertible_to_string_view ccstr{str};  // another copy
>> >>> +
>> >>> +template <typename stringstream = std::basic_stringstream<C>>
>> >>> +void
>> >>> +test01()
>> >>> +{
>> >>> +  // Test C++26 constructor and str(s) taking a generalized string_view
>> >>> +
>> >>> +  static_assert(! requires { stringstream(1); },
>> >>> +      "stringstream ctor should reject what cannot be converted to a 
>> >>> string_view");
>> >>> +  static_assert(! requires { stringstream().str(1); },
>> >>> +      "stringstream::str(s) should reject what cannot be converted to a 
>> >>> string_view");
>> >>> +
>> >>> +  static_assert(!std::is_convertible_v<string_view, stringstream>,
>> >>> +      "stringstream(string_view, ios::openmode) is explicit");
>> >>> +  static_assert(!std::is_convertible_v<const string_view, stringstream>,
>> >>> +      "stringstream(string_view, ios::openmode) is explicit");
>> >>> +  static_assert(!std::is_convertible_v<convertible_to_string_view, 
>> >>> stringstream>,
>> >>> +      "stringstream(convertible_to_string_view, ios::openmode) is 
>> >>> explicit");
>> >>> +  static_assert(!std::is_convertible_v<const 
>> >>> convertible_to_string_view, stringstream>,
>> >>> +      "stringstream(convertible_to_string_view, ios::openmode) is 
>> >>> explicit");
>> >>> +
>> >>> +  {
>> >>> +    stringstream strstr(cstr);
>> >>> +    VERIFY( strstr.str() == cstr.s );
>> >>> +    VERIFY( strstr.get() == cstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    stringstream strstr(ccstr);
>> >>> +    VERIFY( strstr.str() == ccstr.s );
>> >>> +    VERIFY( strstr.get() == ccstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    stringstream strstr(cstr, std::ios_base::in);
>> >>> +    VERIFY( strstr.str() == cstr.s );
>> >>> +    VERIFY( strstr.get() == cstr.s[0] );
>> >>> +    VERIFY( strstr.put('X').rdstate() == strstr.badbit );
>> >>> +  }
>> >>> +  {
>> >>> +    stringstream strstr(cstr, std::ios_base::out);
>> >>> +    VERIFY( strstr.str() == cstr.s );
>> >>> +    VERIFY( strstr.put('Y').good() );
>> >>> +    VERIFY( strstr.get() == stringstream::traits_type::eof());
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +void
>> >>> +test02()
>> >>> +{
>> >>> +  // Test C++26 various constructors taking string views
>> >>> +
>> >>> +  auto const mode = std::ios_base::in | std::ios_base::out;
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // basic_stringstream(const T&, ios_base::openmode, const 
>> >>> allocator_type&)
>> >>> +
>> >>> +    stringstream::allocator_type a;
>> >>> +    {
>> >>> +      stringstream strstr(cstr, mode, a); // ={} checks for 
>> >>> non-explicit ctor
>> >>> +      VERIFY( strstr.str() == cstr.s );
>> >>> +    }
>> >>> +    {
>> >>> +      stringstream strstr(cstr, std::ios::in, a);
>> >>> +      VERIFY( strstr.str() == cstr.s );
>> >>> +      VERIFY( strstr.get() == cstr.s[0] );
>> >>> +      VERIFY( strstr.put('X').rdstate() == strstr.badbit );
>> >>> +    }
>> >>> +    {
>> >>> +      stringstream strstr(cstr, std::ios::out, a);
>> >>> +      VERIFY( strstr.str() == cstr.s );
>> >>> +      VERIFY( strstr.put('X').good() );
>> >>> +      VERIFY( strstr.get() == stringstream::traits_type::eof());
>> >>> +    }
>> >>> +  }
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // basic_stringstream(const T&, ios_base::openmode)
>> >>> +
>> >>> +    {
>> >>> +      stringstream strstr(cstr, mode);
>> >>> +      VERIFY( strstr.str() == cstr.s );
>> >>> +      VERIFY( strstr.get() == cstr.s[0] );
>> >>> +      VERIFY( strstr.put('X').good() );
>> >>> +    }
>> >>> +    {
>> >>> +      stringstream strstr(cstr, std::ios::in);
>> >>> +      VERIFY( strstr.str() == cstr.s );
>> >>> +      VERIFY( strstr.get() == cstr.s[0] );
>> >>> +      VERIFY( strstr.put('X').rdstate() == strstr.badbit );
>> >>> +    }
>> >>> +    {
>> >>> +      stringstream strstr(cstr, std::ios::out);
>> >>> +      VERIFY( strstr.str() == cstr.s );
>> >>> +      VERIFY( strstr.put('X').good() );
>> >>> +      VERIFY( strstr.get() == stringstream::traits_type::eof());
>> >>> +    }
>> >>> +  }
>> >>> +
>> >>> +  {
>> >>> +    // template <typename T>
>> >>> +    // explicit
>> >>> +    // basic_stringstream(const T&, ios_base::openmode = 
>> >>> ios_base::in|ios_base::out)
>> >>> +
>> >>> +    stringstream strstr(cstr);
>> >>> +    VERIFY( strstr.str() == cstr.s );
>> >>> +    VERIFY( strstr.get() == cstr.s[0] );
>> >>> +    VERIFY( strstr.put('X').good() );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +// A minimal allocator with no default constructor
>> >>> +template<typename T>
>> >>> +  struct NoDefaultCons : __gnu_test::SimpleAllocator<T>
>> >>> +  {
>> >>> +    using __gnu_test::SimpleAllocator<T>::SimpleAllocator;
>> >>> +    NoDefaultCons() = delete;
>> >>> +    NoDefaultCons(int) { }
>> >>> +  };
>> >>> +
>> >>> +using alloc_type = __gnu_test::uneq_allocator<C>;
>> >>> +
>> >>> +template<typename Alloc, typename CC = typename Alloc::value_type>
>> >>> +  using stringstream_with_alloc
>> >>> +    = std::basic_stringstream<CC, std::char_traits<CC>, Alloc>;
>> >>> +
>> >>> +void test03()
>> >>> +{
>> >>> +  alloc_type a{1};
>> >>> +  {
>> >>> +    stringstream_with_alloc<alloc_type> strstr(cstr, a);
>> >>> +    VERIFY( strstr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{strstr.str()} == cstr );
>> >>> +    VERIFY( strstr.get() == cstr.s[0] );
>> >>> +  }
>> >>> +  {
>> >>> +    stringstream_with_alloc<alloc_type> strstr(cstr, std::ios::in, a);
>> >>> +    VERIFY( strstr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{strstr.str()} == cstr );
>> >>> +    VERIFY( strstr.get() == cstr.s[0] );
>> >>> +    VERIFY( strstr.put('X').rdstate() == strstr.badbit );
>> >>> +  }
>> >>> +  {
>> >>> +    stringstream_with_alloc<alloc_type> strstr(cstr, std::ios::out, a);
>> >>> +    VERIFY( strstr.rdbuf()->get_allocator() == a );
>> >>> +    VERIFY( string_view{strstr.str()} == cstr );
>> >>> +    VERIFY( strstr.put('X').good() );
>> >>> +    VERIFY( strstr.get() == stringstream::traits_type::eof());
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +void test04()
>> >>> +{
>> >>> +  {
>> >>> +    stringstream strstr;
>> >>> +    strstr.str( cstr );
>> >>> +    VERIFY( strstr.str() == cstr.s );
>> >>> +  }
>> >>> +  {
>> >>> +    stringstream strstr;
>> >>> +    strstr.str( ccstr );
>> >>> +    VERIFY( strstr.str() == ccstr.s );
>> >>> +  }
>> >>> +}
>> >>> +
>> >>> +int
>> >>> +main()
>> >>> +{
>> >>> +  test01();
>> >>> +  test02();
>> >>> +  test03();
>> >>> +  test04();
>> >>> +}
>> >>> diff --git 
>> >>> a/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc
>> >>>  
>> >>> b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc
>> >>> new file mode 100644
>> >>> index 00000000000..cfb73c4c510
>> >>> --- /dev/null
>> >>> +++ 
>> >>> b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc
>> >>> @@ -0,0 +1,3 @@
>> >>> +#define C wchar_t
>> >>> +#define L(a) L##a
>> >>> +#include "../char/string_view.cc"
>> >>> --
>> >>> 2.49.0
>> >>>
>> >>
>> >
>> >
>>

Reply via email to