| 52 | |
| 53 | template<std::size_t N> |
| 54 | constexpr long long parse_llong(const char (&arr)[N]) |
| 55 | { |
| 56 | long long base = 10; |
| 57 | std::size_t offset = 0; |
| 58 | |
| 59 | if constexpr (N > 2) { |
| 60 | bool starts_with_zero = arr[0] == '0'; |
| 61 | bool is_hex = starts_with_zero && arr[1] == 'x'; |
| 62 | bool is_binary = starts_with_zero && arr[1] == 'b'; |
| 63 | |
| 64 | if (is_hex) { |
| 65 | // 0xDEADBEEF (hexadecimal) |
| 66 | base = 16; |
| 67 | offset = 2; |
| 68 | } else if (is_binary) { |
| 69 | // 0b101011101 (binary) |
| 70 | base = 2; |
| 71 | offset = 2; |
| 72 | } else if (starts_with_zero) { |
| 73 | // 012345 (octal) |
| 74 | base = 8; |
| 75 | offset = 1; |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | long long number = 0; |
| 80 | long long multiplier = 1; |
| 81 | |
| 82 | for (std::size_t i = 0; i < N - offset; ++i) { |
| 83 | char c = arr[N - 1 - i]; |
| 84 | if (c != '\'') { // skip digit separators |
| 85 | number += to_int(c) * multiplier; |
| 86 | multiplier *= base; |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | return number; |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | /** The tuple template alias used within Boost.Parser. This will be |