[libcxx-commits] [libcxx] d6a9261 - [libc++] Improve the tests for std::basic_stringbuf's constructors and assignment operators

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 18 20:26:02 PDT 2023


Author: Piotr Fusik
Date: 2023-10-18T20:25:42-07:00
New Revision: d6a92611ebb55bcca6231d2bdc5749eaecf349d6

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

LOG: [libc++] Improve the tests for std::basic_stringbuf's constructors and assignment operators

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

Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>

Added: 
    

Modified: 
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.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/move.pass.cpp
    libcxx/utils/data/ignore_format.txt

Removed: 
    


################################################################################
diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.pass.cpp
index 3ae562e17e803f0..e1c71829aa306ba 100644
--- a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.pass.cpp
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++03
+
 // <sstream>
 
 // template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
@@ -15,49 +17,75 @@
 
 #include <sstream>
 #include <cassert>
+#include <utility>
 
+#include "make_string.h"
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
-        std::stringbuf buf1("testing");
-        std::stringbuf buf;
-        buf = std::move(buf1);
-        assert(buf.str() == "testing");
-    }
+#define STR(S) MAKE_STRING(CharT, S)
+
+template <class CharT>
+struct test_stringbuf : std::basic_stringbuf<CharT> {
+  using std::basic_stringbuf<CharT>::basic_stringbuf;
+
+  // Checks the following requirement after being moved from:
+  //    The six pointers of std::basic_streambuf in *this are guaranteed to be 
diff erent
+  //    from the corresponding pointers in the moved-from rhs unless null.
+  void check_
diff erent_pointers(test_stringbuf<CharT> const& other) const {
+    assert(this->eback() == nullptr || this->eback() != other.eback());
+    assert(this->gptr() == nullptr || this->gptr() != other.gptr());
+    assert(this->egptr() == nullptr || this->egptr() != other.egptr());
+    assert(this->pbase() == nullptr || this->pbase() != other.pbase());
+    assert(this->pptr() == nullptr || this->pptr() != other.pptr());
+    assert(this->epptr() == nullptr || this->epptr() != other.epptr());
+  }
+};
+
+template <class CharT>
+void test() {
+  std::basic_string<CharT> strings[] = {STR(""), STR("short"), STR("loooooooooooooooooooong")};
+  for (std::basic_string<CharT> const& s : strings) {
     {
-        std::stringbuf buf1("testing", std::ios_base::in);
-        std::stringbuf buf;
-        buf = std::move(buf1);
-        assert(buf.str() == "testing");
+      test_stringbuf<CharT> buf1(s);
+      test_stringbuf<CharT> buf;
+      buf = std::move(buf1);
+      assert(buf.str() == s);
+      buf.check_
diff erent_pointers(buf1);
     }
     {
-        std::stringbuf buf1("testing", std::ios_base::out);
-        std::stringbuf buf;
-        buf = std::move(buf1);
-        assert(buf.str() == "testing");
+      test_stringbuf<CharT> buf1(s, std::ios_base::in);
+      test_stringbuf<CharT> buf;
+      buf = std::move(buf1);
+      assert(buf.str() == s);
+      buf.check_
diff erent_pointers(buf1);
     }
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
     {
-        std::wstringbuf buf1(L"testing");
-        std::wstringbuf buf;
-        buf = std::move(buf1);
-        assert(buf.str() == L"testing");
+      test_stringbuf<CharT> buf1(s, std::ios_base::out);
+      test_stringbuf<CharT> buf;
+      buf = std::move(buf1);
+      assert(buf.str() == s);
+      buf.check_
diff erent_pointers(buf1);
     }
     {
-        std::wstringbuf buf1(L"testing", std::ios_base::in);
-        std::wstringbuf buf;
-        buf = std::move(buf1);
-        assert(buf.str() == L"testing");
+      test_stringbuf<CharT> buf1;
+      test_stringbuf<CharT> buf;
+      buf = std::move(buf1);
+      buf.check_
diff erent_pointers(buf1);
     }
+    // Use the assignment operator on an actual std::stringbuf, not test_stringbuf
     {
-        std::wstringbuf buf1(L"testing", std::ios_base::out);
-        std::wstringbuf buf;
-        buf = std::move(buf1);
-        assert(buf.str() == L"testing");
+      std::basic_stringbuf<CharT> buf1(s);
+      std::basic_stringbuf<CharT> buf;
+      buf = std::move(buf1);
+      assert(buf.str() == s);
     }
-#endif // TEST_HAS_NO_WIDE_CHARACTERS
+  }
+}
 
