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 // <codecvt>
10
11 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
12
13 // template <class Elem, unsigned long Maxcode = 0x10ffff,
14 // codecvt_mode Mode = (codecvt_mode)0>
15 // class codecvt_utf16
16 // : public codecvt<Elem, char, mbstate_t>
17 // {
18 // // unspecified
19 // };
20
21 // result
22 // out(stateT& state,
23 // const internT* from, const internT* from_end, const internT*& from_next,
24 // externT* to, externT* to_end, externT*& to_next) const;
25
26 #include <codecvt>
27 #include <cassert>
28
29 #include "test_macros.h"
30
31 template <class CharT, std::size_t = sizeof(CharT)>
32 struct TestHelper;
33 template <class CharT>
34 struct TestHelper<CharT, 2> {
35 static void test();
36 };
37 template <class CharT>
38 struct TestHelper<CharT, 4> {
39 static void test();
40 };
41
42 template <class CharT>
test()43 void TestHelper<CharT, 2>::test() {
44 // Nothing to do, the conversion in unsupported
45 }
46
47 template <class CharT>
test()48 void TestHelper<CharT, 4>::test() {
49 {
50 typedef std::codecvt_utf16<CharT> C;
51 C c;
52 CharT w = 0x40003;
53 char n[4] = {0};
54 const CharT* wp = nullptr;
55 std::mbstate_t m;
56 char* np = nullptr;
57 std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
58 assert(r == std::codecvt_base::ok);
59 assert(wp == &w + 1);
60 assert(np == n + 4);
61 assert(n[0] == char(0xD8));
62 assert(n[1] == char(0xC0));
63 assert(n[2] == char(0xDC));
64 assert(n[3] == char(0x03));
65
66 w = 0x1005;
67 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
68 assert(r == std::codecvt_base::ok);
69 assert(wp == &w + 1);
70 assert(np == n + 2);
71 assert(n[0] == char(0x10));
72 assert(n[1] == char(0x05));
73 assert(n[2] == char(0xDC));
74 assert(n[3] == char(0x03));
75
76 w = 0x453;
77 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
78 assert(r == std::codecvt_base::ok);
79 assert(wp == &w + 1);
80 assert(np == n + 2);
81 assert(n[0] == char(0x04));
82 assert(n[1] == char(0x53));
83 assert(n[2] == char(0xDC));
84 assert(n[3] == char(0x03));
85
86 w = 0x56;
87 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
88 assert(r == std::codecvt_base::ok);
89 assert(wp == &w + 1);
90 assert(np == n + 2);
91 assert(n[0] == char(0x00));
92 assert(n[1] == char(0x56));
93 assert(n[2] == char(0xDC));
94 assert(n[3] == char(0x03));
95 }
96 {
97 typedef std::codecvt_utf16<CharT, 0x1000> C;
98 C c;
99 CharT w = 0x40003;
100 char n[4] = {0};
101 const CharT* wp = nullptr;
102 std::mbstate_t m;
103 char* np = nullptr;
104 std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
105 assert(r == std::codecvt_base::error);
106 assert(wp == &w);
107 assert(np == n);
108 assert(n[0] == char(0));
109 assert(n[1] == char(0));
110 assert(n[2] == char(0));
111 assert(n[3] == char(0));
112
113 w = 0x1005;
114 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
115 assert(r == std::codecvt_base::error);
116 assert(wp == &w);
117 assert(np == n);
118 assert(n[0] == char(0));
119 assert(n[1] == char(0));
120 assert(n[2] == char(0));
121 assert(n[3] == char(0));
122
123 w = 0x453;
124 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
125 assert(r == std::codecvt_base::ok);
126 assert(wp == &w + 1);
127 assert(np == n + 2);
128 assert(n[0] == char(0x04));
129 assert(n[1] == char(0x53));
130 assert(n[2] == char(0));
131 assert(n[3] == char(0));
132
133 w = 0x56;
134 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
135 assert(r == std::codecvt_base::ok);
136 assert(wp == &w + 1);
137 assert(np == n + 2);
138 assert(n[0] == char(0x00));
139 assert(n[1] == char(0x56));
140 assert(n[2] == char(0));
141 assert(n[3] == char(0));
142 }
143 {
144 typedef std::codecvt_utf16<CharT, 0x10ffff, std::generate_header> C;
145 C c;
146 CharT w = 0x40003;
147 char n[6] = {0};
148 const CharT* wp = nullptr;
149 std::mbstate_t m;
150 char* np = nullptr;
151 std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 6, np);
152 assert(r == std::codecvt_base::ok);
153 assert(wp == &w + 1);
154 assert(np == n + 6);
155 assert(n[0] == char(0xFE));
156 assert(n[1] == char(0xFF));
157 assert(n[2] == char(0xD8));
158 assert(n[3] == char(0xC0));
159 assert(n[4] == char(0xDC));
160 assert(n[5] == char(0x03));
161
162 w = 0x1005;
163 r = c.out(m, &w, &w + 1, wp, n, n + 6, np);
164 assert(r == std::codecvt_base::ok);
165 assert(wp == &w + 1);
166 assert(np == n + 4);
167 assert(n[0] == char(0xFE));
168 assert(n[1] == char(0xFF));
169 assert(n[2] == char(0x10));
170 assert(n[3] == char(0x05));
171 assert(n[4] == char(0xDC));
172 assert(n[5] == char(0x03));
173
174 w = 0x453;
175 r = c.out(m, &w, &w + 1, wp, n, n + 6, np);
176 assert(r == std::codecvt_base::ok);
177 assert(wp == &w + 1);
178 assert(np == n + 4);
179 assert(n[0] == char(0xFE));
180 assert(n[1] == char(0xFF));
181 assert(n[2] == char(0x04));
182 assert(n[3] == char(0x53));
183 assert(n[4] == char(0xDC));
184 assert(n[5] == char(0x03));
185
186 w = 0x56;
187 r = c.out(m, &w, &w + 1, wp, n, n + 6, np);
188 assert(r == std::codecvt_base::ok);
189 assert(wp == &w + 1);
190 assert(np == n + 4);
191 assert(n[0] == char(0xFE));
192 assert(n[1] == char(0xFF));
193 assert(n[2] == char(0x00));
194 assert(n[3] == char(0x56));
195 assert(n[4] == char(0xDC));
196 assert(n[5] == char(0x03));
197 }
198
199 {
200 typedef std::codecvt_utf16<CharT, 0x10FFFF, std::little_endian> C;
201 C c;
202 CharT w = 0x40003;
203 char n[4] = {0};
204 const CharT* wp = nullptr;
205 std::mbstate_t m;
206 char* np = nullptr;
207 std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
208 assert(r == std::codecvt_base::ok);
209 assert(wp == &w + 1);
210 assert(np == n + 4);
211 assert(n[1] == char(0xD8));
212 assert(n[0] == char(0xC0));
213 assert(n[3] == char(0xDC));
214 assert(n[2] == char(0x03));
215
216 w = 0x1005;
217 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
218 assert(r == std::codecvt_base::ok);
219 assert(wp == &w + 1);
220 assert(np == n + 2);
221 assert(n[1] == char(0x10));
222 assert(n[0] == char(0x05));
223 assert(n[3] == char(0xDC));
224 assert(n[2] == char(0x03));
225
226 w = 0x453;
227 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
228 assert(r == std::codecvt_base::ok);
229 assert(wp == &w + 1);
230 assert(np == n + 2);
231 assert(n[1] == char(0x04));
232 assert(n[0] == char(0x53));
233 assert(n[3] == char(0xDC));
234 assert(n[2] == char(0x03));
235
236 w = 0x56;
237 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
238 assert(r == std::codecvt_base::ok);
239 assert(wp == &w + 1);
240 assert(np == n + 2);
241 assert(n[1] == char(0x00));
242 assert(n[0] == char(0x56));
243 assert(n[3] == char(0xDC));
244 assert(n[2] == char(0x03));
245 }
246 {
247 typedef std::codecvt_utf16<CharT, 0x1000, std::little_endian> C;
248 C c;
249 CharT w = 0x40003;
250 char n[4] = {0};
251 const CharT* wp = nullptr;
252 std::mbstate_t m;
253 char* np = nullptr;
254 std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
255 assert(r == std::codecvt_base::error);
256 assert(wp == &w);
257 assert(np == n);
258 assert(n[1] == char(0));
259 assert(n[0] == char(0));
260 assert(n[3] == char(0));
261 assert(n[2] == char(0));
262
263 w = 0x1005;
264 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
265 assert(r == std::codecvt_base::error);
266 assert(wp == &w);
267 assert(np == n);
268 assert(n[1] == char(0));
269 assert(n[0] == char(0));
270 assert(n[3] == char(0));
271 assert(n[2] == char(0));
272
273 w = 0x453;
274 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
275 assert(r == std::codecvt_base::ok);
276 assert(wp == &w + 1);
277 assert(np == n + 2);
278 assert(n[1] == char(0x04));
279 assert(n[0] == char(0x53));
280 assert(n[3] == char(0));
281 assert(n[2] == char(0));
282
283 w = 0x56;
284 r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
285 assert(r == std::codecvt_base::ok);
286 assert(wp == &w + 1);
287 assert(np == n + 2);
288 assert(n[1] == char(0x00));
289 assert(n[0] == char(0x56));
290 assert(n[3] == char(0));
291 assert(n[2] == char(0));
292 }
293 {
294 typedef std::codecvt_utf16<CharT, 0x10ffff,
295 std::codecvt_mode(std::generate_header |
296 std::little_endian)>
297 C;
298 C c;
299 CharT w = 0x40003;
300 char n[6] = {0};
301 const CharT* wp = nullptr;
302 std::mbstate_t m;
303 char* np = nullptr;
304 std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 6, np);
305 assert(r == std::codecvt_base::ok);
306 assert(wp == &w + 1);
307 assert(np == n + 6);
308 assert(n[1] == char(0xFE));
309 assert(n[0] == char(0xFF));
310 assert(n[3] == char(0xD8));
311 assert(n[2] == char(0xC0));
312 assert(n[5] == char(0xDC));
313 assert(n[4] == char(0x03));
314
315 w = 0x1005;
316 r = c.out(m, &w, &w + 1, wp, n, n + 6, np);
317 assert(r == std::codecvt_base::ok);
318 assert(wp == &w + 1);
319 assert(np == n + 4);
320 assert(n[1] == char(0xFE));
321 assert(n[0] == char(0xFF));
322 assert(n[3] == char(0x10));
323 assert(n[2] == char(0x05));
324 assert(n[5] == char(0xDC));
325 assert(n[4] == char(0x03));
326
327 w = 0x453;
328 r = c.out(m, &w, &w + 1, wp, n, n + 6, np);
329 assert(r == std::codecvt_base::ok);
330 assert(wp == &w + 1);
331 assert(np == n + 4);
332 assert(n[1] == char(0xFE));
333 assert(n[0] == char(0xFF));
334 assert(n[3] == char(0x04));
335 assert(n[2] == char(0x53));
336 assert(n[5] == char(0xDC));
337 assert(n[4] == char(0x03));
338
339 w = 0x56;
340 r = c.out(m, &w, &w + 1, wp, n, n + 6, np);
341 assert(r == std::codecvt_base::ok);
342 assert(wp == &w + 1);
343 assert(np == n + 4);
344 assert(n[1] == char(0xFE));
345 assert(n[0] == char(0xFF));
346 assert(n[3] == char(0x00));
347 assert(n[2] == char(0x56));
348 assert(n[5] == char(0xDC));
349 assert(n[4] == char(0x03));
350 }
351 }
352
main(int,char **)353 int main(int, char**) {
354 TestHelper<char32_t>::test();
355 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
356 TestHelper<wchar_t>::test();
357 #endif
358
359 return 0;
360 }
361