! @brief get codepoint from 4 hex characters following `\u` For input "\u c1 c2 c3 c4" the codepoint is: (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The conversion is done
| 5646 | non-hex character) |
| 5647 | */ |
| 5648 | int get_codepoint() |
| 5649 | { |
| 5650 | // this function only makes sense after reading `\u` |
| 5651 | assert(current == 'u'); |
| 5652 | int codepoint = 0; |
| 5653 | |
| 5654 | const auto factors = { 12u, 8u, 4u, 0u }; |
| 5655 | for (const auto factor : factors) |
| 5656 | { |
| 5657 | get(); |
| 5658 | |
| 5659 | if (current >= '0' and current <= '9') |
| 5660 | { |
| 5661 | codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor); |
| 5662 | } |
| 5663 | else if (current >= 'A' and current <= 'F') |
| 5664 | { |
| 5665 | codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor); |
| 5666 | } |
| 5667 | else if (current >= 'a' and current <= 'f') |
| 5668 | { |
| 5669 | codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor); |
| 5670 | } |
| 5671 | else |
| 5672 | { |
| 5673 | return -1; |
| 5674 | } |
| 5675 | } |
| 5676 | |
| 5677 | assert(0x0000 <= codepoint and codepoint <= 0xFFFF); |
| 5678 | return codepoint; |
| 5679 | } |
| 5680 | |
| 5681 | /*! |
| 5682 | @brief check if the next byte(s) are inside a given range |