[libcxx-commits] [libcxx] 81ad5a5 - [libc++] Implement stringbuf members of P0408R7 (Efficient Access to basic_stringbuf's Buffer)

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jul 1 04:43:16 PDT 2023


Author: Piotr Fusik
Date: 2023-07-01T13:43:08+02:00
New Revision: 81ad5a5cb87740c62b30a4f8232770bd5eb7fc45

URL: https://github.com/llvm/llvm-project/commit/81ad5a5cb87740c62b30a4f8232770bd5eb7fc45
DIFF: https://github.com/llvm/llvm-project/commit/81ad5a5cb87740c62b30a4f8232770bd5eb7fc45.diff

LOG: [libc++] Implement stringbuf members of P0408R7 (Efficient Access to basic_stringbuf's Buffer)

Reviewed By: #libc, Mordante

Differential Revision: https://reviews.llvm.org/D153709

Added: 
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/alloc.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/mode.alloc.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.alloc.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string-alloc.mode.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.alloc.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.mode.alloc.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.move.mode.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.alloc.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.move.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.string-alloc.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.string.move.pass.cpp

Modified: 
    libcxx/docs/Status/Cxx20.rst
    libcxx/include/sstream

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst
index 1ab0252b8e277d..3ce47477fcbfb3 100644
--- a/libcxx/docs/Status/Cxx20.rst
+++ b/libcxx/docs/Status/Cxx20.rst
@@ -49,7 +49,7 @@ Paper Status
    .. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.
    .. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0.
    .. [#note-P2231] P2231: Optional is complete. The changes to variant haven't been implemented yet.
-   .. [#note-P0408] P0408: Only `view()` members implemented.
+   .. [#note-P0408] P0408: All `stringbuf` members and `view()` in all classes implemented.
    .. [#note-P0660] P0660: Section 32.3 Stop Tokens is complete. ``jthread`` hasn't been implemented yet.
 
 .. _issues-status-cxx20:

diff  --git a/libcxx/include/sstream b/libcxx/include/sstream
index 05756eb28164ee..47b3634595f336 100644
--- a/libcxx/include/sstream
+++ b/libcxx/include/sstream
@@ -30,18 +30,41 @@ public:
     explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
     basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}               // C++20
     explicit basic_stringbuf(ios_base::openmode which);                                // C++20
-    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& str,
+    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& s,
                              ios_base::openmode which = ios_base::in | ios_base::out);
+    explicit basic_stringbuf(const allocator_type& a)
+        : basic_stringbuf(ios_base::in | ios_base::out, a) {}                          // C++20
+    basic_stringbuf(ios_base::openmode which, const allocator_type& a);                // C++20
+    explicit basic_stringbuf(basic_string<char_type, traits_type, allocator_type>&& s,
+                             ios_base::openmode which = ios_base::in | ios_base::out); // C++20
+    template <class SAlloc>
+    basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
+        : basic_stringbuf(s, ios_base::in | ios_base::out, a) {}                       // C++20
+    template <class SAlloc>
+    basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
+                    ios_base::openmode which, const allocator_type& a);                // C++20
+    template <class SAlloc>
+    explicit basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
+                             ios_base::openmode which = ios_base::in | ios_base::out); // C++20
     basic_stringbuf(basic_stringbuf&& rhs);
+    basic_stringbuf(basic_stringbuf&& rhs, const allocator_type& a);                   // C++20
 
     // [stringbuf.assign] Assign and swap:
     basic_stringbuf& operator=(basic_stringbuf&& rhs);
     void swap(basic_stringbuf& rhs) noexcept(see below);                               // conditionally noexcept since C++20
 
     // [stringbuf.members] Member functions:
-    basic_string<char_type, traits_type, allocator_type> str() const;
+    allocator_type get_allocator() const noexcept;                                     // C++20
+    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
+    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
+    template <class SAlloc>
+    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
+    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
+    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
     void str(const basic_string<char_type, traits_type, allocator_type>& s);
-    basic_string_view<char_type, traits_type> view() const noexcept; // C++20
+    template <class SAlloc>
+    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
+    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
 
 protected:
     // [stringbuf.virtuals] Overridden virtual functions:
@@ -229,6 +252,8 @@ private:
     string_type __str_;
     mutable char_type* __hm_;
     ios_base::openmode __mode_;
+    _LIBCPP_HIDE_FROM_ABI void __init_buf_ptrs();
+    _LIBCPP_HIDE_FROM_ABI void __move_init(basic_stringbuf&& __rhs);
 
 public:
     // [stringbuf.cons] constructors:
@@ -248,7 +273,48 @@ public:
         str(__s);
     }
 
-    basic_stringbuf(basic_stringbuf&& __rhs);
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const allocator_type& __a)
+        : basic_stringbuf(ios_base::in | ios_base::out, __a) {}
+
+    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(ios_base::openmode __wch, const allocator_type& __a)
+        : __str_(__a), __hm_(nullptr), __mode_(__wch) {}
+
+    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(string_type&& __s,
+                                                   ios_base::openmode __wch = ios_base::in | ios_base::out)
+        : __str_(std::move(__s)), __hm_(nullptr), __mode_(__wch) {
+        __init_buf_ptrs();
+    }
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI
+    basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s, const allocator_type& __a)
+        : basic_stringbuf(__s, ios_base::in | ios_base::out, __a) {}
+
+    template <class _SAlloc>
+    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(
+        const basic_string<char_type, traits_type, _SAlloc>& __s, ios_base::openmode __wch, const allocator_type& __a)
+        : __str_(__s, __a), __hm_(nullptr), __mode_(__wch) {
+        __init_buf_ptrs();
+    }
+
+    template <class _SAlloc>
+      requires (!is_same_v<_SAlloc, allocator_type>)
+    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s,
+                                                   ios_base::openmode __wch = ios_base::in | ios_base::out)
+        : __str_(__s), __hm_(nullptr), __mode_(__wch) {
+        __init_buf_ptrs();
+    }
+#endif // _LIBCPP_STD_VER >= 20
+
+    basic_stringbuf(basic_stringbuf&& __rhs) : __mode_(__rhs.__mode_) { __move_init(std::move(__rhs)); }
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
+        : basic_stringbuf(__rhs.__mode_, __a) {
+        __move_init(std::move(__rhs));
+    }
+#endif
 
     // [stringbuf.assign] Assign and swap:
     basic_stringbuf& operator=(basic_stringbuf&& __rhs);
