Skip to content

Commit d6a9261

Browse files
pfusikldionne
andcommitted
[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 <[email protected]>
1 parent ea9af5e commit d6a9261

File tree

4 files changed

+188
-62
lines changed

4 files changed

+188
-62
lines changed

libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.pass.cpp

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// UNSUPPORTED: c++03
10+
911
// <sstream>
1012

1113
// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
@@ -15,49 +17,75 @@
1517

1618
#include <sstream>
1719
#include <cassert>
20+
#include <utility>
1821

22+
#include "make_string.h"
1923
#include "test_macros.h"
2024

21-
int main(int, char**)
22-
{
23-
{
24-
std::stringbuf buf1("testing");
25-
std::stringbuf buf;
26-
buf = std::move(buf1);
27-
assert(buf.str() == "testing");
28-
}
25+
#define STR(S) MAKE_STRING(CharT, S)
26+
27+
template <class CharT>
28+
struct test_stringbuf : std::basic_stringbuf<CharT> {
29+
using std::basic_stringbuf<CharT>::basic_stringbuf;
30+
31+
// Checks the following requirement after being moved from:
32+
// The six pointers of std::basic_streambuf in *this are guaranteed to be different
33+
// from the corresponding pointers in the moved-from rhs unless null.
34+
void check_different_pointers(test_stringbuf<CharT> const& other) const {
35+
assert(this->eback() == nullptr || this->eback() != other.eback());
36+
assert(this->gptr() == nullptr || this->gptr() != other.gptr());
37+
assert(this->egptr() == nullptr || this->egptr() != other.egptr());
38+
assert(this->pbase() == nullptr || this->pbase() != other.pbase());
39+
assert(this->pptr() == nullptr || this->pptr() != other.pptr());
40+
assert(this->epptr() == nullptr || this->epptr() != other.epptr());
41+
}
42+
};
43+
44+
template <class CharT>
45+
void test() {
46+
std::basic_string<CharT> strings[] = {STR(""), STR("short"), STR("loooooooooooooooooooong")};
47+
for (std::basic_string<CharT> const& s : strings) {
2948
{
30-
std::stringbuf buf1("testing", std::ios_base::in);
31-
std::stringbuf buf;
32-
buf = std::move(buf1);
33-
assert(buf.str() == "testing");
49+
test_stringbuf<CharT> buf1(s);
50+
test_stringbuf<CharT> buf;
51+
buf = std::move(buf1);
52+
assert(buf.str() == s);
53+
buf.check_different_pointers(buf1);
3454
}
3555
{
36-
std::stringbuf buf1("testing", std::ios_base::out);
37-
std::stringbuf buf;
38-
buf = std::move(buf1);
39-
assert(buf.str() == "testing");
56+
test_stringbuf<CharT> buf1(s, std::ios_base::in);
57+
test_stringbuf<CharT> buf;
58+
buf = std::move(buf1);
59+
assert(buf.str() == s);
60+
buf.check_different_pointers(buf1);
4061
}
41-
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
4262
{
43-
std::wstringbuf buf1(L"testing");
44-
std::wstringbuf buf;
45-
buf = std::move(buf1);
46-
assert(buf.str() == L"testing");
63+
test_stringbuf<CharT> buf1(s, std::ios_base::out);
64+
test_stringbuf<CharT> buf;
65+
buf = std::move(buf1);
66+
assert(buf.str() == s);
67+
buf.check_different_pointers(buf1);
4768
}
4869
{
49-
std::wstringbuf buf1(L"testing", std::ios_base::in);
50-
std::wstringbuf buf;
51-
buf = std::move(buf1);
52-
assert(buf.str() == L"testing");
70+
test_stringbuf<CharT> buf1;
71+
test_stringbuf<CharT> buf;
72+
buf = std::move(buf1);
73+
buf.check_different_pointers(buf1);
5374
}
75+
// Use the assignment operator on an actual std::stringbuf, not test_stringbuf
5476
{
55-
std::wstringbuf buf1(L"testing", std::ios_base::out);
56-
std::wstringbuf buf;
57-
buf = std::move(buf1);
58-
assert(buf.str() == L"testing");
77+
std::basic_stringbuf<CharT> buf1(s);
78+
std::basic_stringbuf<CharT> buf;
79+
buf = std::move(buf1);
80+
assert(buf.str() == s);
5981
}
60-
#endif // TEST_HAS_NO_WIDE_CHARACTERS
82+
}
83+
}
6184

85+
int main(int, char**) {
86+
test<char>();
87+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
88+
test<wchar_t>();
89+
#endif
6290
return 0;
6391
}

libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.alloc.pass.cpp

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <sstream>
1919
#include <cassert>
20+
#include <utility>
2021

2122
#include "make_string.h"
2223
#include "test_allocator.h"
@@ -26,12 +27,73 @@
2627
#define SV(S) MAKE_STRING_VIEW(CharT, S)
2728

2829
template <class CharT>
29-
static void test() {
30-
std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf1(STR("testing"));
31-
const test_allocator<CharT> a(2);
32-
const std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> buf(std::move(buf1), a);
33-
assert(buf.get_allocator() == a);
34-
assert(buf.view() == SV("testing"));
30+
struct test_stringbuf : std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>> {
31+
using std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>>::basic_stringbuf;
32+
33+
// Checks the following requirement after being moved from:
34+
// The six pointers of std::basic_streambuf in *this are guaranteed to be different
35+
// from the corresponding pointers in the moved-from rhs unless null.
36+
void check_different_pointers(test_stringbuf<CharT> const& other) const {
37+
assert(this->eback() == nullptr || this->eback() != other.eback());
38+
assert(this->gptr() == nullptr || this->gptr() != other.gptr());
39+
assert(this->egptr() == nullptr || this->egptr() != other.egptr());
40+
assert(this->pbase() == nullptr || this->pbase() != other.pbase());
41+
assert(this->pptr() == nullptr || this->pptr() != other.pptr());
42+
assert(this->epptr() == nullptr || this->epptr() != other.epptr());
43+
}
44+
};
45+
46+
template <class CharT>
47+
void test() {
48+
std::basic_string<CharT> strings[] = {STR(""), STR("short"), STR("loooooooooooooooooooong")};
49+
for (std::basic_string<CharT> const& s : strings) {
50+
using StringBuf = std::basic_stringbuf<CharT, std::char_traits<CharT>, test_allocator<CharT>>;
51+
{
52+
test_stringbuf<CharT> buf1(s);
53+
const test_allocator<CharT> a(2);
54+
test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)), a);
55+
assert(buf.get_allocator() == a);
56+
assert(buf.view() == s);
57+
assert(buf1.view().empty());
58+
buf.check_different_pointers(buf1);
59+
}
60+
{
61+
test_stringbuf<CharT> buf1(s, std::ios_base::in);
62+
const test_allocator<CharT> a(2);
63+
test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)), a);
64+
assert(buf.get_allocator() == a);
65+
assert(buf.view() == s);
66+
assert(buf1.view().empty());
67+
buf.check_different_pointers(buf1);
68+
}
69+
{
70+
test_stringbuf<CharT> buf1(s, std::ios_base::out);
71+
const test_allocator<CharT> a(2);
72+
test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)), a);
73+
assert(buf.get_allocator() == a);
74+
assert(buf.view() == s);
75+
assert(buf1.view().empty());
76+
buf.check_different_pointers(buf1);
77+
}
78+
{
79+
test_stringbuf<CharT> buf1;
80+
const test_allocator<CharT> a(2);
81+
test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)), a);
82+
assert(buf.get_allocator() == a);
83+
assert(buf.view().empty());
84+
assert(buf1.view().empty());
85+
buf.check_different_pointers(buf1);
86+
}
87+
// Use the constructor from an actual std::stringbuf, not test_stringbuf
88+
{
89+
StringBuf buf1(s);
90+
const test_allocator<CharT> a(2);
91+
StringBuf buf(std::move(buf1), a);
92+
assert(buf.get_allocator() == a);
93+
assert(buf.view() == s);
94+
assert(buf1.view().empty());
95+
}
96+
}
3597
}
3698

