1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10
11 // <sstream>
12
13 // template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
14 // class basic_stringbuf
15
16 // basic_stringbuf(basic_stringbuf&& rhs, const Allocator& a);
17
18 #include <sstream>
19 #include <cassert>
20 #include <utility>
21
22 #include "make_string.h"
23 #include "test_allocator.h"
24 #include "test_macros.h"
25
26 #define STR(S) MAKE_STRING(CharT, S)
27 #define SV(S) MAKE_STRING_VIEW(CharT, S)
28
29 template <class CharT>
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.
check_different_pointerstest_stringbuf36 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>
test()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 }
97 }
98
main(int,char **)99 int main(int, char**) {
100 test<char>();
101 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
102 test<wchar_t>();
103 #endif
104 return 0;
105 }
106