SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
random_access_iterator.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2019, 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 <type_traits>
17 
18 #include <seqan3/std/iterator>
19 
20 namespace seqan3::detail
21 {
22 
41 template <typename range_type, template <typename...> typename derived_t_template>
42 class random_access_iterator_base
43 {
44 protected:
46  typename std::add_pointer_t<range_type> host{nullptr};
50  position_type pos{static_cast<position_type>(0)};
51 
53  template <typename range_type2, template <typename...> typename derived_t_template2>
55  requires std::is_const_v<range_type> && !std::is_const_v<range_type2> &&
56  std::is_same_v<std::remove_const_t<range_type>, range_type2> &&
57  std::is_same_v<derived_t_template2, derived_t_template>
59  friend class random_access_iterator_base;
60 
62  using derived_t = derived_t_template<range_type>;
63 
64 public:
66  using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
68  using value_type = typename range_type::value_type;
71  typename range_type::const_reference,
72  typename range_type::reference>;
74  using const_reference = typename range_type::const_reference; //TODO: there is no type trait for this, yet :o
76  using pointer = value_type *;
78  using iterator_category = std::random_access_iterator_tag;
79 
83  constexpr random_access_iterator_base() = default;
86  constexpr random_access_iterator_base(random_access_iterator_base const &) = default;
88  constexpr random_access_iterator_base & operator=(random_access_iterator_base const &) = default;
90  constexpr random_access_iterator_base (random_access_iterator_base &&) = default;
92  constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) = default;
94  ~random_access_iterator_base() = default;
95 
97  explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host} {}
99  constexpr random_access_iterator_base(range_type & host, position_type const pos) noexcept :
100  host{&host}, pos{pos}
101  {}
102 
104  template <typename range_type2>
106  requires std::is_const_v<range_type> && !std::is_const_v<range_type2> &&
107  std::is_same_v<std::remove_const_t<range_type>, range_type2>
109  constexpr random_access_iterator_base(random_access_iterator_base<range_type2, derived_t_template> const & rhs) noexcept :
110  host{rhs.host}, pos{rhs.pos}
111  {}
113 
120  template <typename range_type2>
123  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 pos == rhs.pos;
128  }
129 
131  template <typename range_type2>
133  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
135  constexpr bool operator!=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
136  {
137  return !(*this == rhs);
138  }
139 
141  template <typename range_type2>
143  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
145  constexpr bool operator<(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
146  {
147  return static_cast<bool>(pos < rhs.pos);
148  }
149 
151  template <typename range_type2>
153  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
155  constexpr bool operator>(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
156  {
157  return pos > rhs.pos;
158  }
159 
161  template <typename range_type2>
163  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
165  constexpr bool operator<=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
166  {
167  return pos <= rhs.pos;
168  }
169 
171  template <typename range_type2>
173  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
175  constexpr bool operator>=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
176  {
177  return pos >= rhs.pos;
178  }
180 
185  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--() noexcept
202  {
203  --pos;
204  return *this_derived();
205  }
206 
208  constexpr derived_t operator--(int) noexcept
209  {
210  derived_t cpy{*this_derived()};
211  --pos;
212  return cpy;
213  }
214 
216  constexpr derived_t & operator+=(difference_type const skip) noexcept
217  {
218  pos += skip;
219  return *this_derived();
220  }
221 
223  constexpr derived_t operator+(difference_type const skip) const noexcept
224  {
225  derived_t cpy{*this_derived()};
226  return cpy += skip;
227  }
228 
230  constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept
231  {
232  return it + skip;
233  }
234 
236  constexpr derived_t & operator-=(difference_type const skip) noexcept
237  {
238  pos -= skip;
239  return *this_derived();
240  }
241 
243  constexpr derived_t operator-(difference_type const skip) const noexcept
244  {
245  derived_t cpy{*this_derived()};
246  return cpy -= skip;
247  }
248 
250  constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
251  {
252  return it - skip;
253  }
254 
256  constexpr difference_type operator-(derived_t const lhs) const noexcept
257  {
258  return static_cast<difference_type>(pos - lhs.pos);
259  }
261 
266  constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
268  {
269  return (*host)[pos];
270  }
271 
273  constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
274  {
275  return &host[pos];
276  }
277 
279  constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos+n]))
280  {
281  return (*host)[pos + n];
282  }
284 
285 private:
286 
288  constexpr derived_t* this_derived()
289  {
290  return static_cast<derived_t*>(this);
291  }
292 
294  constexpr derived_t const * this_derived() const
295  {
296  return static_cast<derived_t const *>(this);
297  }
298 };
299 
308 template <typename range_type>
309 class random_access_iterator :
310  public random_access_iterator_base<range_type, random_access_iterator>
311 {
312 private:
314  using base = random_access_iterator_base<range_type, random_access_iterator>;
316  using typename base::position_type;
317 
318 public:
323  using typename base::difference_type;
324  using typename base::value_type;
325  using typename base::reference;
326  using typename base::const_reference;
327  using typename base::pointer;
328  using typename base::iterator_category;
330 
332  using base::base;
333 };
334 
335 } // namespace seqan3::detail
bool operator>(type const &lhs, type const &rhs)
Less-than, greater-than and -or-equal comparisons.
Provides C++20 additions to the <iterator> header.
bool operator!=(type const &lhs, type const &rhs)
(In-)Equality comparison.
t & operator=(t1 const &rhs)
Assignment operator.
bool operator==(type const &lhs, type const &rhs)
(In-)Equality comparison.
bool operator>=(type const &lhs, type const &rhs)
Less-than, greater-than and -or-equal comparisons.
Definition: aligned_sequence_concept.hpp:35