SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
random_access_iterator.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <cassert>
13#include <iterator>
14#include <type_traits>
15
17
18namespace seqan3::detail
19{
20
37template <typename range_type, template <typename...> typename derived_t_template, typename... args_t>
38class random_access_iterator_base
39{
40protected:
42 typename std::add_pointer_t<range_type> host{nullptr};
46 position_type pos{static_cast<position_type>(0)};
47
49 template <typename range_type2, template <typename...> typename derived_t_template2, typename... args2_t>
50 friend class random_access_iterator_base;
51
53 using derived_t = derived_t_template<range_type>;
54
55public:
57 using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
59 using value_type = typename range_type::value_type;
62 typename range_type::const_reference,
63 typename range_type::reference>;
65 using const_reference = typename range_type::const_reference; //TODO: there is no type trait for this, yet :o
67 using pointer = value_type *;
69 using iterator_category = std::random_access_iterator_tag;
70
75 constexpr random_access_iterator_base() = default;
77 constexpr random_access_iterator_base(random_access_iterator_base const &) = default;
79 constexpr random_access_iterator_base & operator=(random_access_iterator_base const &) = default;
81 constexpr random_access_iterator_base(random_access_iterator_base &&) = default;
83 constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) = default;
85 ~random_access_iterator_base() = default;
86
88 explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host}
89 {}
91 constexpr random_access_iterator_base(range_type & host, position_type const pos) noexcept : host{&host}, pos{pos}
92 {}
93
95 template <typename range_type2>
96 requires std::is_const_v<range_type>
97 && (!std::is_const_v<range_type2>) && std::is_same_v<std::remove_const_t<range_type>, range_type2>
98 constexpr random_access_iterator_base(
99 random_access_iterator_base<range_type2, derived_t_template> const & rhs) noexcept :
100 host{rhs.host},
101 pos{rhs.pos}
102 {}
104
112 template <typename range_type2>
113 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
114 constexpr bool operator==(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
115 {
116 return pos == rhs.pos;
117 }
118
120 template <typename range_type2>
121 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
122 constexpr bool operator!=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
123 {
124 return !(*this == rhs);
125 }
126
128 template <typename range_type2>
129 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
130 constexpr bool operator<(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
131 {
132 return static_cast<bool>(pos < rhs.pos);
133 }
134
136 template <typename range_type2>
137 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
138 constexpr bool operator>(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
139 {
140 return pos > rhs.pos;
141 }
142
144 template <typename range_type2>
145 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
146 constexpr bool operator<=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
147 {
148 return pos <= rhs.pos;
149 }
150
152 template <typename range_type2>
153 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
154 constexpr bool operator>=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
155 {
156 return pos >= rhs.pos;
157 }
159
165 constexpr derived_t & operator++() noexcept
166 {
167 ++pos;
168 return *this_derived();
169 }
170
172 constexpr derived_t operator++(int) noexcept
173 {
174 derived_t cpy{*this_derived()};
175 ++pos;
176 return cpy;
177 }
178
180 constexpr derived_t & operator--() noexcept
181 {
182 --pos;
183 return *this_derived();
184 }
185
187 constexpr derived_t operator--(int) noexcept
188 {
189 derived_t cpy{*this_derived()};
190 --pos;
191 return cpy;
192 }
193
195 constexpr derived_t & operator+=(difference_type const skip) noexcept
196 {
197 pos += skip;
198 return *this_derived();
199 }
200
202 constexpr derived_t operator+(difference_type const skip) const noexcept
203 {
204 derived_t cpy{*this_derived()};
205 return cpy += skip;
206 }
207
209 constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept
210 {
211 return it + skip;
212 }
213
215 constexpr derived_t & operator-=(difference_type const skip) noexcept
216 {
217 pos -= skip;
218 return *this_derived();
219 }
220
222 constexpr derived_t operator-(difference_type const skip) const noexcept
223 {
224 derived_t cpy{*this_derived()};
225 return cpy -= skip;
226 }
227
229 constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
230 {
231 return it - skip;
232 }
233
235 constexpr friend difference_type operator-(derived_t const & lhs, derived_t const & rhs) noexcept
236 {
237 return static_cast<difference_type>(lhs.pos - rhs.pos);
238 }
240
246 constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
247 {
248 return (*host)[pos];
249 }
250
252 constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
253 {
254 return &host[pos];
255 }
256
258 constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos + n]))
259 {
260 return (*host)[pos + n];
261 }
263
264private:
266 constexpr derived_t * this_derived()
267 {
268 return static_cast<derived_t *>(this);
269 }
270
272 constexpr derived_t const * this_derived() const
273 {
274 return static_cast<derived_t const *>(this);
275 }
276};
277
286template <typename range_type>
287class random_access_iterator : public random_access_iterator_base<range_type, random_access_iterator>
288{
289private:
291 using base = random_access_iterator_base<range_type, random_access_iterator>;
293 using typename base::position_type;
294
295public:
300 using typename base::const_reference;
301 using typename base::difference_type;
302 using typename base::iterator_category;
303 using typename base::pointer;
304 using typename base::reference;
305 using typename base::value_type;
307
309 using base::base;
310};
311
312} // namespace seqan3::detail
T is_same_v
T operator!=(T... args)
Provides platform and dependency checks.
Hide me