SeqAn3 3.3.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// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#include <cassert>
16#include <iterator>
17#include <type_traits>
18
20
21namespace seqan3::detail
22{
23
40template <typename range_type, template <typename...> typename derived_t_template, typename... args_t>
41class random_access_iterator_base
42{
43protected:
45 typename std::add_pointer_t<range_type> host{nullptr};
49 position_type pos{static_cast<position_type>(0)};
50
52 template <typename range_type2, template <typename...> typename derived_t_template2, typename... args2_t>
53 friend class random_access_iterator_base;
54
56 using derived_t = derived_t_template<range_type>;
57
58public:
60 using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
62 using value_type = typename range_type::value_type;
65 typename range_type::const_reference,
66 typename range_type::reference>;
68 using const_reference = typename range_type::const_reference; //TODO: there is no type trait for this, yet :o
70 using pointer = value_type *;
72 using iterator_category = std::random_access_iterator_tag;
73
78 constexpr random_access_iterator_base() = default;
80 constexpr random_access_iterator_base(random_access_iterator_base const &) = default;
82 constexpr random_access_iterator_base & operator=(random_access_iterator_base const &) = default;
84 constexpr random_access_iterator_base(random_access_iterator_base &&) = default;
86 constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) = default;
88 ~random_access_iterator_base() = default;
89
91 explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host}
92 {}
94 constexpr random_access_iterator_base(range_type & host, position_type const pos) noexcept : host{&host}, pos{pos}
95 {}
96
98 template <typename range_type2>
99 requires std::is_const_v<range_type>
100 && (!std::is_const_v<range_type2>) && std::is_same_v<std::remove_const_t<range_type>, range_type2>
101 constexpr random_access_iterator_base(
102 random_access_iterator_base<range_type2, derived_t_template> const & rhs) noexcept :
103 host{rhs.host},
104 pos{rhs.pos}
105 {}
107
115 template <typename range_type2>
116 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
117 constexpr bool operator==(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
118 {
119 return pos == rhs.pos;
120 }
121
123 template <typename range_type2>
124 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
125 constexpr bool operator!=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
126 {
127 return !(*this == rhs);
128 }
129
131 template <typename range_type2>
132 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
133 constexpr bool operator<(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
134 {
135 return static_cast<bool>(pos < rhs.pos);
136 }
137
139 template <typename range_type2>
140 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
141 constexpr bool operator>(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
142 {
143 return pos > rhs.pos;
144 }
145
147 template <typename range_type2>
148 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
149 constexpr bool operator<=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
150 {
151 return pos <= rhs.pos;
152 }
153
155 template <typename range_type2>
156 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
157 constexpr bool operator>=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
158 {
159 return pos >= rhs.pos;
160 }
162
168 constexpr derived_t & operator++() noexcept
169 {
170 ++pos;
171 return *this_derived();
172 }
173
175 constexpr derived_t operator++(int) noexcept
176 {
177 derived_t cpy{*this_derived()};
178 ++pos;
179 return cpy;
180 }
181
183 constexpr derived_t & operator--() noexcept
184 {
185 --pos;
186 return *this_derived();
187 }
188
190 constexpr derived_t operator--(int) noexcept
191 {
192 derived_t cpy{*this_derived()};
193 --pos;
194 return cpy;
195 }
196
198 constexpr derived_t & operator+=(difference_type const skip) noexcept
199 {
200 pos += skip;
201 return *this_derived();
202 }
203
205 constexpr derived_t operator+(difference_type const skip) const noexcept
206 {
207 derived_t cpy{*this_derived()};
208 return cpy += skip;
209 }
210
212 constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept
213 {
214 return it + skip;
215 }
216
218 constexpr derived_t & operator-=(difference_type const skip) noexcept
219 {
220 pos -= skip;
221 return *this_derived();
222 }
223
225 constexpr derived_t operator-(difference_type const skip) const noexcept
226 {
227 derived_t cpy{*this_derived()};
228 return cpy -= skip;
229 }
230
232 constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
233 {
234 return it - skip;
235 }
236
238 constexpr friend difference_type operator-(derived_t const & lhs, derived_t const & rhs) noexcept
239 {
240 return static_cast<difference_type>(lhs.pos - rhs.pos);
241 }
243
249 constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
250 {
251 return (*host)[pos];
252 }
253
255 constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
256 {
257 return &host[pos];
258 }
259
261 constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos + n]))
262 {
263 return (*host)[pos + n];
264 }
266
267private:
269 constexpr derived_t * this_derived()
270 {
271 return static_cast<derived_t *>(this);
272 }
273
275 constexpr derived_t const * this_derived() const
276 {
277 return static_cast<derived_t const *>(this);
278 }
279};
280
289template <typename range_type>
290class random_access_iterator : public random_access_iterator_base<range_type, random_access_iterator>
291{
292private:
294 using base = random_access_iterator_base<range_type, random_access_iterator>;
296 using typename base::position_type;
297
298public:
303 using typename base::const_reference;
304 using typename base::difference_type;
305 using typename base::iterator_category;
306 using typename base::pointer;
307 using typename base::reference;
308 using typename base::value_type;
310
312 using base::base;
313};
314
315} // namespace seqan3::detail
T is_same_v
T operator!=(T... args)
Provides platform and dependency checks.