// File: oknenavin[P]cxon/test/../src/cxon/lang/common/cio/char.hxx
// Function: std::enable_if<is_char_8<char>::value, int>::type cxon::cio::chr::utf32_to_utf8<char>(char (&) [4], char32_t)
inline auto utf32_to_utf8(T (&t)[4], char32_t c32) noexcept
            -> enable_if_t<is_char_8<T>::value, int>
        {
            static constexpr unsigned long const ms[] = { 0xBFUL, 0x00UL, 0xC0UL, 0xE0UL, 0xF0UL, 0xF8UL, 0xFCUL };
                if (c32 >= 0xD800UL && c32 <= 0xDBFFUL) return 0; // surrogate
            int const bs = c32 >= 0x80UL ? c32 >= 0x800UL ? c32 >= 0x10000UL ? c32 >= 0x110000UL ? 0 : 4 : 3 : 2 : 1;
                switch (bs) {
                    case 4: t[3] = (T)((c32 | 0x80UL) & 0xBFUL); c32 >>= 6; CXON_FALLTHROUGH;
                    case 3: t[2] = (T)((c32 | 0x80UL) & 0xBFUL); c32 >>= 6; CXON_FALLTHROUGH;
                    case 2: t[1] = (T)((c32 | 0x80UL) & 0xBFUL); c32 >>= 6; CXON_FALLTHROUGH;
                    case 1: t[0] = (T)( c32 | ms[bs]          );
                }
            return bs;
            //if (c32 < 0x80)  // 0XXX XXXX
            //    return t[0] = char(c32), 1;
            //if (c32 < 0x800) { // 110XXXXX
            //    t[0] = char(0xC0 | (c32 >> 6));
            //    t[1] = char(0x80 | (0x3F & c32));
            //    return 2;
            //}
            //if (c32 < 0x10000) { // 1110XXXX
            //    // error: 0xFFFE || 0xFFFF // not a char?
            //        if (c32 >= 0xD800 && c32 <= 0xDBFF) return 0;
            //    t[0] = char(0xE0 | (c32 >> 12));
            //    t[1] = char(0x80 | (0x3F & (c32 >> 6)));
            //    t[2] = char(0x80 | (0x3F & c32));
            //    return 3;
            //}
            //if (c32 < 0x110000) { // 11110XXX
            //    t[0] = char(0xF0 | (c32 >> 18));
            //    t[1] = char(0x80 | (0x3F & (c32 >> 12)));
            //    t[2] = char(0x80 | (0x3F & (c32 >> 6)));
            //    t[3] = char(0x80 | (0x3F & c32));
            //    return 4;
            //}
            //return 0;
        }

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpq $0xd800, %rax           # imm = 0xD800
jb 0x1558d
movl -0x14(%rbp), %eax
cmpq $0xdbff, %rax           # imm = 0xDBFF
ja 0x1558d
movl $0x0, -0x4(%rbp)
jmp 0x156a8
movl -0x14(%rbp), %eax
cmpq $0x80, %rax
jb 0x155ed
movl -0x14(%rbp), %eax
cmpq $0x800, %rax            # imm = 0x800
jb 0x155db
movl -0x14(%rbp), %eax
cmpq $0x10000, %rax          # imm = 0x10000
jb 0x155c9
movl -0x14(%rbp), %eax
movl %eax, %edx
movl $0x4, %eax
xorl %ecx, %ecx
cmpq $0x110000, %rdx         # imm = 0x110000
cmovael %ecx, %eax
movl %eax, -0x1c(%rbp)
jmp 0x155d3
movl $0x3, %eax
movl %eax, -0x1c(%rbp)
jmp 0x155d3
movl -0x1c(%rbp), %eax
movl %eax, -0x20(%rbp)
jmp 0x155e5
movl $0x2, %eax
movl %eax, -0x20(%rbp)
jmp 0x155e5
movl -0x20(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x155f7
movl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x155f7
movl -0x24(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x30(%rbp)
subl $0x3, %eax
ja 0x156a2
movq -0x30(%rbp), %rax
leaq 0xabbec(%rip), %rcx     # 0xc1208
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl -0x14(%rbp), %eax
orq $0x80, %rax
andq $0xbf, %rax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x3(%rax)
movl -0x14(%rbp), %eax
shrl $0x6, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
orq $0x80, %rax
andq $0xbf, %rax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x2(%rax)
movl -0x14(%rbp), %eax
shrl $0x6, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
orq $0x80, %rax
andq $0xbf, %rax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x1(%rax)
movl -0x14(%rbp), %eax
shrl $0x6, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
movslq -0x18(%rbp), %rdx
leaq 0xadc6a(%rip), %rcx     # 0xc3300
orq (%rcx,%rdx,8), %rax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, (%rax)
movl -0x18(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
popq %rbp
retq
nopl (%rax)