SeqAn3
inherited_iterator_base.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/ranges>
49 #include <seqan3/std/iterator>
50 
51 namespace seqan3::detail
52 {
53 
75 template <typename derived_t, std::Iterator base_t>
76 class inherited_iterator_base : public base_t
77 {
78 public:
83  using difference_type = typename std::iterator_traits<base_t>::difference_type;
84  using value_type = typename std::iterator_traits<base_t>::value_type;
85  using reference = typename std::iterator_traits<base_t>::reference;
86  using pointer = typename std::iterator_traits<base_t>::pointer;
87  using iterator_category = typename std::iterator_traits<base_t>::iterator_category;
89 
93  inherited_iterator_base() = default;
94  constexpr inherited_iterator_base(inherited_iterator_base const & rhs) = default;
95  constexpr inherited_iterator_base(inherited_iterator_base && rhs) = default;
96  constexpr inherited_iterator_base & operator=(inherited_iterator_base const & rhs) = default;
97  constexpr inherited_iterator_base & operator=(inherited_iterator_base && rhs) = default;
98  ~inherited_iterator_base() = default;
99 
100  inherited_iterator_base(base_t it) : base_t{it} {}
102 
107  constexpr bool operator==(derived_t const & rhs) const noexcept(noexcept(base_t{} == base_t{}))
109  requires std::EqualityComparable<base_t>
111  {
112  return *this_to_base() == static_cast<base_t>(rhs);
113  }
114 
115  constexpr bool operator!=(derived_t const & rhs) const noexcept(noexcept(base_t{} == base_t{}))
117  requires std::EqualityComparable<base_t>
119  {
120  return !(*this == rhs);
121  }
122 
123  constexpr bool operator<(derived_t const & rhs) const noexcept(noexcept(base_t{} < base_t{}))
127  {
128  return *this_to_base() < static_cast<base_t>(rhs);
129  }
130 
131  constexpr bool operator>(derived_t const & rhs) const noexcept(noexcept(base_t{} > base_t{}))
135  {
136  return *this_to_base() > static_cast<base_t>(rhs);
137  }
138 
139  constexpr bool operator<=(derived_t const & rhs) const noexcept(noexcept(base_t{} < base_t{}))
143  {
144  return !(*this > rhs);
145  }
146 
147  constexpr bool operator>=(derived_t const & rhs) const noexcept(noexcept(base_t{} < base_t{}))
151  {
152  return !(*this < rhs);
153  }
155 
160  constexpr derived_t & operator++() noexcept(noexcept(++base_t{}))
163  requires std::InputIterator<base_t>
165  {
166  ++(*this_to_base());
167  return *this_derived();
168  }
169 
171  constexpr derived_t operator++(int) noexcept(noexcept(++base_t{}))
175  {
176  inherited_iterator_base cpy{*this};
177  ++(*this_derived());
178  return static_cast<derived_t>(cpy);
179  }
180 
182  constexpr derived_t & operator--() noexcept(noexcept(--base_t{}))
184  requires std::BidirectionalIterator<base_t>
186  {
187  --(*this_to_base());
188  return *this_derived();
189  }
190 
192  constexpr derived_t operator--(int) noexcept(noexcept(--base_t{}))
196  {
197  inherited_iterator_base cpy{*this};
198  --(*this);
199  return static_cast<derived_t>(cpy);
200  }
201 
203  constexpr derived_t & operator+=(difference_type const skip) noexcept(noexcept(base_t{} += skip))
205  requires std::RandomAccessIterator<base_t>
207  {
208  *this_to_base() += skip;
209  return *this_derived();
210  }
211 
213  constexpr derived_t operator+(difference_type const skip) const noexcept(noexcept(base_t{} += skip))
215  requires std::RandomAccessIterator<base_t>
217  {
218  derived_t cpy{*this_derived()};
219  return cpy += skip;
220  }
221 
223  constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept(noexcept(base_t{} += skip))
225  requires std::RandomAccessIterator<base_t>
227  {
228  return it + skip;
229  }
230 
232  constexpr derived_t & operator-=(difference_type const skip) noexcept(noexcept(base_t{} -= skip))
234  requires std::RandomAccessIterator<base_t>
236  {
237  *this_to_base() -= skip;
238  return *this_derived();
239  }
240 
242  constexpr derived_t operator-(difference_type const skip) const noexcept(noexcept(base_t{} -= skip))
244  requires std::RandomAccessIterator<base_t>
246  {
247  derived_t cpy{*this_derived()};
248  return cpy -= skip;
249  }
250 
252  constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept(noexcept(base_t{} -= skip))
254  requires std::RandomAccessIterator<base_t>
256  {
257  return it - skip;
258  }
259 
261  constexpr difference_type operator-(derived_t const rhs) const noexcept
265  {
266  assert(static_cast<base_t>(rhs) > *this_to_base());
267  return static_cast<difference_type>(*this_to_base() - static_cast<base_t>(rhs));
268  }
270 
274  constexpr reference operator*() const noexcept(noexcept(*base_t{}))
277  requires std::InputIterator<base_t>
279  {
280  return **this_to_base();
281  }
282 
284  constexpr pointer operator->() const noexcept(noexcept(*base_t{}))
286  requires std::InputIterator<base_t>
288  {
289  return &*this_to_base();
290  }
291 
293  constexpr reference operator[](std::make_signed_t<difference_type> const n) const noexcept(noexcept(base_t{}[0]))
295  requires std::RandomAccessIterator<base_t>
297  {
298  return this_to_base()[n];
299  }
301 
302 private:
303 
305  derived_t * this_derived()
306  {
307  return static_cast<derived_t*>(this);
308  }
309 
311  derived_t const * this_derived() const
312  {
313  return static_cast<derived_t const *>(this);
314  }
315 
317  base_t * this_to_base()
318  {
319  return static_cast<base_t*>(this);
320  }
321 
323  base_t const * this_to_base() const
324  {
325  return static_cast<base_t const *>(this);
326  }
327 };
328 
329 } // namespace seqan3::detail
The concept RandomAccessIterator refines std::BidirectionalIterator by adding support for constant ti...
Provides C++20 additions to the <iterator> header.
SeqAn specific customisations in the standard namespace.
Definition: align_result.hpp:221
The InputIterator concept is a refinement of std::Iterator, adding the requirement that the reference...
t & operator=(t1 const &rhs)
Assignment operator.
Adaptations of concepts from the Ranges TS.
Definition: aligned_sequence_concept.hpp:288
Provides C++20 additions to the type_traits header.
The concept BidirectionalIterator refines std::ForwardIterator by adding the ability to move an itera...
Requires std::EqualityComparable and all remaing comparison operators (<, <=, >, >=).