From af43f1f18a6615065e5f6baed9c2672b388bc99c Mon Sep 17 00:00:00 2001 From: yhirose Date: Mon, 13 Jun 2022 23:16:07 -0400 Subject: [PATCH] Support C++20 char8_t --- peglib.h | 126 ++++++++++++++++++++++++++++++++++++++++++-------- test/test3.cc | 8 ++++ 2 files changed, 115 insertions(+), 19 deletions(-) diff --git a/peglib.h b/peglib.h index 5f98161..367a578 100644 --- a/peglib.h +++ b/peglib.h @@ -2309,6 +2309,60 @@ public: 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(s), n, path, log); + } + + Result parse(const char8_t *s, const char *path = nullptr, + Log log = nullptr) const { + return parse(reinterpret_cast(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(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(s), dt, path, log); + } + + template + 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(s), n, val, *path, + log); + } + + template + 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(s), val, *path, + log); + } + + template + 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(s), n, dt, val, + *path, log); + } + + template + 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(s), dt, val, + *path, log); + } +#endif + void operator=(Action a) { action = a; } template Definition &operator,(T fn) { @@ -4317,13 +4371,21 @@ public: 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(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()) {} +#if defined(__cpp_lib_char8_t) + parser(std::u8string_view sv, const Rules &rules) + : parser(reinterpret_cast(sv.data()), sv.size(), rules) {} + + parser(std::u8string_view sv) + : parser(reinterpret_cast(sv.data()), sv.size(), Rules()) {} +#endif + operator bool() { return grammar_ != nullptr; } bool load_grammar(const char *s, size_t n, const Rules &rules) { @@ -4352,10 +4414,6 @@ public: 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, const char *path = nullptr) const { if (grammar_ != nullptr) { @@ -4365,11 +4423,6 @@ public: 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 bool parse_n(const char *s, size_t n, T &val, const char *path = nullptr) const { @@ -4380,11 +4433,6 @@ public: return false; } - template - bool parse(std::string_view sv, T &val, const char *path = nullptr) const { - return parse_n(sv.data(), sv.size(), val, path); - } - template bool parse_n(const char *s, size_t n, std::any &dt, T &val, const char *path = nullptr) const { @@ -4396,12 +4444,51 @@ public: 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 + bool parse(std::string_view sv, T &val, const char *path = nullptr) const { + return parse_n(sv.data(), sv.size(), val, path); + } + template bool parse(std::string_view sv, std::any &dt, T &val, const char *path = nullptr) const { 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(sv.data()), sv.size(), path); + } + + bool parse(std::u8string_view sv, std::any &dt, + const char *path = nullptr) const { + return parse_n(reinterpret_cast(sv.data()), sv.size(), dt, + path); + } + + template + bool parse(std::u8string_view sv, T &val, const char *path = nullptr) const { + return parse_n(reinterpret_cast(sv.data()), sv.size(), val, + path); + } + + template + bool parse(std::u8string_view sv, std::any &dt, T &val, + const char *path = nullptr) const { + return parse_n(reinterpret_cast(sv.data()), sv.size(), dt, + val, path); + } +#endif + Definition &operator[](const char *s) { 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) { auto end = std::chrono::steady_clock::now(); auto nano = std::chrono::duration_cast( - end - stats.start) - .count(); + end - stats.start) + .count(); 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]; size_t total_success = 0; diff --git a/test/test3.cc b/test/test3.cc index f644f2f..94ab1cc 100644 --- a/test/test3.cc +++ b/test/test3.cc @@ -9,6 +9,14 @@ inline bool exact(Grammar &g, const char *d, const char *s) { 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(s)); + auto r = g[d].parse(s, n); + return r.ret && r.len == n; +} +#endif + inline Grammar &make_peg_grammar() { return ParserGenerator::grammar(); } TEST(PEGTest, PEG_Grammar) {