SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
random_access_iterator.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2021, 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 <seqan3/std/iterator>
17 #include <type_traits>
18 
19 #include <seqan3/core/platform.hpp>
20 
21 namespace seqan3::detail
22 {
23 
40 template <typename range_type, template <typename ...> typename derived_t_template>
41 class random_access_iterator_base
42 {
43 protected:
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>
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;
59 
61  using derived_t = derived_t_template <range_type>;
62 
63 public:
65  using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
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; //TODO: there is no type trait for this, yet :o
75  using pointer = value_type *;
77  using iterator_category = std::random_access_iterator_tag;
78 
83  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;
94 
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 :
99  host{&host}, pos{pos}
100  {}
101 
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}
110  {}
112 
120  template <typename range_type2>
122  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
124  constexpr bool operator==(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
125  {
126  return pos == rhs.pos;
127  }
128 
130  template <typename range_type2>
132  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
134  constexpr bool operator!=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
135  {
136  return !(*this == rhs);
137  }
138 
140  template <typename range_type2>
142  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 static_cast<bool>(pos < rhs.pos);
147  }
148 
150  template <typename range_type2>
152  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  }
158 
160  template <typename range_type2>
162  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
164  constexpr bool operator<=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
165  {
166  return pos <= rhs.pos;
167  }
168 
170  template <typename range_type2>
172  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
174  constexpr bool operator>=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
175  {
176  return pos >= rhs.pos;
177  }
179 
185  constexpr derived_t & operator++() noexcept
186  {
187  ++pos;
188  return *this_derived();
189  }
190 
192  constexpr derived_t operator++(int) noexcept
193  {
194  derived_t cpy{*this_derived()};
195  ++pos;
196  return cpy;
197  }
198 
200  constexpr derived_t & operator--() noexcept
201  {
202  --pos;
203  return *this_derived();
204  }
205 
207  constexpr derived_t operator--(int) noexcept
208  {
209  derived_t cpy{*this_derived()};
210  --pos;
211  return cpy;
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 derived_t & operator-=(difference_type const skip) noexcept
236  {
237  pos -= skip;
238  return *this_derived();
239  }
240 
242  constexpr derived_t operator-(difference_type const skip) const noexcept
243  {
244  derived_t cpy{*this_derived()};
245  return cpy -= skip;
246  }
247 
249  constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
250  {
251  return it - skip;
252  }
253 
255  constexpr friend difference_type operator-(derived_t const & lhs, derived_t const & rhs) noexcept
256  {
257  return static_cast<difference_type>(lhs.pos - rhs.pos);
258  }
260 
266  constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
267  {
268  return (*host)[pos];
269  }
270 
272  constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
273  {
274  return &host[pos];
275  }
276 
278  constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos+n]))
279  {
280  return (*host)[pos + n];
281  }
283 
284 private:
285 
287  constexpr derived_t* this_derived()
288  {
289  return static_cast<derived_t*>(this);
290  }
291 
293  constexpr derived_t const * this_derived() const
294  {
295  return static_cast<derived_t const *>(this);
296  }
297 };
298 
307 template <typename range_type>
308 class random_access_iterator :
309  public random_access_iterator_base<range_type, random_access_iterator>
310 {
311 private:
313  using base = random_access_iterator_base<range_type, random_access_iterator>;
315  using typename base::position_type;
316 
317 public:
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;
329 
331  using base::base;
332 };
333 
334 } // namespace seqan3::detail
T is_same_v
Provides C++20 additions to the <iterator> header.
T operator!=(T... args)
Provides platform and dependency checks.