mirror of
https://github.com/nemtrif/utfcpp.git
synced 2025-04-06 14:05:06 +00:00
Adding base class for iterator2
class utf8::internal::iterator2 is a base class for utf8::iterator2 and utf8::unchecked::iterator2.
This commit is contained in:
parent
df0e5bad02
commit
7e42ceb42f
3 changed files with 87 additions and 46 deletions
|
@ -318,6 +318,27 @@ namespace utf8
|
|||
}
|
||||
}; // class iterator
|
||||
|
||||
//the iterator2 class
|
||||
template <typename octet_iterator>
|
||||
class iterator2 : public utf8::internal::iterator2<octet_iterator> {
|
||||
|
||||
public:
|
||||
using Base = utf8::internal::iterator2<octet_iterator>;
|
||||
iterator2 () {}
|
||||
iterator2 (octet_iterator begin, octet_iterator end): Base{begin, end, utf8::next<octet_iterator>} {}
|
||||
}; // class iterator2
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline bool operator==(const iterator2<octet_iterator>& a, const iterator2<octet_iterator>& b)
|
||||
{
|
||||
return a.equals(b);
|
||||
}
|
||||
template <typename octet_iterator>
|
||||
inline bool operator!=(const iterator2<octet_iterator>& a, const iterator2<octet_iterator>& b)
|
||||
{
|
||||
return !a.equals(b);
|
||||
}
|
||||
|
||||
} // namespace utf8
|
||||
|
||||
#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later
|
||||
|
|
|
@ -29,6 +29,7 @@ DEALINGS IN THE SOFTWARE.
|
|||
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
|
||||
// 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 <typename octet_iterator>
|
||||
class iterator2 : public std::iterator <std::input_iterator_tag, uint32_t> {
|
||||
public:
|
||||
using function = std::function<uint32_t(octet_iterator&, octet_iterator)>;
|
||||
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
|
||||
|
|
|
@ -263,64 +263,31 @@ namespace utf8
|
|||
|
||||
//the iterator2 class
|
||||
template <typename octet_iterator>
|
||||
class iterator2 : public std::iterator <std::input_iterator_tag, uint32_t> {
|
||||
class iterator2 : public utf8::internal::iterator2<octet_iterator> {
|
||||
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 <typename T>
|
||||
struct N {
|
||||
uint32_t operator()(T& o, T) const {
|
||||
return utf8::unchecked::next(o);
|
||||
}
|
||||
};
|
||||
constexpr static N<octet_iterator> NEXT{};
|
||||
|
||||
public:
|
||||
using Base = utf8::internal::iterator2<octet_iterator>;
|
||||
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 <typename octet_iterator>
|
||||
inline bool operator==(const iterator2<octet_iterator>& a, const iterator2<octet_iterator>& b)
|
||||
{
|
||||
return a.equals(b);
|
||||
return a.equals(b);
|
||||
}
|
||||
template <typename octet_iterator>
|
||||
inline bool operator!=(const iterator2<octet_iterator>& a, const iterator2<octet_iterator>& b)
|
||||
{
|
||||
return !a.equals(b);
|
||||
return !a.equals(b);
|
||||
}
|
||||
|
||||
} // namespace utf8::unchecked
|
||||
|
|
Loading…
Add table
Reference in a new issue