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 // <locale>
11 
12 // template <> class codecvt<char32_t, char, mbstate_t>
13 // template <> class codecvt<char16_t, char, mbstate_t>
14 // template <> class codecvt<char32_t, char16_t, mbstate_t>  // extension
15 
16 // sanity check
17 
18 #include <locale>
19 #include <codecvt>
20 #include <cassert>
21 
22 #include <stdio.h>
23 
main()24 int main()
25 {
26     typedef std::codecvt<char32_t, char, std::mbstate_t> F32_8;
27     typedef std::codecvt<char16_t, char, std::mbstate_t> F16_8;
28     typedef std::codecvt_utf16<char32_t> F32_16;
29     std::locale l = std::locale(std::locale::classic(), new F32_16);
30     const F32_8& f32_8 = std::use_facet<F32_8>(std::locale::classic());
31     const F32_16& f32_16 = std::use_facet<F32_16>(l);
32     const F16_8& f16_8 = std::use_facet<F16_8>(std::locale::classic());
33     std::mbstate_t mbs = {0};
34     F32_8::intern_type* c32p;
35     F16_8::intern_type* c16p;
36     F32_8::extern_type* c8p;
37     const F32_8::intern_type* c_c32p;
38     const F16_8::intern_type* c_c16p;
39     const F32_8::extern_type* c_c8p;
40     F32_8::intern_type c32;
41     F16_8::intern_type c16[2];
42     char c16c[4];
43     char* c16cp;
44     F32_8::extern_type c8[4];
45     for (F32_8::intern_type c32x = 0; c32x < 0x110003; ++c32x)
46     {
47         if ((0xD800 <= c32x && c32x < 0xE000) || c32x >= 0x110000)
48         {
49             assert(f32_16.out(mbs, &c32x, &c32x+1, c_c32p, c16c+0, c16c+4, c16cp) == F32_8::error);
50             assert(f32_8.out(mbs, &c32x, &c32x+1, c_c32p, c8, c8+4, c8p) == F32_8::error);
51         }
52         else
53         {
54             assert(f32_16.out(mbs, &c32x, &c32x+1, c_c32p, c16c, c16c+4, c16cp) == F32_8::ok);
55             assert(c_c32p-&c32x == 1);
56             if (c32x < 0x10000)
57                 assert(c16cp-c16c == 2);
58             else
59                 assert(c16cp-c16c == 4);
60             for (int i = 0; i < (c16cp - c16c) / 2; ++i)
61                 c16[i] = (unsigned char)c16c[2*i] << 8 | (unsigned char)c16c[2*i+1];
62             c_c16p = c16 + (c16cp - c16c) / 2;
63             assert(f16_8.out(mbs, c16, c_c16p, c_c16p, c8, c8+4, c8p) == F32_8::ok);
64             if (c32x < 0x10000)
65                 assert(c_c16p-c16 == 1);
66             else
67                 assert(c_c16p-c16 == 2);
68             if (c32x < 0x80)
69                 assert(c8p-c8 == 1);
70             else if (c32x < 0x800)
71                 assert(c8p-c8 == 2);
72             else if (c32x < 0x10000)
73                 assert(c8p-c8 == 3);
74             else
75                 assert(c8p-c8 == 4);
76             c_c8p = c8p;
77             assert(f32_8.in(mbs, c8, c_c8p, c_c8p, &c32, &c32+1, c32p) == F32_8::ok);
78             if (c32x < 0x80)
79                 assert(c_c8p-c8 == 1);
80             else if (c32x < 0x800)
81                 assert(c_c8p-c8 == 2);
82             else if (c32x < 0x10000)
83                 assert(c_c8p-c8 == 3);
84             else
85                 assert(c_c8p-c8 == 4);
86             assert(c32p-&c32 == 1);
87             assert(c32 == c32x);
88             assert(f32_8.out(mbs, &c32x, &c32x+1, c_c32p, c8, c8+4, c8p) == F32_8::ok);
89             assert(c_c32p-&c32x == 1);
90             if (c32x < 0x80)
91                 assert(c8p-c8 == 1);
92             else if (c32x < 0x800)
93                 assert(c8p-c8 == 2);
94             else if (c32x < 0x10000)
95                 assert(c8p-c8 == 3);
96             else
97                 assert(c8p-c8 == 4);
98             c_c8p = c8p;
99             assert(f16_8.in(mbs, c8, c_c8p, c_c8p, c16, c16+2, c16p) == F32_8::ok);
100             if (c32x < 0x80)
101                 assert(c_c8p-c8 == 1);
102             else if (c32x < 0x800)
103                 assert(c_c8p-c8 == 2);
104             else if (c32x < 0x10000)
105                 assert(c_c8p-c8 == 3);
106             else
107                 assert(c_c8p-c8 == 4);
108             if (c32x < 0x10000)
109                 assert(c16p-c16 == 1);
110             else
111                 assert(c16p-c16 == 2);
112             for (int i = 0; i < c16p-c16; ++i)
113             {
114                 c16c[2*i] = static_cast<char>(c16[i] >> 8);
115                 c16c[2*i+1] = static_cast<char>(c16[i]);
116             }
117             const char* c_c16cp = c16c + (c16p-c16)*2;
118             assert(f32_16.in(mbs, c16c, c_c16cp, c_c16cp, &c32, &c32+1, c32p) == F32_8::ok);
119             if (c32x < 0x10000)
120                 assert(c_c16cp-c16c == 2);
121             else
122                 assert(c_c16cp-c16c == 4);
123             assert(c32p-&c32 == 1);
124             assert(c32 == c32x);
125         }
126     }
127 }
128