Iros
 
Loading...
Searching...
No Matches
common_iterator.h
Go to the documentation of this file.
1#pragma once
2
7
8namespace di::container {
9template<concepts::InputIterator Iter, concepts::SentinelFor<Iter> Sent>
10requires(!concepts::SameAs<Iter, Sent> && concepts::Copyable<Iter>)
12 : public IteratorBase<CommonIterator<Iter, Sent>,
13 meta::Conditional<concepts::ForwardIterator<Iter>, ForwardIteratorTag, InputIteratorTag>,
14 meta::IteratorValue<Iter>, meta::IteratorSSizeType<Iter>> {
15private:
16public:
19 = default;
20
21 constexpr CommonIterator(Iter it) : m_state(c_<0ZU>, util::move(it)) {}
22 constexpr CommonIterator(Sent sent) : m_state(c_<1ZU>, util::move(sent)) {}
23
24 template<typename It, typename St>
26 constexpr CommonIterator(CommonIterator<It, St> const& other) : m_state(other.m_state) {}
27
28 template<typename It, typename St>
30 constexpr auto operator=(CommonIterator<It, St> const& other) -> CommonIterator& {
31 this->m_state = other.m_state;
32 return *this;
33 }
34
35 constexpr auto operator*() const -> decltype(auto) { return *util::get<0>(m_state); }
36
37 constexpr auto operator->() const
38 requires((concepts::IndirectlyReadable<Iter const> && (requires(Iter const& it) { it.operator->(); })) ||
41 {
42 if constexpr (requires(Iter const& it) { it.operator->(); }) {
43 return util::get<0>(m_state);
44 } else if constexpr (concepts::Reference<meta::IteratorReference<Iter>>) {
45 auto&& temp = *util::get<0>(m_state);
46 return util::addressof(temp);
47 } else {
48 class Proxy {
49 public:
50 constexpr auto operator->() const -> meta::IteratorValue<Iter> const* {
51 return util::addressof(m_value);
52 }
53
54 private:
55 constexpr Proxy(meta::IteratorReference<Iter>&& value) : m_value(util::move(value)) {}
56
57 meta::IteratorValue<Iter> m_value;
58 };
59
60 return Proxy(*util::get<0>(m_state));
61 }
62 }
63
64 constexpr void advance_one() { ++util::get<0>(m_state); }
65
66private:
67 template<concepts::InputIterator It, concepts::SentinelFor<It> St>
69 friend class CommonIterator;
70
71 template<typename It, concepts::SentinelFor<It> St>
73 constexpr friend auto operator==(CommonIterator const& a, CommonIterator<It, St> const& b) -> bool {
74 if (a.m_state.index() == b.m_state.index()) {
75 return true;
76 }
77 if (a.m_state.index() == 0) {
78 return util::get<0>(a.m_state) == util::get<1>(b.m_state);
79 }
80 return util::get<1>(a.m_state) == util::get<0>(b.m_state);
81 }
82
83 template<typename It, concepts::SentinelFor<It> St>
85 constexpr friend auto operator==(CommonIterator const& a, CommonIterator<It, St> const& b) -> bool {
86 if (a.m_state.index() == 1 && b.m_state.index() == 1) {
87 return true;
88 }
89 if (a.m_state.index() == 0 && b.m_state.index() == 0) {
90 return util::get<0>(a.m_state) == util::get<0>(b.m_state);
91 }
92 if (a.m_state.index() == 0) {
93 return util::get<0>(a.m_state) == util::get<1>(b.m_state);
94 }
95 return util::get<1>(a.m_state) == util::get<0>(b.m_state);
96 }
97
98 template<concepts::SizedSentinelFor<Iter> It, concepts::SizedSentinelFor<Iter> St>
100 constexpr friend auto operator-(CommonIterator const& a, CommonIterator<It, St> const& b)
102 if (a.m_state.index() == 1 && b.m_state.index() == 1) {
103 return 0;
104 }
105 if (a.m_state.index() == 0 && b.m_state.index() == 0) {
106 return util::get<0>(a.m_state) - util::get<0>(b.m_state);
107 }
108 if (a.m_state.index() == 0) {
109 return util::get<0>(a.m_state) - util::get<1>(b.m_state);
110 }
111 return util::get<1>(a.m_state) - util::get<0>(b.m_state);
112 }
113
114 constexpr friend auto tag_invoke(types::Tag<iterator_move>, CommonIterator const& a) -> decltype(auto) {
115 return iterator_move(util::get<0>(a.m_state));
116 }
117
118 template<concepts::IndirectlySwappable<Iter> It, typename St>
119 constexpr friend void tag_invoke(types::Tag<iterator_swap>, CommonIterator const& a,
120 CommonIterator<It, St> const& b) {
121 return iterator_swap(util::get<0>(a.m_state), util::get<0>(b.m_state));
122 }
123
124 Variant<Iter, Sent> m_state;
125};
126}
constexpr CommonIterator(Iter it)
Definition common_iterator.h:21
constexpr CommonIterator(Sent sent)
Definition common_iterator.h:22
constexpr CommonIterator(CommonIterator< It, St > const &other)
Definition common_iterator.h:26
constexpr auto operator=(CommonIterator< It, St > const &other) -> CommonIterator &
Definition common_iterator.h:30
constexpr auto operator->() const
Definition common_iterator.h:37
constexpr friend auto tag_invoke(types::Tag< iterator_move >, CommonIterator const &a) -> decltype(auto)
Definition common_iterator.h:114
friend class CommonIterator
Definition common_iterator.h:69
constexpr friend void tag_invoke(types::Tag< iterator_swap >, CommonIterator const &a, CommonIterator< It, St > const &b)
Definition common_iterator.h:119
constexpr void advance_one()
Definition common_iterator.h:64
constexpr auto operator*() const -> decltype(auto)
Definition common_iterator.h:35
Definition variant_forward_declaration.h:6
Definition operations.h:11
Definition operations.h:99
Definition operations.h:40
Definition operations.h:27
Definition language.h:50
Definition core.h:114
Definition sentinel_for.h:9
Definition sized_sentinel_for.h:9
Definition any_storable.h:9
Definition sequence.h:12
constexpr auto iterator_move
Definition iterator_move.h:56
constexpr auto move
Definition move.h:38
constexpr auto iterator_swap
Definition iterator_swap.h:49
constexpr auto value
Definition value.h:34
Definition merge_interfaces.h:6
decltype(container::iterator_ssize_type(types::in_place_type< meta::RemoveCVRef< T > >)) IteratorSSizeType
Definition iterator_ssize_type.h:8
meta::Type< decltype(container::iterator_value(types::in_place_type< meta::RemoveCVRef< T > >))> IteratorValue
Definition iterator_value.h:8
decltype(*util::declval< T const & >()) IteratorReference
Definition iterator_reference.h:7
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
constexpr auto get(T &&value) -> decltype(auto)
Definition get.h:8
constexpr auto c_
A value of type Constexpr<val>.
Definition constexpr.h:252
Definition forward_iterator_tag.h:6
Definition input_iterator_tag.h:4