SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
random_access_iterator.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 
39 template <typename range_type, template <typename ...> typename derived_t_template>
40 class random_access_iterator_base
41 {
42 protected:
44  typename std::add_pointer_t<range_type> host{nullptr};
48  position_type pos{static_cast<position_type>(0)};
49 
51  template <typename range_type2, template <typename ...> typename derived_t_template2>
53  requires std::is_const_v<range_type> && !std::is_const_v<range_type2> &&
54  std::is_same_v<std::remove_const_t<range_type>, range_type2> &&
55  std::is_same_v<derived_t_template2, derived_t_template>
57  friend class random_access_iterator_base;
58 
60  using derived_t = derived_t_template <range_type>;
61 
62 public:
64  using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
66  using value_type = typename range_type::value_type;
69  typename range_type::const_reference,
70  typename range_type::reference>;
72  using const_reference = typename range_type::const_reference; //TODO: there is no type trait for this, yet :o
74  using pointer = value_type *;
76  using iterator_category = std::random_access_iterator_tag;
77 
81  constexpr random_access_iterator_base() = default;
84  constexpr random_access_iterator_base(random_access_iterator_base const &) = default;
86  constexpr random_access_iterator_base & operator=(random_access_iterator_base const &) = default;
88  constexpr random_access_iterator_base (random_access_iterator_base &&) = default;
90  constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) = default;
92  ~random_access_iterator_base() = default;
93 
95  explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host} {}
97  constexpr random_access_iterator_base(range_type & host, position_type const pos) noexcept :
98  host{&host}, pos{pos}
99  {}
100 
102  template <typename range_type2>
104  requires std::is_const_v<range_type> && !std::is_const_v<range_type2> &&
105  std::is_same_v<std::remove_const_t<range_type>, range_type2>
107  constexpr random_access_iterator_base(random_access_iterator_base<range_type2, derived_t_template> const & rhs) noexcept :
108  host{rhs.host}, pos{rhs.pos}
109  {}
111 
118  template <typename range_type2>
121  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
123  constexpr bool operator==(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
124  {
125  return pos == rhs.pos;
126  }
127 
129  template <typename range_type2>
131  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 !(*this == rhs);
136  }
137 
139  template <typename range_type2>
141  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
143  constexpr bool operator<(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
144  {
145  return static_cast<bool>(pos < rhs.pos);
146  }
147 
149  template <typename range_type2>
151  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
153  constexpr bool operator>(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
154  {
155  return pos > rhs.pos;
156  }
157 
159  template <typename range_type2>
161  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
163  constexpr bool operator<=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
164  {
165  return pos <= rhs.pos;
166  }
167 
169  template <typename range_type2>
171  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
173  constexpr bool operator>=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
174  {
175  return pos >= rhs.pos;
176  }
178 
183  constexpr derived_t & operator++() noexcept
185  {
186  ++pos;
187  return *this_derived();
188  }
189 
191  constexpr derived_t operator++(int) noexcept
192  {
193  derived_t cpy{*this_derived()};
194  ++pos;
195  return cpy;
196  }
197 
199  constexpr derived_t & operator--() noexcept
200  {
201  --pos;
202  return *this_derived();
203  }
204 
206  constexpr derived_t operator--(int) noexcept
207  {
208  derived_t cpy{*this_derived()};
209  --pos;
210  return cpy;
211  }
212 
214  constexpr derived_t & operator+=(difference_type const skip) noexcept
215  {
216  pos += skip;
217  return *this_derived();
218  }
219 
221  constexpr derived_t operator+(difference_type const skip) const noexcept
222  {
223  derived_t cpy{*this_derived()};
224  return cpy += skip;
225  }
226 
228  constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept
229  {
230  return it + skip;
231  }
232 
234  constexpr derived_t & operator-=(difference_type const skip) noexcept
235  {
236  pos -= skip;
237  return *this_derived();
238  }
239 
241  constexpr derived_t operator-(difference_type const skip) const noexcept
242  {
243  derived_t cpy{*this_derived()};
244  return cpy -= skip;
245  }
246 
248  constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
249  {
250  return it - skip;
251  }
252 
254  constexpr difference_type operator-(derived_t const lhs) const noexcept
255  {
256  return static_cast<difference_type>(pos - lhs.pos);
257  }
259 
264  constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
266  {
267  return (*host)[pos];
268  }
269 
271  constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
272  {
273  return &host[pos];
274  }
275 
277  constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos+n]))
278  {
279  return (*host)[pos + n];
280  }
282 
283 private:
284 
286  constexpr derived_t* this_derived()
287  {
288  return static_cast<derived_t*>(this);
289  }
290 
292  constexpr derived_t const * this_derived() const
293  {
294  return static_cast<derived_t const *>(this);
295  }
296 };
297 
306 template <typename range_type>
307 class random_access_iterator :
308  public random_access_iterator_base<range_type, random_access_iterator>
309 {
310 private:
312  using base = random_access_iterator_base<range_type, random_access_iterator>;
314  using typename base::position_type;
315 
316 public:
321  using typename base::difference_type;
322  using typename base::value_type;
323  using typename base::reference;
324  using typename base::const_reference;
325  using typename base::pointer;
326  using typename base::iterator_category;
328 
330  using base::base;
331 };
332 
333 } // namespace seqan3::detail
std::rel_ops::operator!=
T operator!=(T... args)
iterator
Provides C++20 additions to the <iterator> header.
std::random_access_iterator_tag
std::add_pointer_t
cassert
std::remove_const_t
std::conditional_t
std::make_unsigned_t