BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
random_access_iterator.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
5// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
6// shipped with this file and also available at: https://github.com/biocpp/biocpp-core/blob/main/LICENSE.md
7// -----------------------------------------------------------------------------------------------------
8
14#pragma once
15
16#include <cassert>
17#include <iterator>
18#include <type_traits>
19
20#include <bio/core.hpp>
21
22namespace bio::ranges::detail
23{
24
41template <typename range_type, template <typename...> typename derived_t_template>
42class random_access_iterator_base
43{
44protected:
46 typename std::add_pointer_t<range_type> host{nullptr};
50 position_type pos{static_cast<position_type>(0)};
51
53 template <typename, template <typename...> typename>
54 friend class random_access_iterator_base;
55
57 using derived_t = derived_t_template<range_type>;
58
59public:
61 using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
63 using value_type = typename range_type::value_type;
65 using reference = std::
66 conditional_t<std::is_const_v<range_type>, typename range_type::const_reference, typename range_type::reference>;
68 using const_reference = typename range_type::const_reference; //TODO: there is no type trait for this, yet :o
70 using pointer = value_type *;
72 using iterator_category = std::random_access_iterator_tag;
73
78 constexpr random_access_iterator_base() noexcept = default;
80 constexpr random_access_iterator_base(random_access_iterator_base const &) noexcept = default;
82 constexpr random_access_iterator_base & operator=(random_access_iterator_base const &) noexcept = default;
84 constexpr random_access_iterator_base(random_access_iterator_base &&) noexcept = default;
86 constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) noexcept = default;
88 ~random_access_iterator_base() noexcept = default;
89
91 explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host} {}
93 constexpr random_access_iterator_base(range_type & host, position_type const pos) noexcept : host{&host}, pos{pos}
94 {}
95
97 template <typename range_type2>
98 requires(std::is_const_v<range_type> && (!std::is_const_v<range_type2>) &&
100 constexpr random_access_iterator_base(
101 random_access_iterator_base<range_type2, derived_t_template> const & rhs) noexcept :
102 host{rhs.host}, pos{rhs.pos}
103 {}
105
113 constexpr friend bool operator==(derived_t const & lhs, derived_t const & rhs) noexcept
114 {
115 return lhs.pos == rhs.pos;
116 }
117
119 constexpr friend auto operator<=>(derived_t const & lhs, derived_t const & rhs) noexcept
120 {
121 return lhs.pos <=> rhs.pos;
122 }
124
130 constexpr derived_t & operator++() noexcept
131 {
132 ++pos;
133 return *this_derived();
134 }
135
137 constexpr derived_t operator++(int) noexcept
138 {
139 derived_t cpy{*this_derived()};
140 ++pos;
141 return cpy;
142 }
143
145 constexpr derived_t & operator--() noexcept
146 {
147 --pos;
148 return *this_derived();
149 }
150
152 constexpr derived_t operator--(int) noexcept
153 {
154 derived_t cpy{*this_derived()};
155 --pos;
156 return cpy;
157 }
158
160 constexpr derived_t & operator+=(difference_type const skip) noexcept
161 {
162 pos += skip;
163 return *this_derived();
164 }
165
167 constexpr derived_t operator+(difference_type const skip) const noexcept
168 {
169 derived_t cpy{*this_derived()};
170 return cpy += skip;
171 }
172
174 constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept
175 {
176 return it + skip;
177 }
178
180 constexpr derived_t & operator-=(difference_type const skip) noexcept
181 {
182 pos -= skip;
183 return *this_derived();
184 }
185
187 constexpr derived_t operator-(difference_type const skip) const noexcept
188 {
189 derived_t cpy{*this_derived()};
190 return cpy -= skip;
191 }
192
194 constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
195 {
196 return it - skip;
197 }
198
200 constexpr friend difference_type operator-(derived_t const & lhs, derived_t const & rhs) noexcept
201 {
202 return static_cast<difference_type>(lhs.pos - rhs.pos);
203 }
205
211 constexpr reference operator*() const noexcept(noexcept((*host)[pos])) { return (*host)[pos]; }
212
214 constexpr pointer operator->() const noexcept(noexcept((&host)[pos])) { return &host[pos]; }
215
217 constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos + n]))
218 {
219 return (*host)[pos + n];
220 }
222
223private:
225 constexpr derived_t * this_derived() { return static_cast<derived_t *>(this); }
226
228 constexpr derived_t const * this_derived() const { return static_cast<derived_t const *>(this); }
229};
230
239template <typename range_type>
240class random_access_iterator : public random_access_iterator_base<range_type, random_access_iterator>
241{
242private:
244 using base = random_access_iterator_base<range_type, random_access_iterator>;
246 using typename base::position_type;
247
248public:
253 using typename base::const_reference;
254 using typename base::difference_type;
255 using typename base::iterator_category;
256 using typename base::pointer;
257 using typename base::reference;
258 using typename base::value_type;
260
262 using base::base;
263};
264
265} // namespace bio::ranges::detail
Provides platform and dependency checks.
T is_same_v