SeqAn3
random_access_iterator.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
40 #pragma once
41 
42 #include <cassert>
43 #include <type_traits>
44 
45 #include <range/v3/utility/iterator_traits.hpp>
46 #include <range/v3/range_traits.hpp>
47 
48 #include <seqan3/std/iterator>
49 
50 namespace seqan3::detail
51 {
52 
71 template <typename range_type, template <typename...> typename derived_t_template>
72 class random_access_iterator_base
73 {
74 protected:
76  typename std::add_pointer_t<range_type> host{nullptr};
78  using position_type = typename range_type::size_type;
80  position_type pos{static_cast<position_type>(0)};
81 
83  template <typename range_type2, template <typename...> typename derived_t_template2>
85  requires std::is_const_v<range_type> && !std::is_const_v<range_type2> &&
86  std::is_same_v<std::remove_const_t<range_type>, range_type2> &&
87  std::is_same_v<derived_t_template2, derived_t_template>
89  friend class random_access_iterator_base;
90 
92  using derived_t = derived_t_template<range_type>;
93 
94 public:
96  using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
98  using value_type = typename range_type::value_type;
100  using reference = std::conditional_t<std::is_const_v<range_type>,
101  typename range_type::const_reference,
102  typename range_type::reference>;
104  using const_reference = typename range_type::const_reference; //TODO: there is no metafunction for this, yet :o
106  using pointer = value_type *;
108  using iterator_category = std::random_access_iterator_tag;
109 
113  constexpr random_access_iterator_base() = default;
116  constexpr random_access_iterator_base(random_access_iterator_base const &) = default;
118  constexpr random_access_iterator_base & operator=(random_access_iterator_base const &) = default;
120  constexpr random_access_iterator_base (random_access_iterator_base &&) = default;
122  constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) = default;
124  ~random_access_iterator_base() = default;
125 
127  explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host} {}
129  constexpr random_access_iterator_base(range_type & host, position_type const pos) noexcept :
130  host{&host}, pos{pos}
131  {}
132 
134  template <typename range_type2>
136  requires std::is_const_v<range_type> && !std::is_const_v<range_type2> &&
137  std::is_same_v<std::remove_const_t<range_type>, range_type2>
139  constexpr random_access_iterator_base(random_access_iterator_base<range_type2, derived_t_template> const & rhs) noexcept :
140  host{rhs.host}, pos{rhs.pos}
141  {}
143 
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 
158  template <typename range_type2>
160  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
162  constexpr bool operator!=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
163  {
164  return pos != rhs.pos;
165  }
166 
167  template <typename range_type2>
169  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
171  constexpr bool operator<(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
172  {
173  return static_cast<bool>(pos < rhs.pos);
174  }
175 
176  template <typename range_type2>
178  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
180  constexpr bool operator>(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
181  {
182  return pos > rhs.pos;
183  }
184 
185  template <typename range_type2>
187  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
189  constexpr bool operator<=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
190  {
191  return pos <= rhs.pos;
192  }
193 
194  template <typename range_type2>
196  requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
198  constexpr bool operator>=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
199  {
200  return pos >= rhs.pos;
201  }
203 
208  constexpr derived_t & operator++() noexcept
210  {
211  ++pos;
212  return *this_derived();
213  }
214 
216  constexpr derived_t operator++(int) noexcept
217  {
218  derived_t cpy{*this_derived()};
219  ++pos;
220  return cpy;
221  }
222 
224  constexpr derived_t & operator--() noexcept
225  {
226  --pos;
227  return *this_derived();
228  }
229 
231  constexpr derived_t operator--(int) noexcept
232  {
233  derived_t cpy{*this_derived()};
234  --pos;
235  return cpy;
236  }
237 
239  constexpr derived_t & operator+=(difference_type const skip) noexcept
240  {
241  pos += skip;
242  return *this_derived();
243  }
244 
246  constexpr derived_t operator+(difference_type const skip) const noexcept
247  {
248  derived_t cpy{*this_derived()};
249  return cpy += skip;
250  }
251 
253  constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept
254  {
255  return it + skip;
256  }
257 
259  constexpr derived_t & operator-=(difference_type const skip) noexcept
260  {
261  pos -= skip;
262  return *this_derived();
263  }
264 
266  constexpr derived_t operator-(difference_type const skip) const noexcept
267  {
268  derived_t cpy{*this_derived()};
269  return cpy -= skip;
270  }
271 
273  constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
274  {
275  return it - skip;
276  }
277 
279  constexpr difference_type operator-(derived_t const lhs) const noexcept
280  {
281  return static_cast<difference_type>(pos - lhs.pos);
282  }
284 
289  constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
291  {
292  return (*host)[pos];
293  }
294 
296  constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
297  {
298  return &host[pos];
299  }
300 
302  constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos+n]))
303  {
304  return (*host)[pos + n];
305  }
307 
308 private:
309 
311  derived_t* this_derived()
312  {
313  return static_cast<derived_t*>(this);
314  }
315 
317  derived_t const * this_derived() const
318  {
319  return static_cast<derived_t const *>(this);
320  }
321 };
322 
331 template <typename range_type>
332 class random_access_iterator :
333  public random_access_iterator_base<range_type, random_access_iterator>
334 {
335 private:
337  using base = random_access_iterator_base<range_type, random_access_iterator>;
339  using typename base::position_type;
340 
341 public:
346  using typename base::difference_type;
347  using typename base::value_type;
348  using typename base::reference;
349  using typename base::const_reference;
350  using typename base::pointer;
351  using typename base::iterator_category;
353 
355  using base::base;
356 };
357 
358 } // 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:288
Provides C++20 additions to the type_traits header.