Support C++20 char8_t

This commit is contained in:
yhirose 2022-06-13 23:16:07 -04:00
parent bce65fe754
commit af43f1f18a
2 changed files with 115 additions and 19 deletions

126
peglib.h
View File

@ -2309,6 +2309,60 @@ public:
return parse_and_get_value(s, n, dt, val, path, log); return parse_and_get_value(s, n, dt, val, path, log);
} }
#if defined(__cpp_lib_char8_t)
Result parse(const char8_t *s, size_t n, const char *path = nullptr,
Log log = nullptr) const {
return parse(reinterpret_cast<const char *>(s), n, path, log);
}
Result parse(const char8_t *s, const char *path = nullptr,
Log log = nullptr) const {
return parse(reinterpret_cast<const char *>(s), path, log);
}
Result parse(const char8_t *s, size_t n, std::any &dt,
const char *path = nullptr, Log log = nullptr) const {
return parse(reinterpret_cast<const char *>(s), n, dt, path, log);
}
Result parse(const char8_t *s, std::any &dt, const char *path = nullptr,
Log log = nullptr) const {
return parse(reinterpret_cast<const char *>(s), dt, path, log);
}
template <typename T>
Result parse_and_get_value(const char8_t *s, size_t n, T &val,
const char *path = nullptr,
Log log = nullptr) const {
return parse_and_get_value(reinterpret_cast<const char *>(s), n, val, *path,
log);
}
template <typename T>
Result parse_and_get_value(const char8_t *s, T &val,
const char *path = nullptr,
Log log = nullptr) const {
return parse_and_get_value(reinterpret_cast<const char *>(s), val, *path,
log);
}
template <typename T>
Result parse_and_get_value(const char8_t *s, size_t n, std::any &dt, T &val,
const char *path = nullptr,
Log log = nullptr) const {
return parse_and_get_value(reinterpret_cast<const char *>(s), n, dt, val,
*path, log);
}
template <typename T>
Result parse_and_get_value(const char8_t *s, std::any &dt, T &val,
const char *path = nullptr,
Log log = nullptr) const {
return parse_and_get_value(reinterpret_cast<const char *>(s), dt, val,
*path, log);
}
#endif
void operator=(Action a) { action = a; } void operator=(Action a) { action = a; }
template <typename T> Definition &operator,(T fn) { template <typename T> Definition &operator,(T fn) {
@ -4317,13 +4371,21 @@ public:
load_grammar(s, n, rules); load_grammar(s, n, rules);
} }
parser(const char *s, size_t n) : parser(s, n, Rules()) {}
parser(std::string_view sv, const Rules &rules) parser(std::string_view sv, const Rules &rules)
: parser(sv.data(), sv.size(), rules) {} : parser(sv.data(), sv.size(), rules) {}
parser(const char *s, size_t n) : parser(s, n, Rules()) {}
parser(std::string_view sv) : parser(sv.data(), sv.size(), Rules()) {} parser(std::string_view sv) : parser(sv.data(), sv.size(), Rules()) {}
#if defined(__cpp_lib_char8_t)
parser(std::u8string_view sv, const Rules &rules)
: parser(reinterpret_cast<const char *>(sv.data()), sv.size(), rules) {}
parser(std::u8string_view sv)
: parser(reinterpret_cast<const char *>(sv.data()), sv.size(), Rules()) {}
#endif
operator bool() { return grammar_ != nullptr; } operator bool() { return grammar_ != nullptr; }
bool load_grammar(const char *s, size_t n, const Rules &rules) { bool load_grammar(const char *s, size_t n, const Rules &rules) {
@ -4352,10 +4414,6 @@ public:
return false; return false;
} }
bool parse(std::string_view sv, const char *path = nullptr) const {
return parse_n(sv.data(), sv.size(), path);
}
bool parse_n(const char *s, size_t n, std::any &dt, bool parse_n(const char *s, size_t n, std::any &dt,
const char *path = nullptr) const { const char *path = nullptr) const {
if (grammar_ != nullptr) { if (grammar_ != nullptr) {
@ -4365,11 +4423,6 @@ public:
return false; return false;
} }
bool parse(std::string_view sv, std::any &dt,
const char *path = nullptr) const {
return parse_n(sv.data(), sv.size(), dt, path);
}
template <typename T> template <typename T>
bool parse_n(const char *s, size_t n, T &val, bool parse_n(const char *s, size_t n, T &val,
const char *path = nullptr) const { const char *path = nullptr) const {
@ -4380,11 +4433,6 @@ public:
return false; return false;
} }
template <typename T>
bool parse(std::string_view sv, T &val, const char *path = nullptr) const {
return parse_n(sv.data(), sv.size(), val, path);
}
template <typename T> template <typename T>
bool parse_n(const char *s, size_t n, std::any &dt, T &val, bool parse_n(const char *s, size_t n, std::any &dt, T &val,
const char *path = nullptr) const { const char *path = nullptr) const {
@ -4396,12 +4444,51 @@ public:
return false; return false;
} }
bool parse(std::string_view sv, const char *path = nullptr) const {
return parse_n(sv.data(), sv.size(), path);
}
bool parse(std::string_view sv, std::any &dt,
const char *path = nullptr) const {
return parse_n(sv.data(), sv.size(), dt, path);
}
template <typename T>
bool parse(std::string_view sv, T &val, const char *path = nullptr) const {
return parse_n(sv.data(), sv.size(), val, path);
}
template <typename T> template <typename T>
bool parse(std::string_view sv, std::any &dt, T &val, bool parse(std::string_view sv, std::any &dt, T &val,
const char *path = nullptr) const { const char *path = nullptr) const {
return parse_n(sv.data(), sv.size(), dt, val, path); return parse_n(sv.data(), sv.size(), dt, val, path);
} }
#if defined(__cpp_lib_char8_t)
bool parse(std::u8string_view sv, const char *path = nullptr) const {
return parse_n(reinterpret_cast<const char *>(sv.data()), sv.size(), path);
}
bool parse(std::u8string_view sv, std::any &dt,
const char *path = nullptr) const {
return parse_n(reinterpret_cast<const char *>(sv.data()), sv.size(), dt,
path);
}
template <typename T>
bool parse(std::u8string_view sv, T &val, const char *path = nullptr) const {
return parse_n(reinterpret_cast<const char *>(sv.data()), sv.size(), val,
path);
}
template <typename T>
bool parse(std::u8string_view sv, std::any &dt, T &val,
const char *path = nullptr) const {
return parse_n(reinterpret_cast<const char *>(sv.data()), sv.size(), dt,
val, path);
}
#endif
Definition &operator[](const char *s) { return (*grammar_)[s]; } Definition &operator[](const char *s) { return (*grammar_)[s]; }
const Definition &operator[](const char *s) const { return (*grammar_)[s]; } const Definition &operator[](const char *s) const { return (*grammar_)[s]; }
@ -4596,10 +4683,11 @@ inline void enable_profiling(parser &parser, std::ostream &os) {
if (index == 0) { if (index == 0) {
auto end = std::chrono::steady_clock::now(); auto end = std::chrono::steady_clock::now();
auto nano = std::chrono::duration_cast<std::chrono::microseconds>( auto nano = std::chrono::duration_cast<std::chrono::microseconds>(
end - stats.start) end - stats.start)
.count(); .count();
auto sec = nano / 1000000.0; auto sec = nano / 1000000.0;
os << "duration: " << sec << "s (" << nano << "µs)" << std::endl << std::endl; os << "duration: " << sec << "s (" << nano << "µs)" << std::endl
<< std::endl;
char buff[BUFSIZ]; char buff[BUFSIZ];
size_t total_success = 0; size_t total_success = 0;

View File

@ -9,6 +9,14 @@ inline bool exact(Grammar &g, const char *d, const char *s) {
return r.ret && r.len == n; return r.ret && r.len == n;
} }
#if defined(__cpp_lib_char8_t)
inline bool exact(Grammar &g, const char *d, const char8_t *s) {
auto n = strlen(reinterpret_cast<const char *>(s));
auto r = g[d].parse(s, n);
return r.ret && r.len == n;
}
#endif
inline Grammar &make_peg_grammar() { return ParserGenerator::grammar(); } inline Grammar &make_peg_grammar() { return ParserGenerator::grammar(); }
TEST(PEGTest, PEG_Grammar) { TEST(PEGTest, PEG_Grammar) {