3799
int main(int, char**) {

libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.pass.cpp

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// UNSUPPORTED: c++03
10+
911
// <sstream>
1012

1113
// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
@@ -15,43 +17,79 @@
1517

1618
#include <sstream>
1719
#include <cassert>
20+
#include <utility>
1821

22+
#include "make_string.h"
1923
#include "test_macros.h"
2024

21-
int main(int, char**)
22-
{
23-
{
24-
std::stringbuf buf1("testing");
25-
std::stringbuf buf(std::move(buf1));
26-
assert(buf.str() == "testing");
27-
}
25+
#define STR(S) MAKE_STRING(CharT, S)
26+
27+
template <class CharT>
28+
struct test_stringbuf : std::basic_stringbuf<CharT> {
29+
using std::basic_stringbuf<CharT>::basic_stringbuf;
30+
31+
test_stringbuf(std::basic_stringbuf<CharT>&& other) : std::basic_stringbuf<CharT>(std::move(other)) {}
32+
33+
// Checks the following requirement after being moved from:
34+
// The six pointers of std::basic_streambuf in *this are guaranteed to be different
35+
// from the corresponding pointers in the moved-from rhs unless null.
36+
void check_different_pointers(test_stringbuf<CharT> const& other) const {
37+
assert(this->eback() == nullptr || this->eback() != other.eback());
38+
assert(this->gptr() == nullptr || this->gptr() != other.gptr());
39+
assert(this->egptr() == nullptr || this->egptr() != other.egptr());
40+
assert(this->pbase() == nullptr || this->pbase() != other.pbase());
41+
assert(this->pptr() == nullptr || this->pptr() != other.pptr());
42+
assert(this->epptr() == nullptr || this->epptr() != other.epptr());
43+
}
44+
};
45+
46+
template <class CharT>
47+
void test() {
48+
std::basic_string<CharT> strings[] = {STR(""), STR("short"), STR("loooooooooooooooooooong")};
49+
for (std::basic_string<CharT> const& s : strings) {
50+
using StringBuf = std::basic_stringbuf<CharT>;
2851
{
29-
std::stringbuf buf1("testing", std::ios_base::in);
30-
std::stringbuf buf(std::move(buf1));
31-
assert(buf.str() == "testing");
52+
test_stringbuf<CharT> buf1(s);
53+
test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)));
54+
assert(buf.str() == s);
55+
assert(buf1.str().empty());
56+
buf.check_different_pointers(buf1);
3257
}
3358
{
34-
std::stringbuf buf1("testing", std::ios_base::out);
35-
std::stringbuf buf(std::move(buf1));
36-
assert(buf.str() == "testing");
59+
test_stringbuf<CharT> buf1(s, std::ios_base::in);
60+
test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)));
61+
assert(buf.str() == s);
62+
assert(buf1.str().empty());
63+
buf.check_different_pointers(buf1);
3764
}
38-
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
3965
{
40-
std::wstringbuf buf1(L"testing");
41-
std::wstringbuf buf(std::move(buf1));
42-
assert(buf.str() == L"testing");
66+
test_stringbuf<CharT> buf1(s, std::ios_base::out);
67+
test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)));
68+
assert(buf.str() == s);
69+
assert(buf1.str().empty());
70+
buf.check_different_pointers(buf1);
4371
}
4472
{
45-
std::wstringbuf buf1(L"testing", std::ios_base::in);
46-
std::wstringbuf buf(std::move(buf1));
47-
assert(buf.str() == L"testing");
73+
test_stringbuf<CharT> buf1;
74+
test_stringbuf<CharT> buf(std::move(static_cast<StringBuf&>(buf1)));
75+
assert(buf.str().empty());
76+
assert(buf1.str().empty());
77+
buf.check_different_pointers(buf1);
4878
}
79+
// Use the constructor from an actual std::stringbuf, not test_stringbuf
4980
{
50-
std::wstringbuf buf1(L"testing", std::ios_base::out);
51-
std::wstringbuf buf(std::move(buf1));
52-
assert(buf.str() == L"testing");
81+
StringBuf buf1(s);
82+
StringBuf buf(std::move(buf1));
83+
assert(buf.str() == s);
84+
assert(buf1.str().empty());
5385
}
54-
#endif
86+
}
87+
}
5588

89+
int main(int, char**) {
90+
test<char>();
91+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
92+
test<wchar_t>();
93+
#endif
5694
return 0;
5795
}

libcxx/utils/data/ignore_format.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3477,10 +3477,8 @@ libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.cons/str
34773477
libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/str.pass.cpp
34783478
libcxx/test/std/input.output/string.streams/ostringstream/types.pass.cpp
34793479
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/member_swap.pass.cpp
3480-
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/move.pass.cpp
34813480
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.assign/nonmember_swap.pass.cpp
34823481
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
3483-
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/move.pass.cpp
34843482
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string.pass.cpp
34853483
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.pass.cpp
34863484
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/overflow.pass.cpp

0 commit comments

Comments
 (0)