7namespace CppClingo::Util {
13inline auto hex_val(
char c) -> uint32_t {
14 if (c >=
'0' && c <=
'9') {
17 if (c >=
'A' && c <=
'F') {
18 return 10 + (c -
'A');
20 if (c >=
'a' && c <=
'f') {
21 return 10 + (c -
'a');
23 throw std::invalid_argument(
"invalid hex character");
26inline auto encode_utf8(uint32_t cp,
auto out) ->
void {
28 throw std::invalid_argument(
"invalid unicode code point");
31 *out++ =
static_cast<char>(cp);
32 }
else if (cp <= 0x7FF) {
33 *out++ =
static_cast<char>(0xC0 | (cp >> 6));
34 *out++ =
static_cast<char>(0x80 | (cp & 0x3F));
35 }
else if (cp <= 0xFFFF) {
36 *out++ =
static_cast<char>(0xE0 | (cp >> 12));
37 *out++ =
static_cast<char>(0x80 | ((cp >> 6) & 0x3F));
38 *out++ =
static_cast<char>(0x80 | (cp & 0x3F));
40 *out++ =
static_cast<char>(0xF0 | (cp >> 18));
41 *out++ =
static_cast<char>(0x80 | ((cp >> 12) & 0x3F));
42 *out++ =
static_cast<char>(0x80 | ((cp >> 6) & 0x3F));
43 *out++ =
static_cast<char>(0x80 | (cp & 0x3F));
47inline auto parse_unicode_escape(
auto it,
auto ie,
auto out) ->
auto {
49 if (it == ie || *it !=
'{') {
50 throw std::runtime_error(
"expected '{' at the beginning of unicode escape");
53 for (++it; it != ie; ++it, ++count) {
56 throw std::runtime_error(
"expected at least one hex digit in unicode escape");
62 throw std::runtime_error(
"too many hex digits in unicode escape");
64 cp = (cp << 4) | hex_val(*it);
66 throw std::runtime_error(
"expected '}' at the end of unicode escape");
73void unquote(std::string_view in,
auto out,
bool fstring =
false) {
76 for (
auto it = in.begin(), ie = in.end(); it != ie; ++it) {
78 if (escape ==
'{' || escape ==
'}') {
82 throw std::runtime_error(
"expected brace");
85 }
else if (escape ==
'\\') {
89 it = Detail::parse_unicode_escape(it + 1, ie, out);
113 throw std::runtime_error(
"invalid escape sequence");
117 }
else if (c ==
'\\' || (fstring && (c ==
'{' || c ==
'}'))) {