]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/2.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 27_io / basic_stringbuf / cons / wchar_t / 2.cc
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // C++20 29.8.2.2 basic_stringbuf constructors [stringbuf.cons]
19
20 // { dg-do run { target c++20 } }
21 // { dg-require-effective-target cxx11_abi }
22
23 #include <sstream>
24 #include <string>
25 #include <testsuite_allocator.h>
26 #include <testsuite_hooks.h>
27
28 template<typename Alloc, typename C = typename Alloc::value_type>
29 using stringbuf_with_alloc
30 = std::basic_stringbuf<C, std::char_traits<C>, Alloc>;
31
32 void
33 test01()
34 {
35 // Test C++20 constructors taking an allocator but no string.
36
37 static_assert(!std::is_convertible_v<std::allocator<wchar_t>, std::wstringbuf>,
38 "wstringbuf(const allocator<wchar_t>&) is explicit");
39
40 {
41 using alloc_type = __gnu_test::uneq_allocator<wchar_t>;
42 using sbuf_t = stringbuf_with_alloc<alloc_type>;
43
44 static_assert(!std::is_convertible_v<const alloc_type&, sbuf_t>,
45 "basic_stringbuf(const basic_stringbuf::allocator_type&) is explicit");
46
47 alloc_type aa;
48 sbuf_t sbuf1(aa);
49 VERIFY( aa == sbuf1.get_allocator() );
50
51 alloc_type aaa(42);
52 sbuf_t sbuf2(aaa);
53 VERIFY( aaa == sbuf2.get_allocator() );
54
55 VERIFY( sbuf1.get_allocator() != sbuf2.get_allocator() );
56 }
57
58 std::wstringbuf::allocator_type a;
59 {
60 std::wstringbuf sbuf(std::ios_base::in, a);
61 VERIFY( sbuf.str().empty() );
62
63 std::wstringbuf sbuf2 = {std::ios_base::in, a}; // non-explicit ctor
64 }
65
66 {
67 std::wstringbuf sbuf(a);
68 VERIFY( sbuf.str().empty() );
69 }
70 }
71
72 auto const cstr = L"This is a test string";
73
74 void
75 test02()
76 {
77 // Test C++20 constructor taking an rvalue string
78
79 static_assert(!std::is_convertible_v<std::wstring, std::wstringbuf>,
80 "wstringbuf(wstring&&, ios::openmode) is explicit");
81
82 std::wstring s1(cstr);
83 std::wstringbuf sbuf1(std::move(s1));
84 VERIFY( s1.empty() );
85 VERIFY( sbuf1.str() == cstr );
86 VERIFY( sbuf1.sgetc() == cstr[0] );
87
88 std::wstring s2(cstr);
89 std::wstringbuf sbuf2(std::move(s2), std::ios_base::in);
90 VERIFY( s2.empty() );
91 VERIFY( sbuf2.str() == cstr );
92 VERIFY( sbuf2.sgetc() == cstr[0] );
93 VERIFY( sbuf2.sputc(L'X') == std::wstringbuf::traits_type::eof() );
94
95 std::wstring s3(cstr);
96 std::wstringbuf sbuf3(std::move(s3), std::ios_base::out);
97 VERIFY( s3.empty() );
98 VERIFY( sbuf3.str() == cstr );
99 VERIFY( sbuf3.sputc(L'Y') == L'Y' );
100 VERIFY( sbuf3.sgetc() == std::wstringbuf::traits_type::eof() );
101 }
102
103 // A minimal allocator with no default constructor
104 template<typename T>
105 struct NoDefaultCons : __gnu_test::SimpleAllocator<T>
106 {
107 using __gnu_test::SimpleAllocator<T>::SimpleAllocator;
108
109 NoDefaultCons() = delete;
110
111 NoDefaultCons(int) { }
112 };
113
114 void
115 test03()
116 {
117 // Test C++20 constructors taking strings using different allocators
118
119 using alloc_type = __gnu_test::tracker_allocator<wchar_t>;
120 using str_type = std::basic_string<wchar_t, std::char_traits<wchar_t>, alloc_type>;
121
122 auto const mode = std::ios_base::in | std::ios_base::out;
123 str_type s1(cstr);
124
125 {
126 // basic_stringbuf(const basic_string<wchar_t, traits_type, SAlloc>&,
127 // ios_base::openmode,
128 // const allocator_type&)
129
130 std::wstringbuf::allocator_type a;
131 std::wstringbuf sbuf = {s1, mode, a}; // ={} checks for non-explicit ctor
132 std::wstring s2(cstr);
133 VERIFY( sbuf.str() == s2 );
134
135 std::wstringbuf sbuf2 = {std::move(s1), std::ios::in, a};
136 VERIFY( sbuf2.str() == s2 );
137 VERIFY( s1 == cstr ); // did not move from std::move(s1)
138 VERIFY( sbuf2.sgetc() == s1[0] );
139 VERIFY( sbuf2.sputc(L'X') == std::wstringbuf::traits_type::eof() );
140
141 std::wstringbuf sbuf3 = {std::move(s1), std::ios::out, a};
142 VERIFY( sbuf3.str() == s2 );
143 VERIFY( s1 == cstr ); // did not move from std::move(s1)
144 VERIFY( sbuf3.sputc(L'X') == L'X' );
145 VERIFY( sbuf3.sgetc() == std::wstringbuf::traits_type::eof() );
146 }
147
148 {
149 // explicit
150 // basic_stringbuf(const basic_string<wchar_t, traits_type, SAlloc>&,
151 // ios_base::openmode)
152
153 std::wstringbuf sbuf(s1, mode);
154 std::wstring s2(cstr);
155 VERIFY( sbuf.str() == s2 );
156
157 std::wstringbuf sbuf2(std::move(s1), std::ios::in);
158 VERIFY( sbuf2.str() == s2 );
159 VERIFY( s1 == cstr ); // did not move from std::move(s1)
160 VERIFY( sbuf2.sgetc() == s1[0] );
161 VERIFY( sbuf2.sputc(L'X') == std::wstringbuf::traits_type::eof() );
162
163 std::wstringbuf sbuf3(std::move(s1), std::ios::out);
164 VERIFY( sbuf3.str() == s2 );
165 VERIFY( s1 == cstr ); // did not move from std::move(s1)
166 VERIFY( sbuf3.sputc(L'X') == L'X' );
167 VERIFY( sbuf3.sgetc() == std::wstringbuf::traits_type::eof() );
168 }
169
170 {
171 // explicit
172 // basic_stringbuf(const basic_string<wchar_t, traits_type, SAlloc>&,
173 // ios_base::openmode = ios_base::in|ios_base::out)
174
175 static_assert( ! std::is_convertible_v<str_type, std::wstringbuf>,
176 "wstringbuf(const basic_string<wchar_t, traits_type, SAlloc>&,"
177 " openmode) is explicit");
178
179 std::wstringbuf sbuf(s1);
180 std::wstring s2(cstr);
181 VERIFY( sbuf.str() == s2 );
182
183 std::wstringbuf sbuf2(std::move(s1));
184 VERIFY( sbuf2.str() == s2 );
185 VERIFY( s1 == cstr ); // did not move from std::move(s1)
186 VERIFY( sbuf2.sgetc() == s1[0] );
187 }
188
189 {
190 NoDefaultCons<wchar_t> a(1);
191 stringbuf_with_alloc<NoDefaultCons<wchar_t>> sbuf1(s1, a);
192 VERIFY( sbuf1.str() == cstr );
193 VERIFY( sbuf1.sgetc() == s1[0] );
194
195 stringbuf_with_alloc<NoDefaultCons<wchar_t>> sbuf2(s1, std::ios::in, a);
196 VERIFY( sbuf2.str() == cstr );
197 VERIFY( sbuf2.sgetc() == s1[0] );
198 VERIFY( sbuf2.sputc(L'X') == std::wstringbuf::traits_type::eof() );
199
200 stringbuf_with_alloc<NoDefaultCons<wchar_t>> sbuf3(s1, std::ios::out, a);
201 VERIFY( sbuf3.str() == cstr );
202 VERIFY( sbuf3.sputc(L'X') == L'X' );
203 VERIFY( sbuf3.sgetc() == std::wstringbuf::traits_type::eof() );
204 }
205 }
206
207 void
208 test04()
209 {
210 // Test C++20 allocator-extended move constructor
211
212 std::wstringbuf sbuf1(cstr);
213
214 std::wstringbuf::allocator_type a;
215 std::wstringbuf sbuf2(std::move(sbuf1), a);
216 VERIFY( sbuf1.str().empty() );
217
218 std::wstring s(cstr);
219 VERIFY( sbuf2.str() == s );
220 }
221
222 int
223 main()
224 {
225 test01();
226 test02();
227 test03();
228 test04();
229 }