16 #include <type_traits>
20 namespace seqan3::detail
39 template <
typename range_type,
template <
typename ...>
typename derived_t_template>
40 class random_access_iterator_base
48 position_type pos{static_cast<position_type>(0)};
51 template <
typename range_type2,
template <
typename ...>
typename derived_t_template2>
53 requires std::is_const_v<range_type> && !std::is_const_v<range_type2> &&
54 std::is_same_v<std::remove_const_t<range_type>, range_type2> &&
55 std::is_same_v<derived_t_template2, derived_t_template>
57 friend class random_access_iterator_base;
60 using derived_t = derived_t_template <range_type>;
64 using difference_type =
typename range_type::difference_type;
66 using value_type =
typename range_type::value_type;
69 typename range_type::const_reference,
70 typename range_type::reference>;
72 using const_reference =
typename range_type::const_reference;
74 using pointer = value_type *;
81 constexpr random_access_iterator_base() =
default;
84 constexpr random_access_iterator_base(random_access_iterator_base
const &) =
default;
86 constexpr random_access_iterator_base & operator=(random_access_iterator_base
const &) =
default;
88 constexpr random_access_iterator_base (random_access_iterator_base &&) =
default;
90 constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) =
default;
92 ~random_access_iterator_base() =
default;
95 explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host} {}
97 constexpr random_access_iterator_base(range_type & host, position_type
const pos) noexcept :
102 template <
typename range_type2>
104 requires std::is_const_v<range_type> && !std::is_const_v<range_type2> &&
105 std::is_same_v<std::remove_const_t<range_type>, range_type2>
107 constexpr random_access_iterator_base(random_access_iterator_base<range_type2, derived_t_template>
const & rhs) noexcept :
108 host{rhs.host}, pos{rhs.pos}
118 template <
typename range_type2>
123 constexpr
bool operator==(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
125 return pos == rhs.pos;
129 template <
typename range_type2>
133 constexpr
bool operator!=(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
135 return !(*
this == rhs);
139 template <
typename range_type2>
143 constexpr
bool operator<(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
145 return static_cast<bool>(pos < rhs.pos);
149 template <
typename range_type2>
153 constexpr
bool operator>(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
155 return pos > rhs.pos;
159 template <
typename range_type2>
163 constexpr
bool operator<=(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
165 return pos <= rhs.pos;
169 template <
typename range_type2>
173 constexpr
bool operator>=(random_access_iterator_base<range_type2, derived_t_template>
const & rhs)
const noexcept
175 return pos >= rhs.pos;
183 constexpr derived_t & operator++() noexcept
187 return *this_derived();
191 constexpr derived_t operator++(
int) noexcept
193 derived_t cpy{*this_derived()};
199 constexpr derived_t & operator--() noexcept
202 return *this_derived();
206 constexpr derived_t operator--(
int) noexcept
208 derived_t cpy{*this_derived()};
214 constexpr derived_t & operator+=(difference_type
const skip) noexcept
217 return *this_derived();
221 constexpr derived_t operator+(difference_type
const skip)
const noexcept
223 derived_t cpy{*this_derived()};
228 constexpr
friend derived_t operator+(difference_type
const skip, derived_t
const & it) noexcept
234 constexpr derived_t & operator-=(difference_type
const skip) noexcept
237 return *this_derived();
241 constexpr derived_t operator-(difference_type
const skip)
const noexcept
243 derived_t cpy{*this_derived()};
248 constexpr
friend derived_t operator-(difference_type
const skip, derived_t
const & it) noexcept
254 constexpr difference_type operator-(derived_t
const lhs)
const noexcept
256 return static_cast<difference_type>(pos - lhs.pos);
264 constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
271 constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
277 constexpr reference operator[](position_type
const n)
const noexcept(noexcept((*host)[pos+n]))
279 return (*host)[pos + n];
286 constexpr derived_t* this_derived()
288 return static_cast<derived_t*>(
this);
292 constexpr derived_t
const * this_derived()
const
294 return static_cast<derived_t const *>(
this);
306 template <
typename range_type>
307 class random_access_iterator :
308 public random_access_iterator_base<range_type, random_access_iterator>
312 using base = random_access_iterator_base<range_type, random_access_iterator>;
314 using typename base::position_type;
321 using typename base::difference_type;
322 using typename base::value_type;
323 using typename base::reference;
324 using typename base::const_reference;
325 using typename base::pointer;
326 using typename base::iterator_category;