+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
index ac90d423373f3b4..c652fa10127dc2a 100644
--- 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
@@ -17,6 +17,7 @@
 
 #include <sstream>
 #include <cassert>
+#include <utility>
 
 #include "make_string.h"
 #include "test_allocator.h"
@@ -26,12 +27,73 @@
 #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"));
+struct test_stringbuf : std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> {
+  using std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>>::basic_stringbuf;
+
+  // Checks the following requirement after being moved from:
+  //    The six pointers of std::basic_streambuf in *this are guaranteed to be 
diff erent
+  //    from the corresponding pointers in the moved-from rhs unless null.
+  void check_
diff erent_pointers(test_stringbuf<CharT> const& other) const {
+    assert(this->eback() == nullptr || this->eback() != other.eback());
+    assert(this->gptr() == nullptr || this->gptr() != other.gptr());
+    assert(this->egptr() == nullptr || this->egptr() != other.egptr());
+    assert(this->pbase() == nullptr || this->pbase() != other.pbase());
+    assert(this->pptr() == nullptr || this->pptr() != other.pptr());
+    assert(this->epptr() == nullptr || this->epptr() != other.epptr());
+  }
+};
+
+template <class CharT>
+void test() {
+  std::basic_string<CharT> strings[] = {STR(""), STR("short"), STR("loooooooooooooooooooong")};
+  for (std::basic_string<CharT> const& s : strings) {
+    using StringBuf = std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>>;
+    {
+      test_stringbuf<CharT> buf1(s);
+      const test_allocator<CharT> a(2);
+      test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)), a);
+      assert(buf.get_allocator() == a);
+      assert(buf.view() == s);
+      assert(buf1.view().empty());
+      buf.check_
diff erent_pointers(buf1);
+    }
+    {
+      test_stringbuf<CharT> buf1(s, std::ios_base::in);
+      const test_allocator<CharT> a(2);
+      test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)), a);
+      assert(buf.get_allocator() == a);
+      assert(buf.view() == s);
+      assert(buf1.view().empty());
+      buf.check_
diff erent_pointers(buf1);
+    }
+    {
+      test_stringbuf<CharT> buf1(s, std::ios_base::out);
+      const test_allocator<CharT> a(2);
+      test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)), a);
+      assert(buf.get_allocator() == a);
+      assert(buf.view() == s);
+      assert(buf1.view().empty());
+      buf.check_
diff erent_pointers(buf1);
+    }
+    {
+      test_stringbuf<CharT> buf1;
+      const test_allocator<CharT> a(2);
+      test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)), a);
+      assert(buf.get_allocator() == a);
+      assert(buf.view().empty());
+      assert(buf1.view().empty());
+      buf.check_
diff erent_pointers(buf1);
+    }
+    // Use the constructor from an actual std::stringbuf, not test_stringbuf
+    {
+      StringBuf buf1(s);
+      const test_allocator<CharT> a(2);
+      StringBuf buf(std::move(buf1), a);
+      assert(buf.get_allocator() == a);
+      assert(buf.view() == s);
+      assert(buf1.view().empty());
+    }
+  }
 }
 
 int main(int, char**) {

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.pass.cpp
index c4846c01d413f9e..65767a95ad8ff16 100644
--- a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++03
+
 // <sstream>
 
 // template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
@@ -15,43 +17,79 @@
 
 #include <sstream>
 #include <cassert>
+#include <utility>
 
+#include "make_string.h"
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
-        std::stringbuf buf1("testing");
-        std::stringbuf buf(std::move(buf1));
-        assert(buf.str() == "testing");
-    }
+#define STR(S) MAKE_STRING(CharT, S)
+
+template <class CharT>
+struct test_stringbuf : std::basic_stringbuf<CharT> {
+  using std::basic_stringbuf<CharT>::basic_stringbuf;
+
+  test_stringbuf(std::basic_stringbuf<CharT>&& other) : std::basic_stringbuf<CharT>(std::move(other)) {}
+
+  // Checks the following requirement after being moved from:
+  //    The six pointers of std::basic_streambuf in *this are guaranteed to be 
diff erent
+  //    from the corresponding pointers in the moved-from rhs unless null.
+  void check_
diff erent_pointers(test_stringbuf<CharT> const& other) const {
+    assert(this->eback() == nullptr || this->eback() != other.eback());
+    assert(this->gptr() == nullptr || this->gptr() != other.gptr());
+    assert(this->egptr() == nullptr || this->egptr() != other.egptr());
+    assert(this->pbase() == nullptr || this->pbase() != other.pbase());
+    assert(this->pptr() == nullptr || this->pptr() != other.pptr());
+    assert(this->epptr() == nullptr || this->epptr() != other.epptr());
+  }
+};
+
+template <class CharT>
+void test() {
+  std::basic_string<CharT> strings[] = {STR(""), STR("short"), STR("loooooooooooooooooooong")};
+  for (std::basic_string<CharT> const& s : strings) {
+    using StringBuf = std::basic_stringbuf<CharT>;
     {
-        std::stringbuf buf1("testing", std::ios_base::in);
-        std::stringbuf buf(std::move(buf1));
-        assert(buf.str() == "testing");
+      test_stringbuf<CharT> buf1(s);
+      test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)));
+      assert(buf.str() == s);
+      assert(buf1.str().empty());
+      buf.check_
diff erent_pointers(buf1);
     }
     {
-        std::stringbuf buf1("testing", std::ios_base::out);
-        std::stringbuf buf(std::move(buf1));
-        assert(buf.str() == "testing");
+      test_stringbuf<CharT> buf1(s, std::ios_base::in);
+      test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)));
+      assert(buf.str() == s);
+      assert(buf1.str().empty());
+      buf.check_
diff erent_pointers(buf1);
     }
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
     {
-        std::wstringbuf buf1(L"testing");
-        std::wstringbuf buf(std::move(buf1));
-        assert(buf.str() == L"testing");
+      test_stringbuf<CharT> buf1(s, std::ios_base::out);
+      test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)));
+      assert(buf.str() == s);
+      assert(buf1.str().empty());
+      buf.check_
diff erent_pointers(buf1);
     }
     {
-        std::wstringbuf buf1(L"testing", std::ios_base::in);
-        std::wstringbuf buf(std::move(buf1));
-        assert(buf.str() == L"testing");
+      test_stringbuf<CharT> buf1;
+      test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)));
+      assert(buf.str().empty());
+      assert(buf1.str().empty());
+      buf.check_
diff erent_pointers(buf1);
     }
