// File: alfanick[P]rest-cpp/src/rest/json.hpp
// Function: nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, bool, long, double, std::allocator>::lexer::to_unicode(unsigned long, unsigned long)
static string_t to_unicode(const std::size_t codepoint1,
                                   const std::size_t codepoint2 = 0)
        {
            string_t result;

            // calculate the codepoint from the given code points
            std::size_t codepoint = codepoint1;

            // check if codepoint1 is a high surrogate
            if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
            {
                // check if codepoint2 is a low surrogate
                if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
                {
                    codepoint =
                        // high surrogate occupies the most significant 22 bits
                        (codepoint1 << 10)
                        // low surrogate occupies the least significant 15 bits
                        + codepoint2
                        // there is still the 0xD800, 0xDC00 and 0x10000 noise
                        // in the result so we have to subtract with:
                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
                        - 0x35FDC00;
                }
                else
                {
                    throw std::invalid_argument("missing or wrong low surrogate");
                }
            }

            if (codepoint < 0x80)
            {
                // 1-byte characters: 0xxxxxxx (ASCII)
                result.append(1, static_cast<typename string_t::value_type>(codepoint));
            }
            else if (codepoint <= 0x7ff)
            {
                // 2-byte characters: 110xxxxx 10xxxxxx
                result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
            }
            else if (codepoint <= 0xffff)
            {
                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
                result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
            }
            else if (codepoint <= 0x10ffff)
            {
                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
                result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
                result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
                result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
            }
            else
            {
                throw std::out_of_range("code points above 0x10FFFF are invalid");
            }

            return result;
        }

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x10(%rsp)
movq %rdi, %rax
movq %rax, 0x18(%rsp)
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq %rdx, 0x40(%rsp)
movb $0x0, 0x3f(%rsp)
callq 0x959e0
movq 0x48(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0xd800, 0x48(%rsp)     # imm = 0xD800
jb 0xa1665
cmpq $0xdbff, 0x48(%rsp)     # imm = 0xDBFF
ja 0xa1665
cmpq $0xdc00, 0x40(%rsp)     # imm = 0xDC00
jb 0xa15f3
cmpq $0xdfff, 0x40(%rsp)     # imm = 0xDFFF
ja 0xa15f3
movq 0x48(%rsp), %rax
shlq $0xa, %rax
addq 0x40(%rsp), %rax
subq $0x35fdc00, %rax        # imm = 0x35FDC00
movq %rax, 0x30(%rsp)
jmp 0xa1663
movl $0x10, %edi
callq 0x8f970
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x8(%rsp)
leaq 0x43172(%rip), %rsi     # 0xe4781
callq 0x98eb0
jmp 0xa1616
movq 0x8(%rsp), %rdi
movq 0x64936(%rip), %rsi     # 0x105f58
movq 0x648cf(%rip), %rdx     # 0x105ef8
callq 0x97c60
jmp 0xa1894
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
callq 0x911a0
jmp 0xa1880
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
jmp 0xa1880
jmp 0xa1665
cmpq $0x80, 0x30(%rsp)
jae 0xa168b
movq 0x10(%rsp), %rdi
movsbl 0x30(%rsp), %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa1686
jmp 0xa1860
cmpq $0x7ff, 0x30(%rsp)      # imm = 0x7FF
ja 0xa16e2
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
movl $0x506, %ecx            # imm = 0x506
bextrl %ecx, %eax, %eax
orl $0xc0, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa16bd
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
andl $0x3f, %eax
orl $0x80, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa16dd
jmp 0xa185e
cmpq $0xffff, 0x30(%rsp)     # imm = 0xFFFF
ja 0xa1760
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
movl $0x40c, %ecx            # imm = 0x40C
bextrl %ecx, %eax, %eax
orl $0xe0, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa1714
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
movl $0x606, %ecx            # imm = 0x606
bextrl %ecx, %eax, %eax
orl $0x80, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa173b
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
andl $0x3f, %eax
orl $0x80, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa175b
jmp 0xa185c
cmpq $0x10ffff, 0x30(%rsp)   # imm = 0x10FFFF
ja 0xa1806
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
movl $0x312, %ecx            # imm = 0x312
bextrl %ecx, %eax, %eax
orl $0xf0, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa1796
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
movl $0x60c, %ecx            # imm = 0x60C
bextrl %ecx, %eax, %eax
orl $0x80, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa17bd
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
movl $0x606, %ecx            # imm = 0x606
bextrl %ecx, %eax, %eax
orl $0x80, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa17e4
movq 0x10(%rsp), %rdi
movl 0x30(%rsp), %eax
andl $0x3f, %eax
orl $0x80, %eax
movsbl %al, %edx
movl $0x1, %esi
callq 0x93880
jmp 0xa1804
jmp 0xa185a
movl $0x10, %edi
callq 0x8f970
movq %rax, %rdi
movq %rdi, %rax
movq %rax, (%rsp)
leaq 0x42f7f(%rip), %rsi     # 0xe47a0
callq 0x8d8f0
jmp 0xa1828
movq (%rsp), %rdi
movq 0x646f5(%rip), %rsi     # 0x105f28
movq 0x64636(%rip), %rdx     # 0x105e70
callq 0x97c60
jmp 0xa1894
movq (%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
callq 0x911a0
jmp 0xa1880
jmp 0xa185c
jmp 0xa185e
jmp 0xa1860
movb $0x1, 0x3f(%rsp)
testb $0x1, 0x3f(%rsp)
jne 0xa1876
movq 0x10(%rsp), %rdi
callq 0x99830
movq 0x18(%rsp), %rax
addq $0x58, %rsp
retq
movq 0x10(%rsp), %rdi
callq 0x99830
movq 0x28(%rsp), %rdi
callq 0x981c0
nopw %cs:(%rax,%rax)
nop