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