+    // Use the constructor from an actual std::stringbuf, not test_stringbuf
     {
-        std::wstringbuf buf1(L"testing", std::ios_base::out);
-        std::wstringbuf buf(std::move(buf1));
-        assert(buf.str() == L"testing");
+      StringBuf buf1(s);
+      StringBuf buf(std::move(buf1));
+      assert(buf.str() == s);
+      assert(buf1.str().empty());
     }
-#endif
+  }
+}
 
+int main(int, char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
   return 0;
 }

diff  --git a/libcxx/utils/data/ignore_format.txt b/libcxx/utils/data/ignore_format.txt
index 8a415c1610d452c..82b1bc920d1db56 100644
--- a/libcxx/utils/data/ignore_format.txt
+++ b/libcxx/utils/data/ignore_format.txt
@@ -3477,10 +3477,8 @@ libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.cons/str
 libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/str.pass.cpp
 libcxx/test/std/input.output/string.streams/ostringstream/types.pass.cpp
 libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/member_swap.pass.cpp
-libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.pass.cpp
 libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/nonmember_swap.pass.cpp
 libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
-libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.pass.cpp
 libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.pass.cpp
 libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.pass.cpp
 libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/overflow.pass.cpp


        


More information about the libcxx-commits mailing list