125 lines
2.5 KiB
C++
125 lines
2.5 KiB
C++
#ifndef code__unicode__iterator_hxx_
|
|
#define code__unicode__iterator_hxx_
|
|
|
|
#include <code/unicode/decoding.hxx>
|
|
|
|
#include <cstdint>
|
|
|
|
namespace code::unicode
|
|
{
|
|
|
|
template<typename Decoder, typename IteratorType>
|
|
class Unicode_input_iterator
|
|
{
|
|
public:
|
|
using decoder_type = Decoder;
|
|
using iterator_type = IteratorType;
|
|
using value_type = std::uint32_t;
|
|
|
|
// TODO standard member types
|
|
|
|
Unicode_input_iterator()
|
|
{}
|
|
|
|
explicit Unicode_input_iterator(iterator_type it) : it_{ std::move(it) }
|
|
{
|
|
decode();
|
|
}
|
|
|
|
Unicode_input_iterator(iterator_type it, iterator_type end)
|
|
: it_{ std::move(it) }, end_{ std::move(end) }
|
|
{
|
|
decode();
|
|
}
|
|
|
|
Unicode_input_iterator(decoder_type decoder, iterator_type it)
|
|
: decoder_{ std::move(decoder) }, it_{ std::move(it) }
|
|
{
|
|
decode();
|
|
}
|
|
|
|
Unicode_input_iterator(decoder_type decoder,
|
|
iterator_type it,
|
|
iterator_type end)
|
|
: decoder_{ std::move(decoder) },
|
|
it_{ std::move(it) },
|
|
end_{ std::move(end) }
|
|
{
|
|
decode();
|
|
}
|
|
|
|
value_type operator*() const
|
|
{
|
|
return unicode_;
|
|
}
|
|
|
|
Unicode_input_iterator&
|
|
operator++()
|
|
{
|
|
decode();
|
|
return *this;
|
|
}
|
|
|
|
struct Proxy
|
|
{
|
|
value_type unicode_;
|
|
|
|
value_type operator*() const
|
|
{
|
|
return unicode_;
|
|
}
|
|
};
|
|
|
|
Proxy
|
|
operator++(int)
|
|
{
|
|
auto unicode = unicode_;
|
|
decode();
|
|
return Proxy{unicode};
|
|
}
|
|
|
|
bool
|
|
equal(iterator_type const& other) const
|
|
{
|
|
return it_ == other;
|
|
}
|
|
|
|
private:
|
|
void
|
|
decode()
|
|
{
|
|
if (it_ != end_)
|
|
unicode_ = decoder_.decode(it_, end_);
|
|
}
|
|
|
|
decoder_type decoder_;
|
|
iterator_type it_;
|
|
iterator_type end_;
|
|
std::uint32_t unicode_{};
|
|
};
|
|
|
|
template<typename InputIterator >
|
|
using Utf8_input_iterator = Unicode_input_iterator<Utf8_decoder, InputIterator>;
|
|
|
|
template<typename Decoder, typename IteratorType>
|
|
bool
|
|
operator==(
|
|
Unicode_input_iterator<Decoder, IteratorType> const& lhs,
|
|
typename Unicode_input_iterator<Decoder, IteratorType>::iterator_type const& rhs)
|
|
{
|
|
return lhs.equal(rhs);
|
|
}
|
|
|
|
template<typename Decoder, typename IteratorType>
|
|
bool
|
|
operator!=(
|
|
Unicode_input_iterator<Decoder, IteratorType> const& lhs,
|
|
typename Unicode_input_iterator< Decoder, IteratorType >::iterator_type const& rhs)
|
|
{
|
|
return !lhs.equal(rhs);
|
|
}
|
|
|
|
} // namespace code::unicode
|
|
|
|
#endif
|