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