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