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_utf8_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  {
42    typedef std::codecvt_utf8_utf16<CharT> C;
43    C c;
44    CharT w[2] = {0xD8C0, 0xDC03};
45    char n[4] = {0};
46    const CharT* wp = nullptr;
47    std::mbstate_t m;
48    char* np = nullptr;
49    std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 4, np);
50    assert(r == std::codecvt_base::ok);
51    assert(wp == w + 2);
52    assert(np == n + 4);
53    assert(n[0] == char(0xF1));
54    assert(n[1] == char(0x80));
55    assert(n[2] == char(0x80));
56    assert(n[3] == char(0x83));
57
58    w[0] = 0x1005;
59    r = c.out(m, w, w + 1, wp, n, n + 4, np);
60    assert(r == std::codecvt_base::ok);
61    assert(wp == w + 1);
62    assert(np == n + 3);
63    assert(n[0] == char(0xE1));
64    assert(n[1] == char(0x80));
65    assert(n[2] == char(0x85));
66
67    w[0] = 0x453;
68    r = c.out(m, w, w + 1, wp, n, n + 4, np);
69    assert(r == std::codecvt_base::ok);
70    assert(wp == w + 1);
71    assert(np == n + 2);
72    assert(n[0] == char(0xD1));
73    assert(n[1] == char(0x93));
74
75    w[0] = 0x56;
76    r = c.out(m, w, w + 1, wp, n, n + 4, np);
77    assert(r == std::codecvt_base::ok);
78    assert(wp == w + 1);
79    assert(np == n + 1);
80    assert(n[0] == char(0x56));
81  }
82  {
83    typedef std::codecvt_utf8_utf16<CharT, 0x1000> C;
84    C c;
85    CharT w[2] = {0xD8C0, 0xDC03};
86    char n[4] = {0};
87    const CharT* wp = nullptr;
88    std::mbstate_t m;
89    char* np = nullptr;
90    std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 4, np);
91    assert(r == std::codecvt_base::error);
92    assert(wp == w);
93    assert(np == n);
94
95    w[0] = 0x1005;
96    r = c.out(m, w, w + 1, wp, n, n + 4, np);
97    assert(r == std::codecvt_base::error);
98    assert(wp == w);
99    assert(np == n);
100
101    w[0] = 0x453;
102    r = c.out(m, w, w + 1, wp, n, n + 4, np);
103    assert(r == std::codecvt_base::ok);
104    assert(wp == w + 1);
105    assert(np == n + 2);
106    assert(n[0] == char(0xD1));
107    assert(n[1] == char(0x93));
108
109    w[0] = 0x56;
110    r = c.out(m, w, w + 1, wp, n, n + 4, np);
111    assert(r == std::codecvt_base::ok);
112    assert(wp == w + 1);
113    assert(np == n + 1);
114    assert(n[0] == char(0x56));
115  }
116  {
117    typedef std::codecvt_utf8_utf16<CharT, 0x10ffff, std::generate_header> C;
118    C c;
119    CharT w[2] = {0xD8C0, 0xDC03};
120    char n[7] = {0};
121    const CharT* wp = nullptr;
122    std::mbstate_t m;
123    char* np = nullptr;
124    std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 7, np);
125    assert(r == std::codecvt_base::ok);
126    assert(wp == w + 2);
127    assert(np == n + 7);
128    assert(n[0] == char(0xEF));
129    assert(n[1] == char(0xBB));
130    assert(n[2] == char(0xBF));
131    assert(n[3] == char(0xF1));
132    assert(n[4] == char(0x80));
133    assert(n[5] == char(0x80));
134    assert(n[6] == char(0x83));
135
136    w[0] = 0x1005;
137    r = c.out(m, w, w + 1, wp, n, n + 7, np);
138    assert(r == std::codecvt_base::ok);
139    assert(wp == w + 1);
140    assert(np == n + 6);
141    assert(n[0] == char(0xEF));
142    assert(n[1] == char(0xBB));
143    assert(n[2] == char(0xBF));
144    assert(n[3] == char(0xE1));
145    assert(n[4] == char(0x80));
146    assert(n[5] == char(0x85));
147
148    w[0] = 0x453;
149    r = c.out(m, w, w + 1, wp, n, n + 7, np);
150    assert(r == std::codecvt_base::ok);
151    assert(wp == w + 1);
152    assert(np == n + 5);
153    assert(n[0] == char(0xEF));
154    assert(n[1] == char(0xBB));
155    assert(n[2] == char(0xBF));
156    assert(n[3] == char(0xD1));
157    assert(n[4] == char(0x93));
158
159    w[0] = 0x56;
160    r = c.out(m, w, w + 1, wp, n, n + 7, np);
161    assert(r == std::codecvt_base::ok);
162    assert(wp == w + 1);
163    assert(np == n + 4);
164    assert(n[0] == char(0xEF));
165    assert(n[1] == char(0xBB));
166    assert(n[2] == char(0xBF));
167    assert(n[3] == char(0x56));
168  }
169}
170
171template <class CharT>
172void TestHelper<CharT, 4>::test() {
173  {
174    typedef std::codecvt_utf8_utf16<CharT> C;
175    C c;
176    CharT w[2] = {0xD8C0, 0xDC03};
177    char n[4] = {0};
178    const CharT* wp = nullptr;
179    std::mbstate_t m;
180    char* np = nullptr;
181    std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 4, np);
182    assert(r == std::codecvt_base::ok);
183    assert(wp == w + 2);
184    assert(np == n + 4);
185    assert(n[0] == char(0xF1));
186    assert(n[1] == char(0x80));
187    assert(n[2] == char(0x80));
188    assert(n[3] == char(0x83));
189
190    w[0] = 0x1005;
191    r = c.out(m, w, w + 1, wp, n, n + 4, np);
192    assert(r == std::codecvt_base::ok);
193    assert(wp == w + 1);
194    assert(np == n + 3);
195    assert(n[0] == char(0xE1));
196    assert(n[1] == char(0x80));
197    assert(n[2] == char(0x85));
198
199    w[0] = 0x453;
200    r = c.out(m, w, w + 1, wp, n, n + 4, np);
201    assert(r == std::codecvt_base::ok);
202    assert(wp == w + 1);
203    assert(np == n + 2);
204    assert(n[0] == char(0xD1));
205    assert(n[1] == char(0x93));
206
207    w[0] = 0x56;
208    r = c.out(m, w, w + 1, wp, n, n + 4, np);
209    assert(r == std::codecvt_base::ok);
210    assert(wp == w + 1);
211    assert(np == n + 1);
212    assert(n[0] == char(0x56));
213  }
214  {
215    typedef std::codecvt_utf8_utf16<CharT, 0x1000> C;
216    C c;
217    CharT w[2] = {0xD8C0, 0xDC03};
218    char n[4] = {0};
219    const CharT* wp = nullptr;
220    std::mbstate_t m;
221    char* np = nullptr;
222    std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 4, np);
223    assert(r == std::codecvt_base::error);
224    assert(wp == w);
225    assert(np == n);
226
227    w[0] = 0x1005;
228    r = c.out(m, w, w + 1, wp, n, n + 4, np);
229    assert(r == std::codecvt_base::error);
230    assert(wp == w);
231    assert(np == n);
232
233    w[0] = 0x453;
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[0] == char(0xD1));
239    assert(n[1] == char(0x93));
240
241    w[0] = 0x56;
242    r = c.out(m, w, w + 1, wp, n, n + 4, np);
243    assert(r == std::codecvt_base::ok);
244    assert(wp == w + 1);
245    assert(np == n + 1);
246    assert(n[0] == char(0x56));
247  }
248  {
249    typedef std::codecvt_utf8_utf16<CharT, 0x10ffff, std::generate_header> C;
250    C c;
251    CharT w[2] = {0xD8C0, 0xDC03};
252    char n[7] = {0};
253    const CharT* wp = nullptr;
254    std::mbstate_t m;
255    char* np = nullptr;
256    std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 7, np);
257    assert(r == std::codecvt_base::ok);
258    assert(wp == w + 2);
259    assert(np == n + 7);
260    assert(n[0] == char(0xEF));
261    assert(n[1] == char(0xBB));
262    assert(n[2] == char(0xBF));
263    assert(n[3] == char(0xF1));
264    assert(n[4] == char(0x80));
265    assert(n[5] == char(0x80));
266    assert(n[6] == char(0x83));
267
268    w[0] = 0x1005;
269    r = c.out(m, w, w + 1, wp, n, n + 7, np);
270    assert(r == std::codecvt_base::ok);
271    assert(wp == w + 1);
272    assert(np == n + 6);
273    assert(n[0] == char(0xEF));
274    assert(n[1] == char(0xBB));
275    assert(n[2] == char(0xBF));
276    assert(n[3] == char(0xE1));
277    assert(n[4] == char(0x80));
278    assert(n[5] == char(0x85));
279
280    w[0] = 0x453;
281    r = c.out(m, w, w + 1, wp, n, n + 7, np);
282    assert(r == std::codecvt_base::ok);
283    assert(wp == w + 1);
284    assert(np == n + 5);
285    assert(n[0] == char(0xEF));
286    assert(n[1] == char(0xBB));
287    assert(n[2] == char(0xBF));
288    assert(n[3] == char(0xD1));
289    assert(n[4] == char(0x93));
290
291    w[0] = 0x56;
292    r = c.out(m, w, w + 1, wp, n, n + 7, np);
293    assert(r == std::codecvt_base::ok);
294    assert(wp == w + 1);
295    assert(np == n + 4);
296    assert(n[0] == char(0xEF));
297    assert(n[1] == char(0xBB));
298    assert(n[2] == char(0xBF));
299    assert(n[3] == char(0x56));
300  }
301}
302
303int main() {
304#ifndef _WIN32
305  TestHelper<wchar_t>::test();
306#endif
307  TestHelper<char32_t>::test();
308  TestHelper<char16_t>::test();
309}
310