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

122
peglib.h
View File

@ -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<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; }
template <typename T> 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<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; }
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 <typename T>
bool parse_n(const char *s, size_t n, T &val,
const char *path = nullptr) const {
@ -4380,11 +4433,6 @@ public:
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>
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 <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>
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<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]; }
const Definition &operator[](const char *s) const { return (*grammar_)[s]; }
@ -4599,7 +4686,8 @@ inline void enable_profiling(parser &parser, std::ostream &os) {
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;

View File

@ -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<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(); }
TEST(PEGTest, PEG_Grammar) {