From 7e42ceb42f47453efeedc351b62ba733f56bb24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Jean-Prost?= Date: Wed, 23 Oct 2019 14:38:24 +0200 Subject: [PATCH] Adding base class for iterator2 class utf8::internal::iterator2 is a base class for utf8::iterator2 and utf8::unchecked::iterator2. --- source/utf8/checked.h | 21 +++++++++++++++ source/utf8/core.h | 53 ++++++++++++++++++++++++++++++++++++ source/utf8/unchecked.h | 59 +++++++++-------------------------------- 3 files changed, 87 insertions(+), 46 deletions(-) diff --git a/source/utf8/checked.h b/source/utf8/checked.h index 0567b50..247147d 100644 --- a/source/utf8/checked.h +++ b/source/utf8/checked.h @@ -318,6 +318,27 @@ namespace utf8 } }; // class iterator + //the iterator2 class + template + class iterator2 : public utf8::internal::iterator2 { + + public: + using Base = utf8::internal::iterator2; + iterator2 () {} + iterator2 (octet_iterator begin, octet_iterator end): Base{begin, end, utf8::next} {} + }; // class iterator2 + + template + inline bool operator==(const iterator2& a, const iterator2& b) + { + return a.equals(b); + } + template + inline bool operator!=(const iterator2& a, const iterator2& b) + { + return !a.equals(b); + } + } // namespace utf8 #if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later diff --git a/source/utf8/core.h b/source/utf8/core.h index 244e892..bb3de60 100644 --- a/source/utf8/core.h +++ b/source/utf8/core.h @@ -29,6 +29,7 @@ DEALINGS IN THE SOFTWARE. #define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 #include +#include // Determine the C++ standard version. // If the user defines UTF_CPP_CPLUSPLUS, use that. @@ -297,6 +298,58 @@ namespace internal return utf8::internal::validate_next(it, end, ignored); } + //the iterator2 class + template + class iterator2 : public std::iterator { + public: + using function = std::function; + private: + uint32_t cp{}; + octet_iterator p{}; + const octet_iterator end{}; + bool ok{}; + const function func{}; + + void read() + { + ok = p != end; + if(ok) + { + cp = func(p, end); + } + } + public: + iterator2 () {} + iterator2 (octet_iterator begin_, octet_iterator end_, function f): p{begin_}, end{end_}, func{f} { read(); } + uint32_t operator * () const { return cp; } + uint32_t* operator -> () const { return &cp; } + + iterator2& operator ++ () + { + if(!ok) + { + throw std::runtime_error("no such element"); + } + read(); + return *this; + } + iterator2 operator ++ (int) + { + if(!ok) + { + throw std::runtime_error("no such element"); + } + iterator2 tmp = *this; + read(); + return tmp; + } + + bool equals(const iterator2& a) const + { + return ok == a.ok && (!ok || p == a.p); + } + }; // class iterator2 + } // namespace internal /// The library API - functions intended to be called by the users diff --git a/source/utf8/unchecked.h b/source/utf8/unchecked.h index ce2d207..b88d287 100644 --- a/source/utf8/unchecked.h +++ b/source/utf8/unchecked.h @@ -263,64 +263,31 @@ namespace utf8 //the iterator2 class template - class iterator2 : public std::iterator { + class iterator2 : public utf8::internal::iterator2 { private: - uint32_t cp{}; - octet_iterator p{}; - const octet_iterator e{}; - bool ok{}; - - void read() - { - ok = p != e; - if(ok) - { - cp = utf8::unchecked::next(p); - } - } + template + struct N { + uint32_t operator()(T& o, T) const { + return utf8::unchecked::next(o); + } + }; + constexpr static N NEXT{}; + public: + using Base = utf8::internal::iterator2; iterator2 () {} - iterator2 (octet_iterator begin, octet_iterator end): p{begin}, e{end} { read(); } - iterator2 (const iterator2& a): cp{a.cp}, p{a.p}, e{a.e}, ok{a.ok} {} - - uint32_t operator * () const { return cp; } - uint32_t* operator -> () const { return &cp; } - - iterator2& operator ++ () - { - if(!ok) - { - throw std::runtime_error("no such element"); - } - read(); - return *this; - } - iterator2 operator ++ (int) - { - if(!ok) - { - throw std::runtime_error("no such element"); - } - iterator2 tmp = *this; - read(); - return tmp; - } - - bool equals(const iterator2& a) const - { - return ok == a.ok && (!ok || p == a.p); - } + iterator2 (octet_iterator begin, octet_iterator end): Base{begin, end, NEXT} {} }; // class iterator2 template inline bool operator==(const iterator2& a, const iterator2& b) { - return a.equals(b); + return a.equals(b); } template inline bool operator!=(const iterator2& a, const iterator2& b) { - return !a.equals(b); + return !a.equals(b); } } // namespace utf8::unchecked