From 813c483a312e1b1b4fa5a02234009ec546a0cc8c Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 23 May 2020 23:33:57 +0300 Subject: Add putback depth char_scanner template parameter --- libbutl/char-scanner.ixx | 52 +++++++++++++++++++++++------------------------- libbutl/char-scanner.mxx | 12 ++++++----- libbutl/char-scanner.txx | 20 +++++++++---------- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/libbutl/char-scanner.ixx b/libbutl/char-scanner.ixx index 7e9c4b0..57aefc2 100644 --- a/libbutl/char-scanner.ixx +++ b/libbutl/char-scanner.ixx @@ -3,36 +3,33 @@ namespace butl { - template - inline char_scanner:: + template + inline char_scanner:: char_scanner (std::istream& is, bool crlf, std::uint64_t l, std::uint64_t p) : char_scanner (is, validator_type (), crlf, l, p) { } - template - inline auto char_scanner:: + template + inline auto char_scanner:: peek (std::string& what) -> xchar { return peek (&what); } - template - inline auto char_scanner:: + template + inline auto char_scanner:: peek () -> xchar { return peek (nullptr /* what */); } - template - inline auto char_scanner:: + template + inline auto char_scanner:: get (std::string* what) -> xchar { - if (unget_) - { - unget_ = false; - return ungetc_; - } + if (ungetn_ != 0) + return ungetb_[--ungetn_]; else { xchar c (peek (what)); @@ -41,33 +38,34 @@ namespace butl } } - template - inline auto char_scanner:: + template + inline auto char_scanner:: get (std::string& what) -> xchar { return get (&what); } - template - inline auto char_scanner:: + template + inline auto char_scanner:: get () -> xchar { return get (nullptr /* what */); } - template - inline void char_scanner:: + template + inline void char_scanner:: unget (const xchar& c) { // Because iostream::unget cannot work once eos is reached, we have to // provide our own implementation. // - unget_ = true; - ungetc_ = c; + assert (ungetn_ != N); // Make sure the buffer is not filled. + + ungetb_[ungetn_++] = c; } - template - inline auto char_scanner:: + template + inline auto char_scanner:: peek_ () -> int_type { if (gptr_ != egptr_) @@ -86,8 +84,8 @@ namespace butl return r; } - template - inline void char_scanner:: + template + inline void char_scanner:: get_ () { int_type c; @@ -106,8 +104,8 @@ namespace butl save_->push_back (static_cast (c)); } - template - inline std::uint64_t char_scanner:: + template + inline std::uint64_t char_scanner:: pos_ () const { return buf_ != nullptr ? buf_->tellg () : 0; diff --git a/libbutl/char-scanner.mxx b/libbutl/char-scanner.mxx index e57245b..60994cf 100644 --- a/libbutl/char-scanner.mxx +++ b/libbutl/char-scanner.mxx @@ -9,6 +9,7 @@ #ifndef __cpp_lib_modules_ts #include // char_traits +#include // size_t #include // uint64_t #include // INT_* #include // pair, make_pair() @@ -46,11 +47,12 @@ LIBBUTL_MODEXPORT namespace butl // Low-level character stream scanner. Normally used as a base for // higher-level lexers. // - template + template class char_scanner { public: using validator_type = V; + static constexpr const std::size_t unget_depth = N; // If the crlf argument is true, then recognize Windows newlines (0x0D // 0x0A) and convert them to just '\n' (0x0A). Note that a standalone @@ -119,7 +121,7 @@ LIBBUTL_MODEXPORT namespace butl : char_type (0); } - xchar (int_type v, + xchar (int_type v = 0, std::uint64_t l = 0, std::uint64_t c = 0, std::uint64_t p = 0) @@ -247,10 +249,10 @@ LIBBUTL_MODEXPORT namespace butl bool crlf_; bool eos_ = false; - bool unget_ = false; - bool unpeek_ = false; + std::size_t ungetn_ = 0; + xchar ungetb_[N]; - xchar ungetc_ = '\0'; + bool unpeek_ = false; xchar unpeekc_ = '\0'; }; } diff --git a/libbutl/char-scanner.txx b/libbutl/char-scanner.txx index d4e2082..35edf42 100644 --- a/libbutl/char-scanner.txx +++ b/libbutl/char-scanner.txx @@ -7,8 +7,8 @@ namespace butl { - template - char_scanner:: + template + char_scanner:: char_scanner (std::istream& is, validator_type v, bool crlf, @@ -26,12 +26,12 @@ namespace butl { } - template - auto char_scanner:: + template + auto char_scanner:: peek (std::string* what) -> xchar { - if (unget_) - return ungetc_; + if (ungetn_ > 0) + return ungetb_[ungetn_ - 1]; if (unpeek_) return unpeekc_; @@ -108,12 +108,12 @@ namespace butl return xchar (v, line, column, position); } - template - void char_scanner:: + template + void char_scanner:: get (const xchar& c) { - if (unget_) - unget_ = false; + if (ungetn_ > 0) + --ungetn_; else { if (unpeek_) -- cgit v1.1