3 #include <libcaramel/util/crtp.hpp>
22 requires std::is_reference_v<T>
25 using type = std::reference_wrapper<std::remove_reference_t<T>>;
30 using wrap_refs_t =
typename wrap_refs<T>::type;
33 constexpr
auto unref(T&& t) noexcept -> T&&
35 return static_cast<T&&
>(t);
39 constexpr
auto unref(std::reference_wrapper<T> t) noexcept -> T&
44 template <
typename Any>
47 wrap_refs_t<Any> m_value;
50 explicit constexpr
arrow_proxy(Any&& t) noexcept : m_value(std::forward<decltype(t)&&>(t))
53 constexpr
auto operator*() noexcept ->
auto& {
return unref(m_value); }
54 constexpr
auto operator*()
const noexcept ->
auto& {
return unref(m_value); }
56 constexpr
auto operator->() noexcept {
return std::addressof(**
this); }
57 constexpr
auto operator->()
const noexcept {
return std::addressof(**
this); }
69 template <
typename Sentinel,
typename Iter>
70 concept sized_sentinel_of = requires(
const Iter& it,
const Sentinel& sentinel)
72 it.distance_to(sentinel);
78 using type = std::ptrdiff_t;
81 template <
typename Any>
82 requires sized_sentinel_of<Any, Any>
85 static const Any& _it;
86 using type = decltype(_it.distance_to(_it));
89 template <
typename Any>
90 using infer_difference_type_t =
typename infer_difference_type<Any>::type;
93 template <
typename Any>
96 static const Any& _it;
97 using type = std::remove_const_t<std::remove_reference_t<decltype(*_it)>>;
100 template <
typename Any>
101 requires requires {
typename Any::value_type; }
104 using type =
typename Any::value_type;
107 template <
typename Any>
108 using infer_value_type_t =
typename infer_value_type<Any>::type;
110 template<
typename Any>
111 concept can_increment = requires(Any& v)
116 template<
typename Any>
117 concept can_decrement = requires(Any& v)
122 template <
typename Any>
123 concept can_advance = requires(Any& v,
const infer_difference_type_t<Any> d)
128 template <
typename Any>
129 concept random_access_iter = sized_sentinel_of<Any, Any> and can_advance<Any>;
131 template <
typename Any>
132 concept bidirectional_iter = random_access_iter<Any> or can_decrement<Any>;
134 template <
typename Any>
135 concept single_pass_iter = bool(Any::single_pass_iterator);
137 template <
typename Any,
typename Iter>
138 concept iter_diff = std::is_convertible_v<Any, infer_difference_type_t<Iter>>;
142 template <
typename Child>
146 constexpr
auto operator==(
const Child& rhs)
const ->
bool
148 return this->underlying().equal_to(rhs);
151 constexpr decltype(
auto) operator*()
const {
return this->underlying().dereference(); }
152 constexpr
auto operator->()
const
154 decltype(
auto) ref = **
this;
155 if constexpr (std::is_reference_v<decltype(ref)>)
157 return std::addressof(ref);
165 constexpr
auto operator++() -> Child&
167 if constexpr (detail::can_increment<Child>)
169 this->underlying().increment();
171 else if constexpr (detail::random_access_iter<Child>)
173 this->underlying() += 1;
177 static_assert(detail::random_access_iter<Child>,
178 "Iterator subclass must provide an `increment` or `advance(n)` method");
181 return this->underlying();
184 constexpr
auto operator++(
int)
186 if constexpr (detail::single_pass_iter<Child>)
192 auto it = this->underlying();
199 constexpr
auto operator--() -> Child& requires detail::bidirectional_iter<Child>
201 if constexpr (detail::can_decrement<Child>)
203 this->underlying().decrement();
207 this->underlying() -= 1;
210 return this->underlying();
213 constexpr
auto operator--(
int) -> Child requires detail::bidirectional_iter<Child>
215 auto it = this->underlying();
221 template <detail::iter_diff<Child> Diff>
222 friend constexpr
auto operator+(
const Child& left, Diff off) noexcept
223 requires detail::random_access_iter<Child>
229 template <detail::iter_diff<Child> D>
230 friend constexpr
auto operator+(D off,
const Child&
self) noexcept
231 requires detail::random_access_iter<Child>
236 friend constexpr
auto operator-(
const Child& left,
237 const Child& right) requires detail::random_access_iter<Child>
239 return right.distance_to(left);
242 template <detail::iter_diff<Child> D>
243 friend constexpr
auto operator-(
const Child&
self, D off) noexcept
244 requires detail::random_access_iter<Child>
246 using diff_type = detail::infer_difference_type_t<Child>;
247 using signed_diff_type = std::make_signed_t<diff_type>;
248 return self + -
static_cast<signed_diff_type
>(off);
251 template <detail::sized_sentinel_of<Child> S>
252 friend constexpr
auto operator-(
const S& s,
const Child&
self) noexcept
254 return self.distance_to(s);
257 template <detail::iter_diff<Child> D>
258 constexpr
friend auto operator+=(Child&
self, D off) noexcept
259 -> Child& requires detail::random_access_iter<Child>
265 template <detail::iter_diff<Child> D>
266 constexpr
friend auto operator-=(Child&
self, D off) noexcept
267 -> Child& requires detail::random_access_iter<Child>
269 return self =
self - off;
272 template <detail::iter_diff<Child> D>
273 [[nodiscard]] constexpr decltype(
auto) operator[](D pos)
const noexcept
274 requires detail::random_access_iter<Child>
276 return *(this->underlying() + pos);
279 template <std::convertible_to<const Child&> Self, detail::sized_sentinel_of<Self> S>
280 friend constexpr
auto operator<=>(
const Self&
self,
const S& right) noexcept
282 auto dist =
self - right;
283 auto rel = dist <=> 0;
291 template <std::derived_from<caramel::detail::iterator_facade_base> Derived>
292 struct iterator_traits<Derived>
294 static const Derived& _const_it;
296 using value_type = caramel::detail::infer_value_type_t<Derived>;
297 using difference_type = caramel::detail::infer_difference_type_t<Derived>;
298 using reference = decltype(*_const_it);
299 using pointer = decltype(_const_it.operator->());
302 using iterator_category = std::conditional_t<
304 caramel::detail::random_access_iter<Derived>, std::random_access_iterator_tag,
308 caramel::detail::bidirectional_iter<Derived>, std::bidirectional_iterator_tag,
312 caramel::detail::single_pass_iter<Derived>,
314 std::input_iterator_tag,
316 std::forward_iterator_tag>>>;
318 using iterator_concept = iterator_category;
Definition: iterator_facade.hpp:46
Definition: iterator_facade.hpp:144
Definition: iterator_facade.hpp:77
Definition: iterator_facade.hpp:95
Definition: iterator_facade.hpp:64
Definition: iterator_facade.hpp:17