31 friend struct Sentinel;
32 friend struct Iterator;
34 using Value = di::meta::Reconstructed<View, di::meta::ContainerIterator<View>, di::meta::ContainerIterator<View>>;
37 :
public di::container::IteratorBase<Iterator, di::ForwardIteratorTag, Value,
38 di::meta::ContainerSSizeType<View>> {
43 : m_parent(
di::addressof(parent)), m_base(
di::move(
base)), m_next(
di::move(next)) {}
45 constexpr auto base()
const {
return m_base; }
47 constexpr auto operator*() const -> Value {
48 return di::reconstruct(di::in_place_type<View>, m_base, di::end(m_next));
51 constexpr void advance_one() {
52 m_base = di::begin(m_next);
53 if (m_base != di::end(m_parent->m_base)) {
54 m_base = di::end(m_next);
55 if (m_base == di::end(m_parent->m_base)) {
56 m_next = di::reconstruct(di::in_place_type<View>, m_base, m_base);
58 m_next = m_parent->find_next(m_base);
64 friend struct Sentinel;
66 constexpr friend auto operator==(Iterator
const& a, Iterator
const& b) ->
bool {
return a.m_base == b.m_base; }
69 di::meta::ContainerIterator<View> m_base;
77 constexpr explicit Sentinel(GraphemeClusterView& parent) : m_base(di::end(parent.m_base)) {}
80 constexpr friend auto operator==(Iterator
const& a, Sentinel
const& b) ->
bool {
return a.m_base == b.m_base; }
82 di::meta::ContainerSentinel<View> m_base;
87 requires(di::concepts::DefaultInitializable<View>)
92 constexpr auto base() const& -> View
93 requires(
di::concepts::CopyConstructible<View>)
97 constexpr auto base() && -> View {
return di::move(m_base); }
99 constexpr auto begin() -> Iterator {
102 if (!m_cached_begin) {
103 m_cached_begin = this->find_next(di::begin(m_base));
105 return { *
this, di::begin(m_base), *m_cached_begin };
109 if constexpr (di::concepts::CommonContainer<View>) {
110 return Iterator { *
this, di::end(m_base),
111 di::reconstruct(di::in_place_type<View>, di::end(m_base), di::end(m_base)) };
113 return Sentinel { *
this };
118 constexpr auto find_next(di::meta::ContainerIterator<View> it) -> Value {
121 auto base_end = di::end(m_base);
122 if (last != base_end) {
128 while (last != base_end && !clusterer.is_boundary(*last)) {
132 return di::reconstruct(di::in_place_type<View>, di::move(start), di::move(last));
136 di::Optional<Value> m_cached_begin;