SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
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 requires std::is_const_v<range_type>
54 && (!std::is_const_v<range_type2>) && std::is_same_v<std::remove_const_t<range_type>, range_type2>
55 && std::is_same_v<derived_t_template2<args2_t...>, derived_t_template<args_t...>>
56 friend class random_access_iterator_base;
57
59 using derived_t = derived_t_template<range_type>;
60
61public:
63 using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
65 using value_type = typename range_type::value_type;
68 typename range_type::const_reference,
69 typename range_type::reference>;
71 using const_reference = typename range_type::const_reference; //TODO: there is no type trait for this, yet :o
73 using pointer = value_type *;
75 using iterator_category = std::random_access_iterator_tag;
76
81 constexpr random_access_iterator_base() = default;
83 constexpr random_access_iterator_base(random_access_iterator_base const &) = default;
85 constexpr random_access_iterator_base & operator=(random_access_iterator_base const &) = default;
87 constexpr random_access_iterator_base(random_access_iterator_base &&) = default;
89 constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) = default;
91 ~random_access_iterator_base() = default;
92
94 explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host}
95 {}
97 constexpr random_access_iterator_base(range_type & host, position_type const pos) noexcept : host{&host}, pos{pos}
98 {}
99
101 template <typename range_type2>
102 requires std::is_const_v<range_type>
103 && (!std::is_const_v<range_type2>) && std::is_same_v<std::remove_const_t<range_type>, range_type2>
104 constexpr random_access_iterator_base(
105 random_access_iterator_base<range_type2, derived_t_template> const & rhs) noexcept :
106 host{rhs.host},
107 pos{rhs.pos}
108 {}
110
118 template <typename range_type2>
119 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
120 constexpr bool operator==(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
121 {
122 return pos == rhs.pos;
123 }
124
126 template <typename range_type2>
127 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
128 constexpr bool operator!=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
129 {
130 return !(*this == rhs);
131 }
132
134 template <typename range_type2>
135 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
136 constexpr bool operator<(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
137 {
138 return static_cast<bool>(pos < rhs.pos);
139 }
140
142 template <typename range_type2>
143 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
144 constexpr bool operator>(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
145 {
146 return pos > rhs.pos;
147 }
148
150 template <typename range_type2>
151 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
152 constexpr bool operator<=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
153 {
154 return pos <= rhs.pos;
155 }
156
158 template <typename range_type2>
159 requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
160 constexpr bool operator>=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
161 {
162 return pos >= rhs.pos;
163 }
165
171 constexpr derived_t & operator++() noexcept
172 {
173 ++pos;
174 return *this_derived();
175 }
176
178 constexpr derived_t operator++(int) noexcept
179 {
180 derived_t cpy{*this_derived()};
181 ++pos;
182 return cpy;
183 }
184
186 constexpr derived_t & operator--() noexcept
187 {
188 --pos;
189 return *this_derived();
190 }
191
193 constexpr derived_t operator--(int) noexcept
194 {
195 derived_t cpy{*this_derived()};
196 --pos;
197 return cpy;
198 }
199
201 constexpr derived_t & operator+=(difference_type const skip) noexcept
202 {
203 pos += skip;
204 return *this_derived();
205 }
206
208 constexpr derived_t operator+(difference_type const skip) const noexcept
209 {
210 derived_t cpy{*this_derived()};
211 return cpy += skip;
212 }
213
215 constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept
216 {
217 return it + skip;
218 }
219
221 constexpr derived_t & operator-=(difference_type const skip) noexcept
222 {
223 pos -= skip;
224 return *this_derived();
225 }
226
228 constexpr derived_t operator-(difference_type const skip) const noexcept
229 {
230 derived_t cpy{*this_derived()};
231 return cpy -= skip;
232 }
233
235 constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
236 {
237 return it - skip;
238 }
239
241 constexpr friend difference_type operator-(derived_t const & lhs, derived_t const & rhs) noexcept
242 {
243 return static_cast<difference_type>(lhs.pos - rhs.pos);
244 }
246
252 constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
253 {
254 return (*host)[pos];
255 }
256
258 constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
259 {
260 return &host[pos];
261 }
262
264 constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos + n]))
265 {
266 return (*host)[pos + n];
267 }
269
270private:
272 constexpr derived_t * this_derived()
273 {
274 return static_cast<derived_t *>(this);
275 }
276
278 constexpr derived_t const * this_derived() const
279 {
280 return static_cast<derived_t const *>(this);
281 }
282};
283
292template <typename range_type>
293class random_access_iterator : public random_access_iterator_base<range_type, random_access_iterator>
294{
295private:
297 using base = random_access_iterator_base<range_type, random_access_iterator>;
299 using typename base::position_type;
300
301public:
306 using typename base::const_reference;
307 using typename base::difference_type;
308 using typename base::iterator_category;
309 using typename base::pointer;
310 using typename base::reference;
311 using typename base::value_type;
313
315 using base::base;
316};
317
318} // namespace seqan3::detail
T is_same_v
T operator!=(T... args)
Provides platform and dependency checks.