utf_sanity_check.pass.cpp revision a5a0ba86c8420a8407c23f2ac7665bc1ac5f597e
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
24int 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