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