17 #include <type_traits>
21 namespace seqan3::detail
40 template <
typename range_type,
template <
typename ...>
typename derived_t_template>
41 class random_access_iterator_base
49 position_type pos{
static_cast<position_type
>(0)};
52 template <
typename range_type2,
template <
typename ...>
typename derived_t_template2>
54 requires std::is_const_v<range_type> && (!std::is_const_v<range_type2>) &&
56 std::is_same_v<derived_t_template2, derived_t_template>
58 friend class random_access_iterator_base;
61 using derived_t = derived_t_template <range_type>;
65 using difference_type =
typename range_type::difference_type;
67 using value_type =
typename range_type::value_type;
70 typename range_type::const_reference,
71 typename range_type::reference>;
73 using const_reference =
typename range_type::const_reference;
75 using pointer = value_type *;
82 constexpr random_access_iterator_base() =
default;
85 constexpr random_access_iterator_base(random_access_iterator_base
const &) =
default;
87 constexpr random_access_iterator_base & operator=(random_access_iterator_base
const &) =
default;
89 constexpr random_access_iterator_base (random_access_iterator_base &&) =
default;
91 constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) =
default;
93 ~random_access_iterator_base() =
default;
96 explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host} {}
98 constexpr random_access_iterator_base(range_type & host, position_type
const pos) noexcept :
103 template <
typename range_type2>
105 requires std::is_const_v<range_type> && (!std::is_const_v<range_type2>) &&
108 constexpr random_access_iterator_base(random_access_iterator_base<range_type2, derived_t_template>
const & rhs) noexcept :
109 host{rhs.host}, pos{rhs.pos}
119 template <
typename range_type2>
124 constexpr
bool operator==(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
126 return pos == rhs.pos;
130 template <
typename range_type2>
134 constexpr
bool operator!=(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
136 return !(*
this == rhs);
140 template <
typename range_type2>
144 constexpr
bool operator<(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
146 return static_cast<bool>(pos < rhs.pos);
150 template <
typename range_type2>
154 constexpr
bool operator>(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
156 return pos > rhs.pos;
160 template <
typename range_type2>
164 constexpr
bool operator<=(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
166 return pos <= rhs.pos;
170 template <
typename range_type2>
174 constexpr
bool operator>=(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
176 return pos >= rhs.pos;
184 constexpr derived_t & operator++() noexcept
188 return *this_derived();
192 constexpr derived_t operator++(
int) noexcept
194 derived_t cpy{*this_derived()};
200 constexpr derived_t & operator--() noexcept
203 return *this_derived();
207 constexpr derived_t operator--(
int) noexcept
209 derived_t cpy{*this_derived()};
215 constexpr derived_t & operator+=(difference_type
const skip) noexcept
218 return *this_derived();
222 constexpr derived_t operator+(difference_type
const skip)
const noexcept
224 derived_t cpy{*this_derived()};
229 constexpr
friend derived_t operator+(difference_type
const skip, derived_t
const & it) noexcept
235 constexpr derived_t & operator-=(difference_type
const skip) noexcept
238 return *this_derived();
242 constexpr derived_t operator-(difference_type
const skip)
const noexcept
244 derived_t cpy{*this_derived()};
249 constexpr
friend derived_t operator-(difference_type
const skip, derived_t
const & it) noexcept
255 constexpr
friend difference_type operator-(derived_t
const & lhs, derived_t
const & rhs) noexcept
257 return static_cast<difference_type
>(lhs.pos - rhs.pos);
265 constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
272 constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
278 constexpr reference operator[](position_type
const n)
const noexcept(noexcept((*host)[pos+n]))
280 return (*host)[pos + n];
287 constexpr derived_t* this_derived()
289 return static_cast<derived_t*
>(
this);
293 constexpr derived_t
const * this_derived()
const
295 return static_cast<derived_t
const *
>(
this);
307 template <
typename range_type>
308 class random_access_iterator :
309 public random_access_iterator_base<range_type, random_access_iterator>
313 using base = random_access_iterator_base<range_type, random_access_iterator>;
315 using typename base::position_type;
322 using typename base::difference_type;
323 using typename base::value_type;
324 using typename base::reference;
325 using typename base::const_reference;
326 using typename base::pointer;
327 using typename base::iterator_category;