]> 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-2021 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-options "-std=gnu++2a" }
21 // { dg-do run { target c++2a } }
22 // { dg-require-effective-target cxx11-abi }
23
24 #include <sstream>
25 #include <string>
26 #include <testsuite_allocator.h>
27 #include <testsuite_hooks.h>
28
29 template<typename Alloc, typename C = typename Alloc::value_type>
30 using stringbuf_with_alloc
31 = std::basic_stringbuf<C, std::char_traits<C>, Alloc>;
32
33 void
34 test01()
35 {
36 // Test C++20 constructors taking an allocator but no string.
37
38 static_assert(!std::is_convertible_v<std::allocator<wchar_t>, std::wstringbuf>,
39 "wstringbuf(const allocator<wchar_t>&) is explicit");
40
41 {
42 using alloc_type = __gnu_test::uneq_allocator<wchar_t>;
43 using sbuf_t = stringbuf_with_alloc<alloc_type>;
44
45 static_assert(!std::is_convertible_v<const alloc_type&, sbuf_t>,
46 "basic_stringbuf(const basic_stringbuf::allocator_type&) is explicit");
47
48 alloc_type aa;
49 sbuf_t sbuf1(aa);
50 VERIFY( aa == sbuf1.get_allocator() );
51
52 alloc_type aaa(42);
53 sbuf_t sbuf2(aaa);
54 VERIFY( aaa == sbuf2.get_allocator() );
55
56 VERIFY( sbuf1.get_allocator() != sbuf2.get_allocator() );
57 }
58
59 std::wstringbuf::allocator_type a;
60 {
61 std::wstringbuf sbuf(std::ios_base::in, a);
62 VERIFY( sbuf.str().empty() );
63
64 std::wstringbuf sbuf2 = {std::ios_base::in, a}; // non-explicit ctor
65 }
66
67 {
68 std::wstringbuf sbuf(a);
69 VERIFY( sbuf.str().empty() );
70 }
71 }
72
73 auto const cstr = L"This is a test string";
74
75 void
76 test02()
77 {
78 // Test C++20 constructor taking an rvalue string
79
80 static_assert(!std::is_convertible_v<std::wstring, std::wstringbuf>,
81 "wstringbuf(wstring&&, ios::openmode) is explicit");
82
83 std::wstring s1(cstr);
84 std::wstringbuf sbuf1(std::move(s1));
85 VERIFY( s1.empty() );
86 VERIFY( sbuf1.str() == cstr );
87 VERIFY( sbuf1.sgetc() == cstr[0] );
88
89 std::wstring s2(cstr);
90 std::wstringbuf sbuf2(std::move(s2), std::ios_base::in);
91 VERIFY( s2.empty() );
92 VERIFY( sbuf2.str() == cstr );
93 VERIFY( sbuf2.sgetc() == cstr[0] );
94 VERIFY( sbuf2.sputc(L'X') == std::wstringbuf::traits_type::eof() );
95
96 std::wstring s3(cstr);
97 std::wstringbuf sbuf3(std::move(s3), std::ios_base::out);
98 VERIFY( s3.empty() );
99 VERIFY( sbuf3.str() == cstr );
100 VERIFY( sbuf3.sputc(L'Y') == L'Y' );
101 VERIFY( sbuf3.sgetc() == std::wstringbuf::traits_type::eof() );
102 }
103
104 // A minimal allocator with no default constructor
105 template<typename T>
106 struct NoDefaultCons : __gnu_test::SimpleAllocator<T>
107 {
108 using __gnu_test::SimpleAllocator<T>::SimpleAllocator;
109
110 NoDefaultCons() = delete;
111
112 NoDefaultCons(int) { }
113 };
114
115 void
116 test03()
117 {
118 // Test C++20 constructors taking strings using different allocators
119
120 using alloc_type = __gnu_test::tracker_allocator<wchar_t>;
121 using str_type = std::basic_string<wchar_t, std::char_traits<wchar_t>, alloc_type>;
122
123 auto const mode = std::ios_base::in | std::ios_base::out;
124 str_type s1(cstr);
125
126 {
127 // basic_stringbuf(const basic_string<wchar_t, traits_type, SAlloc>&,
128 // ios_base::openmode,
129 // const allocator_type&)
130
131 std::wstringbuf::allocator_type a;
132 std::wstringbuf sbuf = {s1, mode, a}; // ={} checks for non-explicit ctor
133 std::wstring s2(cstr);
134 VERIFY( sbuf.str() == s2 );
135
136 std::wstringbuf sbuf2 = {std::move(s1), std::ios::in, a};
137 VERIFY( sbuf2.str() == s2 );
138 VERIFY( s1 == cstr ); // did not move from std::move(s1)
139 VERIFY( sbuf2.sgetc() == s1[0] );
140 VERIFY( sbuf2.sputc(L'X') == std::wstringbuf::traits_type::eof() );
141
142 std::wstringbuf sbuf3 = {std::move(s1), std::ios::out, a};
143 VERIFY( sbuf3.str() == s2 );
144 VERIFY( s1 == cstr ); // did not move from std::move(s1)
145 VERIFY( sbuf3.sputc(L'X') == L'X' );
146 VERIFY( sbuf3.sgetc() == std::wstringbuf::traits_type::eof() );
147 }
148
149 {
150 // explicit
151 // basic_stringbuf(const basic_string<wchar_t, traits_type, SAlloc>&,
152 // ios_base::openmode)
153
154 std::wstringbuf sbuf(s1, mode);
155 std::wstring s2(cstr);
156 VERIFY( sbuf.str() == s2 );
157
158 std::wstringbuf sbuf2(std::move(s1), std::ios::in);
159 VERIFY( sbuf2.str() == s2 );
160 VERIFY( s1 == cstr ); // did not move from std::move(s1)
161 VERIFY( sbuf2.sgetc() == s1[0] );
162 VERIFY( sbuf2.sputc(L'X') == std::wstringbuf::traits_type::eof() );
163
164 std::wstringbuf sbuf3(std::move(s1), std::ios::out);
165 VERIFY( sbuf3.str() == s2 );
166 VERIFY( s1 == cstr ); // did not move from std::move(s1)
167 VERIFY( sbuf3.sputc(L'X') == L'X' );
168 VERIFY( sbuf3.sgetc() == std::wstringbuf::traits_type::eof() );
169 }
170
171 {
172 // explicit
173 // basic_stringbuf(const basic_string<wchar_t, traits_type, SAlloc>&,
174 // ios_base::openmode = ios_base::in|ios_base::out)
175
176 static_assert( ! std::is_convertible_v<str_type, std::wstringbuf>,
177 "wstringbuf(const basic_string<wchar_t, traits_type, SAlloc>&,"
178 " openmode) is explicit");
179
180 std::wstringbuf sbuf(s1);
181 std::wstring s2(cstr);
182 VERIFY( sbuf.str() == s2 );
183
184 std::wstringbuf sbuf2(std::move(s1));
185 VERIFY( sbuf2.str() == s2 );
186 VERIFY( s1 == cstr ); // did not move from std::move(s1)
187 VERIFY( sbuf2.sgetc() == s1[0] );
188 }
189
190 {
191 NoDefaultCons<wchar_t> a(1);
192 stringbuf_with_alloc<NoDefaultCons<wchar_t>> sbuf1(s1, a);
193 VERIFY( sbuf1.str() == cstr );
194 VERIFY( sbuf1.sgetc() == s1[0] );
195
196 stringbuf_with_alloc<NoDefaultCons<wchar_t>> sbuf2(s1, std::ios::in, a);
197 VERIFY( sbuf2.str() == cstr );
198 VERIFY( sbuf2.sgetc() == s1[0] );
199 VERIFY( sbuf2.sputc(L'X') == std::wstringbuf::traits_type::eof() );
200
201 stringbuf_with_alloc<NoDefaultCons<wchar_t>> sbuf3(s1, std::ios::out, a);
202 VERIFY( sbuf3.str() == cstr );
203 VERIFY( sbuf3.sputc(L'X') == L'X' );
204 VERIFY( sbuf3.sgetc() == std::wstringbuf::traits_type::eof() );
205 }
206 }
207
208 void
209 test04()
210 {
211 // Test C++20 allocator-extended move constructor
212
213 std::wstringbuf sbuf1(cstr);
214
215 std::wstringbuf::allocator_type a;
216 std::wstringbuf sbuf2(std::move(sbuf1), a);
217 VERIFY( sbuf1.str().empty() );
218
219 std::wstring s(cstr);
220 VERIFY( sbuf2.str() == s );
221 }
222
223 int
224 main()
225 {
226 test01();
227 test02();
228 test03();
229 test04();
230 }