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//     in(stateT& state,
22//        const externT* from, const externT* from_end, const externT*& from_next,
23//        internT* to, internT* to_end, internT*& 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, 0x1000> C;
43    C c;
44    CharT w[2] = {0};
45    char n[4] = {char(0xF1), char(0x80), char(0x80), char(0x83)};
46    CharT* wp = nullptr;
47    std::mbstate_t m;
48    const char* np = nullptr;
49    std::codecvt_base::result r = c.in(m, n, n + 4, np, w, w + 2, wp);
50    assert(r == std::codecvt_base::error);
51    assert(wp == w);
52    assert(np == n);
53
54    n[0] = char(0xE1);
55    n[1] = char(0x80);
56    n[2] = char(0x85);
57    r = c.in(m, n, n + 3, np, w, w + 2, wp);
58    assert(r == std::codecvt_base::error);
59    assert(wp == w);
60    assert(np == n);
61
62    n[0] = char(0xD1);
63    n[1] = char(0x93);
64    r = c.in(m, n, n + 2, np, w, w + 2, wp);
65    assert(r == std::codecvt_base::ok);
66    assert(wp == w + 1);
67    assert(np == n + 2);
68    assert(w[0] == 0x0453);
69
70    n[0] = char(0x56);
71    r = c.in(m, n, n + 1, np, w, w + 2, wp);
72    assert(r == std::codecvt_base::ok);
73    assert(wp == w + 1);
74    assert(np == n + 1);
75    assert(w[0] == 0x0056);
76  }
77  {
78    typedef std::codecvt_utf8_utf16<CharT, 0x10ffff, std::consume_header> C;
79    C c;
80    CharT w[2] = {0};
81    char n[7] = {char(0xEF), char(0xBB), char(0xBF), char(0xF1),
82                 char(0x80), char(0x80), char(0x83)};
83    CharT* wp = nullptr;
84    std::mbstate_t m;
85    const char* np = nullptr;
86    std::codecvt_base::result r = c.in(m, n, n + 7, np, w, w + 2, wp);
87    assert(r == std::codecvt_base::ok);
88    assert(wp == w + 2);
89    assert(np == n + 7);
90    assert(w[0] == 0xD8C0);
91    assert(w[1] == 0xDC03);
92
93    n[0] = char(0xE1);
94    n[1] = char(0x80);
95    n[2] = char(0x85);
96    r = c.in(m, n, n + 3, np, w, w + 2, wp);
97    assert(r == std::codecvt_base::ok);
98    assert(wp == w + 1);
99    assert(np == n + 3);
100    assert(w[0] == 0x1005);
101
102    n[0] = char(0xD1);
103    n[1] = char(0x93);
104    r = c.in(m, n, n + 2, np, w, w + 2, wp);
105    assert(r == std::codecvt_base::ok);
106    assert(wp == w + 1);
107    assert(np == n + 2);
108    assert(w[0] == 0x0453);
109
110    n[0] = char(0x56);
111    r = c.in(m, n, n + 1, np, w, w + 2, wp);
112    assert(r == std::codecvt_base::ok);
113    assert(wp == w + 1);
114    assert(np == n + 1);
115    assert(w[0] == 0x0056);
116  }
117}
118
119template <class CharT>
120void TestHelper<CharT, 4>::test() {
121  {
122    typedef std::codecvt_utf8_utf16<CharT> C;
123    C c;
124    CharT w[2] = {0};
125    char n[4] = {char(0xF1), char(0x80), char(0x80), char(0x83)};
126    CharT* wp = nullptr;
127    std::mbstate_t m;
128    const char* np = nullptr;
129    std::codecvt_base::result r = c.in(m, n, n + 4, np, w, w + 2, wp);
130    assert(r == std::codecvt_base::ok);
131    assert(wp == w + 2);
132    assert(np == n + 4);
133    assert(w[0] == 0xD8C0);
134    assert(w[1] == 0xDC03);
135
136    n[0] = char(0xE1);
137    n[1] = char(0x80);
138    n[2] = char(0x85);
139    r = c.in(m, n, n + 3, np, w, w + 2, wp);
140    assert(r == std::codecvt_base::ok);
141    assert(wp == w + 1);
142    assert(np == n + 3);
143    assert(w[0] == 0x1005);
144
145    n[0] = char(0xD1);
146    n[1] = char(0x93);
147    r = c.in(m, n, n + 2, np, w, w + 2, wp);
148    assert(r == std::codecvt_base::ok);
149    assert(wp == w + 1);
150    assert(np == n + 2);
151    assert(w[0] == 0x0453);
152
153    n[0] = char(0x56);
154    r = c.in(m, n, n + 1, np, w, w + 2, wp);
155    assert(r == std::codecvt_base::ok);
156    assert(wp == w + 1);
157    assert(np == n + 1);
158    assert(w[0] == 0x0056);
159  }
160  {
161    typedef std::codecvt_utf8_utf16<CharT, 0x1000> C;
162    C c;
163    CharT w[2] = {0};
164    char n[4] = {char(0xF1), char(0x80), char(0x80), char(0x83)};
165    CharT* wp = nullptr;
166    std::mbstate_t m;
167    const char* np = nullptr;
168    std::codecvt_base::result r = c.in(m, n, n + 4, np, w, w + 2, wp);
169    assert(r == std::codecvt_base::error);
170    assert(wp == w);
171    assert(np == n);
172
173    n[0] = char(0xE1);
174    n[1] = char(0x80);
175    n[2] = char(0x85);
176    r = c.in(m, n, n + 3, np, w, w + 2, wp);
177    assert(r == std::codecvt_base::error);
178    assert(wp == w);
179    assert(np == n);
180
181    n[0] = char(0xD1);
182    n[1] = char(0x93);
183    r = c.in(m, n, n + 2, np, w, w + 2, wp);
184    assert(r == std::codecvt_base::ok);
185    assert(wp == w + 1);
186    assert(np == n + 2);
187    assert(w[0] == 0x0453);
188
189    n[0] = char(0x56);
190    r = c.in(m, n, n + 1, np, w, w + 2, wp);
191    assert(r == std::codecvt_base::ok);
192    assert(wp == w + 1);
193    assert(np == n + 1);
194    assert(w[0] == 0x0056);
195  }
196  {
197    typedef std::codecvt_utf8_utf16<CharT, 0x10ffff, std::consume_header> C;
198    C c;
199    CharT w[2] = {0};
200    char n[7] = {char(0xEF), char(0xBB), char(0xBF), char(0xF1),
201                 char(0x80), char(0x80), char(0x83)};
202    CharT* wp = nullptr;
203    std::mbstate_t m;
204    const char* np = nullptr;
205    std::codecvt_base::result r = c.in(m, n, n + 7, np, w, w + 2, wp);
206    assert(r == std::codecvt_base::ok);
207    assert(wp == w + 2);
208    assert(np == n + 7);
209    assert(w[0] == 0xD8C0);
210    assert(w[1] == 0xDC03);
211
212    n[0] = char(0xE1);
213    n[1] = char(0x80);
214    n[2] = char(0x85);
215    r = c.in(m, n, n + 3, np, w, w + 2, wp);
216    assert(r == std::codecvt_base::ok);
217    assert(wp == w + 1);
218    assert(np == n + 3);
219    assert(w[0] == 0x1005);
220
221    n[0] = char(0xD1);
222    n[1] = char(0x93);
223    r = c.in(m, n, n + 2, np, w, w + 2, wp);
224    assert(r == std::codecvt_base::ok);
225    assert(wp == w + 1);
226    assert(np == n + 2);
227    assert(w[0] == 0x0453);
228
229    n[0] = char(0x56);
230    r = c.in(m, n, n + 1, np, w, w + 2, wp);
231    assert(r == std::codecvt_base::ok);
232    assert(wp == w + 1);
233    assert(np == n + 1);
234    assert(w[0] == 0x0056);
235  }
236}
237
238int main() {
239#ifndef _WIN32
240  TestHelper<wchar_t>::test();
241#endif
242  TestHelper<char32_t>::test();
243  TestHelper<char16_t>::test();
244}
245