xtd 1.0.0
Loading...
Searching...
No Matches
enumerable_iterators.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "../enumerator.hpp"
6#include "../../../npos.hpp"
8#include "../../../self.hpp"
9#include "../../../usize.hpp"
10#include <compare>
11#include <limits>
12
14namespace xtd {
16 namespace collections {
18 namespace generic {
20 namespace extensions {
54 template<typename type_t, typename enumerable_t>
57 template<typename iterator_enumerable_t>
58 class enumerable_iterator {
59 public:
60 using value_type = type_t;
61 using iterator_category = std::forward_iterator_tag;
62 using iterator_concept = std::forward_iterator_tag;
64 using pointer = value_type*;
65 using reference = value_type&;
66
67 static constexpr auto npos() -> xtd::usize {return std::numeric_limits<xtd::usize>::max();}
68
69 enumerable_iterator() = default;
70 enumerable_iterator(iterator_enumerable_t& enumerable, xtd::usize pos) : enumerable_ {&enumerable}, enumerator_ {enumerable.get_enumerator()}, pos_ {pos} {reset();}
71 enumerable_iterator(enumerable_iterator&& value) noexcept = default;
72 enumerable_iterator(const enumerable_iterator& value) noexcept : enumerable_(value.enumerable_), enumerator_(value.enumerable_->get_enumerator()), pos_ {value.pos_} {reset();}
73 auto operator =(enumerable_iterator&& value) noexcept -> enumerable_iterator& = default;
74 auto operator =(const enumerable_iterator& value) noexcept -> enumerable_iterator& {
75 enumerable_ = value.enumerable_;
76 enumerator_ = value.enumerable_->get_enumerator();
77 pos_ = value.pos_;
78 reset();
79 return const_cast<enumerable_iterator&>(*this);
80 }
81
82 auto operator <=>(const enumerable_iterator& rhs) const noexcept -> std::strong_ordering {return pos_ <=> rhs.pos_;}
83 auto operator ==(const enumerable_iterator& rhs) const noexcept -> bool {return pos_ == rhs.pos_;}
84 auto operator *() const -> reference {return const_cast<value_type&>(enumerator_.current());}
85 auto operator ->() const -> pointer {return &operator*();}
86
87 auto operator ++() -> enumerable_iterator& {
88 if (pos_ != npos()) pos_ = enumerator_.move_next() ? pos_ + 1 : npos();
89 return const_cast<enumerable_iterator&>(*this);
90 }
91 auto operator ++(int) -> enumerable_iterator {
92 auto current = *this;
93 operator ++();
94 return current;
95 }
96
97 template<typename value_t>
98 auto operator +(value_t value) const noexcept -> const enumerable_iterator {return enumerable_iterator {*enumerable_, pos_ + value};}
99 template<typename value_t>
100 auto operator +(value_t value) noexcept -> enumerable_iterator {return enumerable_iterator {*enumerable_, pos_ + value};}
101 template<typename value_t>
102 auto operator +=(value_t value) noexcept -> enumerable_iterator& {
103 *this = *this + value;
104 return *this;
105 }
106 auto operator -(enumerable_iterator value) const noexcept -> difference_type {
107 if (pos_ == npos()) return npos();
108 return static_cast<difference_type>(pos_ - value.pos_);
109 }
110
111 explicit operator enumerable_iterator<const iterator_enumerable_t>() const noexcept {return enumerable_iterator<const iterator_enumerable_t>(*enumerable_, pos_);}
112
113 private:
114 auto reset() -> void {
115 if (pos_ == npos()) return;
116 try {
117 enumerator_.reset();
118 } catch(...) {
119 if (pos_ != 0 && pos_ != npos()) throw;
120 if (enumerator_.move_next() == false) pos_ = npos();
121 return;
122 }
123 for (auto index = xtd::usize {}; index <= pos_; ++index)
124 if (enumerator_.move_next() == false) {
125 pos_ = npos();
126 break;
127 }
128 }
129
130 iterator_enumerable_t* enumerable_ = nullptr;
131 enumerator<type_t> enumerator_;
132 xtd::usize pos_ = 0;
133 };
135
136 public:
138
141 using iterator = enumerable_iterator<enumerable_t>;
143 using const_iterator = enumerable_iterator<const enumerable_t>;
145
147
151 auto begin() const -> const_iterator {return cbegin();}
154 auto begin() -> iterator {return iterator {self(), 0};}
155
158 auto cbegin() const -> const_iterator {return const_iterator {self(), 0};}
159
162 auto cend() const -> const_iterator {return const_iterator {self(), const_iterator::npos()};}
163
166 auto end() const -> const_iterator {return cend();}
169 auto end() -> iterator {return iterator {self(), iterator::npos()};}
171
173
183 template<typename source_collection_t, typename target_collection_t>
184 static auto to_const_iterator(typename source_collection_t::const_iterator& value, const source_collection_t& source_collection, const target_collection_t& target_collection) noexcept -> typename target_collection_t::const_iterator {
185 if (value == source_collection.cbegin()) return target_collection.cbegin();
186 if (value == source_collection.cend()) return target_collection.cend();
187
188 auto result = target_collection.cbegin();
189 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
190 return result;
191 }
192
201 template<typename source_collection_t, typename target_collection_t>
202 static auto to_const_iterator(typename source_collection_t::const_iterator& value, source_collection_t& source_collection, target_collection_t& target_collection) noexcept -> typename target_collection_t::const_iterator {
203 if (value == source_collection.cbegin()) return target_collection.cbegin();
204 if (value == source_collection.cend()) return target_collection.cend();
205
206 auto result = target_collection.cbegin();
207 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
208 return result;
209 }
210
219 template<typename source_collection_t, typename target_collection_t>
220 static auto to_iterator(typename source_collection_t::const_iterator& value, const source_collection_t& source_collection, const target_collection_t& target_collection) noexcept -> typename target_collection_t::const_iterator {
221 if (value == source_collection.cbegin()) return target_collection.cbegin();
222 if (value == source_collection.cend()) return target_collection.cend();
223
224 auto result = target_collection.cbegin();
225 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
226 return result;
227 }
228
237 template<typename source_collection_t, typename target_collection_t>
238 static auto to_iterator(typename source_collection_t::iterator& value, const source_collection_t& source_collection, const target_collection_t& target_collection) noexcept -> typename target_collection_t::iterator {
239 if (value == source_collection.begin()) return target_collection.begin();
240 if (value == source_collection.end()) return target_collection.end();
241
242 auto result = target_collection.begin();
243 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
244 return result;
245 }
246
255 template<typename source_collection_t, typename target_collection_t>
256 static auto to_iterator(typename source_collection_t::const_iterator& value, source_collection_t& source_collection, target_collection_t& target_collection) noexcept -> typename target_collection_t::const_iterator {
257 if (value == source_collection.cbegin()) return target_collection.cbegin();
258 if (value == source_collection.cend()) return target_collection.cend();
259
260 auto result = target_collection.cbegin();
261 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
262 return result;
263 }
264
273 template<typename source_collection_t, typename target_collection_t>
274 static auto to_iterator(typename source_collection_t::iterator& value, source_collection_t& source_collection, target_collection_t& target_collection) noexcept -> typename target_collection_t::iterator {
275 if (value == source_collection.begin()) return target_collection.begin();
276 if (value == source_collection.end()) return target_collection.end();
277
278 auto result = target_collection.begin();
279 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
280 return result;
281 }
282
283
284 private:
285 auto self() const noexcept -> const enumerable_t& {return static_cast<const enumerable_t&>(self_);}
286 auto self() noexcept -> enumerable_t& {return static_cast<enumerable_t&>(self_);}
287 };
288 }
289 }
290 }
291}
292
294namespace std {
295 template<typename type_t, typename enumerable_t>
296 struct iterator_traits<typename xtd::collections::generic::extensions::enumerable_iterators<type_t, enumerable_t>> {
297 using value_type = type_t;
298 using reference = const type_t&;
299 using pointer = const type_t*;
300 using difference_type = std::ptrdiff_t;
301 using iterator_category = std::input_iterator_tag;
302 };
303}
Internal enumerable iterators definition.
Definition enumerable_iterators.hpp:55
auto end() const -> const_iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:166
auto begin() const -> const_iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:151
static auto to_iterator(typename source_collection_t::const_iterator &value, source_collection_t &source_collection, target_collection_t &target_collection) noexcept -> typename target_collection_t::const_iterator
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:256
enumerable_iterator< const enumerable_t > const_iterator
Represents the const iterator of enumerable value type.
Definition enumerable_iterators.hpp:143
auto cbegin() const -> const_iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:158
auto begin() -> iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:154
auto cend() const -> const_iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:162
static auto to_iterator(typename source_collection_t::const_iterator &value, const source_collection_t &source_collection, const target_collection_t &target_collection) noexcept -> typename target_collection_t::const_iterator
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:220
enumerable_iterator< enumerable_t > iterator
Represents the iterator of enumerable value type.
Definition enumerable_iterators.hpp:141
auto end() -> iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:169
static auto to_const_iterator(typename source_collection_t::const_iterator &value, const source_collection_t &source_collection, const target_collection_t &target_collection) noexcept -> typename target_collection_t::const_iterator
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:184
static auto to_iterator(typename source_collection_t::iterator &value, const source_collection_t &source_collection, const target_collection_t &target_collection) noexcept -> typename target_collection_t::iterator
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:238
static auto to_const_iterator(typename source_collection_t::const_iterator &value, source_collection_t &source_collection, target_collection_t &target_collection) noexcept -> typename target_collection_t::const_iterator
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:202
static auto to_iterator(typename source_collection_t::iterator &value, source_collection_t &source_collection, target_collection_t &target_collection) noexcept -> typename target_collection_t::iterator
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:274
Definition enumerable.hpp:17
Contains xtd::collections::generic::enumerator <type_t> class.
#define self_
The self_ expression is a reference value expression whose value is the reference of the implicit obj...
Definition self.hpp:20
constexpr auto npos
Represents a value that is not a valid position in a collection.
Definition npos.hpp:26
std::ptrdiff_t ptrdiff
Represent the signed integer type of the result of subtracting two pointers.
Definition ptrdiff.hpp:23
std::size_t usize
Represents an unsigned size of any object in bytes.
Definition usize.hpp:22
The xtd::extensions namespace contains interface extensions.
Definition collection_common.hpp:14
The xtd::collections::generic namespace contains interfaces and classes that define generic collectio...
Definition comparer.hpp:16
The xtd::collections namespace contains interfaces and classes that define various collections of obj...
Definition any_pair.hpp:10
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
const type_t & reference
Represents the read_only_span reference type.
Definition read_only_span.hpp:73
type_t value_type
Represents the read_only_span value type.
Definition read_only_span.hpp:63
const type_t * pointer
Represents the read_only_span pointer type.
Definition read_only_span.hpp:69
xtd::ptrdiff difference_type
Represents the read_only_span difference type (usually xtd::ptrdiff).
Definition read_only_span.hpp:67
Contains xtd::npos constant.
Contains xtd::ptrdiff type.
Contains self_ keyword.
Supports a simple iteration over a generic collection.
Definition enumerator.hpp:39
Represents a type that can be used to index a collection either from the beginning or the end.
Definition index.hpp:38
Represents a value_type struct.
Definition value_type.hpp:31
Contains xtd::usize type.