@@ -260,13 +326,54 @@ public:
         ;
 
     // [stringbuf.members] Member functions:
+
+#if _LIBCPP_STD_VER >= 20
+    _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
+#endif
+
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
     string_type str() const;
-    void str(const string_type& __s);
+#else
+    _LIBCPP_HIDE_FROM_ABI string_type str() const & { return str(__str_.get_allocator()); }
+
+    template <class _SAlloc>
+      requires __is_allocator<_SAlloc>::value
+    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+        return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa);
+    }
+
+    _LIBCPP_HIDE_FROM_ABI string_type str() && {
+        const basic_string_view<_CharT, _Traits> __view = view();
+        string_type __result(std::move(__str_), __view.data() - __str_.data(), __view.size());
+        __str_.clear();
+        __init_buf_ptrs();
+        return __result;
+    }
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
+
 #if _LIBCPP_STD_VER >= 20
-    _LIBCPP_HIDE_FROM_ABI
-    basic_string_view<char_type, traits_type> view() const noexcept;
+    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
 #endif
 
+    void str(const string_type& __s) {
+        __str_ = __s;
+        __init_buf_ptrs();
+    }
+
+#if _LIBCPP_STD_VER >= 20
+    template <class _SAlloc>
+      requires (!is_same_v<_SAlloc, allocator_type>)
+    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
+        __str_ = __s;
+        __init_buf_ptrs();
+    }
+
+    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) {
+        __str_ = std::move(__s);
+        __init_buf_ptrs();
+    }
+#endif // _LIBCPP_STD_VER >= 20
+
 protected:
     // [stringbuf.virtuals] Overridden virtual functions:
     int_type underflow() override;
@@ -282,9 +389,7 @@ protected:
 };
 
 template <class _CharT, class _Traits, class _Allocator>
-basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& __rhs)
-    : __mode_(__rhs.__mode_)
-{
+_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__move_init(basic_stringbuf&& __rhs) {
     char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
     ptr
diff _t __binp = -1;
     ptr
diff _t __ninp = -1;
@@ -463,49 +568,35 @@ swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
     __x.swap(__y);
 }
 
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>
-basic_stringbuf<_CharT, _Traits, _Allocator>::str() const
-{
-#if _LIBCPP_STD_VER >= 20
-    return string_type(view(), __str_.get_allocator());
-#else // _LIBCPP_STD_VER >= 20
-    if (__mode_ & ios_base::out)
-    {
+basic_stringbuf<_CharT, _Traits, _Allocator>::str() const {
+    if (__mode_ & ios_base::out) {
         if (__hm_ < this->pptr())
             __hm_ = this->pptr();
         return string_type(this->pbase(), __hm_, __str_.get_allocator());
-    }
-    else if (__mode_ & ios_base::in)
+    } else if (__mode_ & ios_base::in)
         return string_type(this->eback(), this->egptr(), __str_.get_allocator());
     return string_type(__str_.get_allocator());
-#endif // _LIBCPP_STD_VER >= 20
 }
+#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
 
 template <class _CharT, class _Traits, class _Allocator>
-void
-basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
-{
-    __str_ = __s;
+_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__init_buf_ptrs() {
     __hm_ = nullptr;
-    if (__mode_ & ios_base::in)
-    {
-        __hm_ = const_cast<char_type*>(__str_.data()) + __str_.size();
-        this->setg(const_cast<char_type*>(__str_.data()),
-                   const_cast<char_type*>(__str_.data()),
-                   __hm_);
-    }
-    if (__mode_ & ios_base::out)
-    {
+    char_type* __data = const_cast<char_type*>(__str_.data());
         typename string_type::size_type __sz = __str_.size();
-        __hm_ = const_cast<char_type*>(__str_.data()) + __sz;
+    if (__mode_ & ios_base::in) {
+        __hm_ = __data + __sz;
+        this->setg(__data, __data, __hm_);
+    }
+    if (__mode_ & ios_base::out) {
+        __hm_ = __data + __sz;
         __str_.resize(__str_.capacity());
-        this->setp(const_cast<char_type*>(__str_.data()),
-                   const_cast<char_type*>(__str_.data()) + __str_.size());
-        if (__mode_ & (ios_base::app | ios_base::ate))
-        {
-            while (__sz > INT_MAX)
-            {
+        this->setp(__data, __data + __str_.size());
+        if (__mode_ & (ios_base::app | ios_base::ate)) {
+            while (__sz > INT_MAX) {
                 this->pbump(INT_MAX);
                 __sz -= INT_MAX;
             }

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/alloc.pass.cpp
new file mode 100644
index 00000000000000..4b08b5ae339eff
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/alloc.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
+// class basic_stringbuf
+
+// explicit basic_stringbuf(const Allocator& a)
+//     : basic_stringbuf(ios_base::in | ios_base::out, a) {}
+
+#include <sstream>
+#include <cassert>
+
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test() {
+  const test_allocator<CharT> a(1);
+  const std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf(a);
+  assert(buf.get_allocator() == a);
+  assert(buf.view().empty());
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/mode.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/mode.alloc.pass.cpp
new file mode 100644
index 00000000000000..43359a2b8c0567
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/mode.alloc.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
+// class basic_stringbuf
+
+// basic_stringbuf(ios_base::openmode which, const Allocator& a);
+
+#include <sstream>
+#include <cassert>
+
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class CharT>
+static void test() {
+  const test_allocator<CharT> a(2);
+  const std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf(std::ios_base::in, a);
+  assert(buf.get_allocator() == a);
+  assert(buf.view().empty());
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.alloc.pass.cpp
new file mode 100644
index 00000000000000..ac90d423373f3b
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.alloc.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
+// class basic_stringbuf
+
+// basic_stringbuf(basic_stringbuf&& rhs, const Allocator& a);
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test() {
+  std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf1(STR("testing"));
+  const test_allocator<CharT> a(2);
+  const std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf(std::move(buf1), a);
+  assert(buf.get_allocator() == a);
+  assert(buf.view() == SV("testing"));
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string-alloc.mode.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string-alloc.mode.pass.cpp
new file mode 100644
index 00000000000000..e8b202746219f1
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string-alloc.mode.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
+// class basic_stringbuf
+
+// template <class SAlloc>
+// explicit basic_stringbuf(const basic_string<charT, traits, SAlloc>& s,
+//                          ios_base::openmode which = ios_base::in | ios_base::out);
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test() {
+  const std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT>> s(STR("testing"));
+  const std::basic_stringbuf<CharT> buf(s, std::ios_base::in);
+  assert(buf.view() == SV("testing"));
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.alloc.pass.cpp
new file mode 100644
index 00000000000000..13aa7f0ed0e23a
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.alloc.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
+// class basic_stringbuf
+
+// template <class SAlloc>
+// basic_stringbuf(const basic_string<charT, traits, SAlloc>& s, const Allocator& a)
+//     : basic_stringbuf(s, ios_base::in | ios_base::out, a) {}
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test() {
+  const std::basic_string<CharT> s(STR("testing"));
+  const test_allocator<CharT> a(2);
+  const std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf(s, a);
+  assert(buf.get_allocator() == a);
+  assert(buf.view() == SV("testing"));
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.mode.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.mode.alloc.pass.cpp
new file mode 100644
index 00000000000000..1f95ef8db22bb2
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.mode.alloc.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
+// class basic_stringbuf
+
+// template <class SAlloc>
+// basic_stringbuf(const basic_string<charT, traits, SAlloc>& s, ios_base::openmode which, const Allocator& a);
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test() {
+  const std::basic_string<CharT> s(STR("testing"));
+  const test_allocator<CharT> a(2);
+  const std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf(s, std::ios_base::in, a);
+  assert(buf.get_allocator() == a);
+  assert(buf.view() == SV("testing"));
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.move.mode.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.move.mode.pass.cpp
new file mode 100644
index 00000000000000..ac5a46c4f3768c
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.move.mode.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
+// class basic_stringbuf
+
+// explicit basic_stringbuf(basic_string<charT, traits, Allocator>&& s, ios_base::openmode which = ios_base::in | ios_base::out);
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test() {
+  {
+    std::basic_string<CharT> s(STR("testing"));
+    const std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf(std::move(s));
+    assert(buf.view() == SV("testing"));
+  }
+  {
+    std::basic_string<CharT> s(STR("testing"));
+    const std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf(
+        std::move(s), std::ios_base::out);
+    assert(buf.view() == SV("testing"));
+  }
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.alloc.pass.cpp
new file mode 100644
index 00000000000000..e6407e3c3ca6fd
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.alloc.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+// class basic_stringbuf
+
+// template <class SAlloc>
+// basic_string<charT, traits, SAlloc> str(const SAlloc& sa) const;
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test() {
+  const std::basic_stringbuf<CharT> buf(STR("testing"));
+  const test_allocator<CharT> a(1);
+  const std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT>> s = buf.str(a);
+  assert(s == SV("testing"));
+  assert(s.get_allocator() == a);
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.move.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.move.pass.cpp
new file mode 100644
index 00000000000000..f0fa330b4b600f
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.move.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+// class basic_stringbuf
+
+// basic_string<charT, traits, Allocator> str() &&;
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+
+template <class CharT>
+static void test() {
+  {
+    std::basic_stringbuf<CharT> buf(STR("testing"));
+    std::basic_string<CharT> s = std::move(buf).str();
+    assert(s == STR("testing"));
+    assert(buf.view().empty());
+  }
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.string-alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.string-alloc.pass.cpp
new file mode 100644
index 00000000000000..f640a1342d6fd0
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.string-alloc.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+// class basic_stringbuf
+
+// template <class SAlloc>
+// void str(const basic_string<charT, traits, SAlloc>& s);
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test() {
+  {
+    const test_allocator<CharT> a(6);
+    const std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT>> s(STR("testing"), a);
+    std::basic_stringbuf<CharT> buf;
+    buf.str(s);
+    assert(buf.view() == SV("testing"));
+  }
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.string.move.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.string.move.pass.cpp
new file mode 100644
index 00000000000000..62c0287c13abae
--- /dev/null
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.string.move.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+// class basic_stringbuf
+
+// void str(basic_string<charT, traits, Allocator>&& s);
+
+#include <sstream>
+#include <cassert>
+
+#include "make_string.h"
+#include "test_macros.h"
+
+#define STR(S) MAKE_STRING(CharT, S)
+
+template <class CharT>
+static void test() {
+  {
+    std::basic_stringbuf<CharT> buf;
+    std::basic_string<CharT> s(STR("testing"));
+    buf.str(std::move(s));
+    assert(buf.str() == STR("testing"));
+  }
+}
+
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+  return 0;
+}


        


More information about the libcxx-commits mailing list