xtd 0.2.0
Loading...
Searching...
No Matches
enumerable_iterators.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "../enumerator.hpp"
9#include "../../../self.hpp"
10#include "../../../size.hpp"
11#include <limits>
12
14namespace xtd {
16 namespace collections {
18 namespace generic {
20 namespace extensions {
48 template<class type_t, class enumerable_t>
51 template<class iterator_enumerable_t>
52 class enumerable_iterator : public xtd::icomparable<enumerable_iterator<iterator_enumerable_t>>, public xtd::iequatable<enumerable_iterator<iterator_enumerable_t >> {
53 public:
54 using value_type = type_t;
55 using iterator_category = std::forward_iterator_tag;
56 using iterator_concept = std::forward_iterator_tag;
57 using difference_type = xtd::ptrdiff;
58 using pointer = value_type*;
59 using reference = value_type&;
60
61 static constexpr auto npos() -> xtd::size {return std::numeric_limits<xtd::size>::max();}
62
63 enumerable_iterator() = default;
64 enumerable_iterator(iterator_enumerable_t& enumerable, xtd::size pos) : enumerable_ {&enumerable}, enumerator_ {enumerable.get_enumerator()}, pos_ {pos} {reset();}
65 enumerable_iterator(enumerable_iterator&& value) noexcept = default;
66 enumerable_iterator(const enumerable_iterator& value) noexcept : enumerable_(value.enumerable_), enumerator_(value.enumerable_->get_enumerator()), pos_ {value.pos_} {reset();}
67 auto operator =(enumerable_iterator&& value) noexcept -> enumerable_iterator& = default;
68 auto operator =(const enumerable_iterator& value) noexcept -> enumerable_iterator& {
69 enumerable_ = value.enumerable_;
70 enumerator_ = value.enumerable_->get_enumerator();
71 pos_ = value.pos_;
72 reset();
73 return const_cast<enumerable_iterator&>(*this);
74 }
75
76 auto compare_to(const enumerable_iterator& rhs) const noexcept -> int32 override {return pos_ < rhs.pos_ ? -1 : pos_ > rhs.pos_ ? 1 : 0;}
77 auto equals(const enumerable_iterator& rhs) const noexcept -> bool override {return pos_ == rhs.pos_;}
78
79 auto operator *() const -> reference {return const_cast<value_type&>(enumerator_.current());}
80 auto operator ->() const -> pointer {return &operator*();}
81
82 auto operator ++() -> enumerable_iterator& {
83 if (pos_ != npos()) pos_ = enumerator_.move_next() ? pos_ + 1 : npos();
84 return const_cast<enumerable_iterator&>(*this);
85 }
86 auto operator ++(int) -> enumerable_iterator {
87 auto current = *this;
88 operator ++();
89 return current;
90 }
91
92 template<class value_t>
93 auto operator +(value_t value) const noexcept -> const enumerable_iterator {return enumerable_iterator {*enumerable_, pos_ + value};}
94 template<class value_t>
95 auto operator +(value_t value) noexcept -> enumerable_iterator {return enumerable_iterator {*enumerable_, pos_ + value};}
96 template<class value_t>
97 auto operator +=(value_t value) noexcept -> enumerable_iterator& {
98 *this = *this + value;
99 return *this;
100 }
101 auto operator -(enumerable_iterator value) const noexcept -> difference_type {
102 if (pos_ == npos()) return npos();
103 return static_cast<difference_type>(pos_ - value.pos_);
104 }
105
106 operator enumerable_iterator<const iterator_enumerable_t>() const noexcept {return enumerable_iterator<const iterator_enumerable_t>(*enumerable_, pos_);}
107
108 private:
109 auto reset() -> void {
110 if (pos_ == npos()) return;
111 enumerator_.reset();
112 for (auto index = xtd::size {}; index <= pos_; ++index)
113 if (enumerator_.move_next() == false) {
114 pos_ = npos();
115 break;
116 }
117 }
118
119 iterator_enumerable_t* enumerable_ = nullptr;
120 enumerator<type_t> enumerator_;
121 xtd::size pos_ = 0;
122 };
124
125 public:
127
130 using iterator = enumerable_iterator<enumerable_t>;
132 using const_iterator = enumerable_iterator<const enumerable_t>;
134
136
140 virtual auto begin() const -> const_iterator {return cbegin();}
143 virtual auto begin() -> iterator {return iterator {self(), 0};}
144
147 virtual auto cbegin() const -> const_iterator {return const_iterator {self(), 0};}
148
151 virtual auto cend() const -> const_iterator {return const_iterator {self(), const_iterator::npos()};}
152
155 virtual auto end() const -> const_iterator {return cend();}
158 virtual auto end() -> iterator {return iterator {self(), iterator::npos()};}
160
162
172 template<class source_collection_t, class target_collection_t>
173 inline 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 {
174 if (value == source_collection.cbegin()) return target_collection.cbegin();
175 if (value == source_collection.cend()) return target_collection.cend();
176
177 auto result = target_collection.cbegin();
178 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
179 return result;
180 }
181
190 template<class source_collection_t, class target_collection_t>
191 inline 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 {
192 if (value == source_collection.cbegin()) return target_collection.cbegin();
193 if (value == source_collection.cend()) return target_collection.cend();
194
195 auto result = target_collection.cbegin();
196 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
197 return result;
198 }
199
208 template<class source_collection_t, class target_collection_t>
209 inline 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 {
210 if (value == source_collection.cbegin()) return target_collection.cbegin();
211 if (value == source_collection.cend()) return target_collection.cend();
212
213 auto result = target_collection.cbegin();
214 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
215 return result;
216 }
217
226 template<class source_collection_t, class target_collection_t>
227 inline 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 {
228 if (value == source_collection.begin()) return target_collection.begin();
229 if (value == source_collection.end()) return target_collection.end();
230
231 auto result = target_collection.begin();
232 for (auto index = ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
233 return result;
234 }
235
244 template<class source_collection_t, class target_collection_t>
245 inline 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 {
246 if (value == source_collection.cbegin()) return target_collection.cbegin();
247 if (value == source_collection.cend()) return target_collection.cend();
248
249 auto result = target_collection.cbegin();
250 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
251 return result;
252 }
253
262 template<class source_collection_t, class target_collection_t>
263 inline 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 {
264 if (value == source_collection.begin()) return target_collection.begin();
265 if (value == source_collection.end()) return target_collection.end();
266
267 auto result = target_collection.begin();
268 for (auto index = ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
269 return result;
270 }
271
272
273 private:
274 auto self() const noexcept -> const enumerable_t& {return static_cast<const enumerable_t&>(self_);}
275 auto self() noexcept -> enumerable_t& {return static_cast<enumerable_t&>(self_);}
276 };
277 }
278 }
279 }
280}
281
283namespace std {
284 template<typename type_t, typename enumerable_t>
285 struct iterator_traits<typename xtd::collections::generic::extensions::enumerable_iterators<type_t, enumerable_t>> {
286 using value_type = type_t;
287 using reference = const type_t&;
288 using pointer = const type_t*;
289 using difference_type = std::ptrdiff_t;
290 using iterator_category = std::input_iterator_tag;
291 };
292}
Internal enumerable iterators definition.
Definition enumerable_iterators.hpp:49
virtual auto begin() -> iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:143
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:245
enumerable_iterator< const enumerable_t > const_iterator
Represents the const iterator of enumerable value type.
Definition enumerable_iterators.hpp:132
virtual auto begin() const -> const_iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:140
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:209
virtual auto end() -> iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:158
enumerable_iterator< enumerable_t > iterator
Represents the iterator of enumerable value type.
Definition enumerable_iterators.hpp:130
virtual auto cbegin() const -> const_iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:147
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:173
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:227
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:191
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:263
virtual auto end() const -> const_iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:155
virtual auto cend() const -> const_iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:151
Provides a set of static methods for querying objects that implement ienumerable <type_t>.
Definition enumerable.hpp:32
Defines a generalized comparison method that a value type or class implements to create a type-specif...
Definition icomparable.hpp:21
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition iequatable.hpp:22
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 xtd::size npos
Represents a value that is not a valid position in a collection.
Definition npos.hpp:26
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
std::int32_t int32
Represents a 32-bit signed integer.
Definition int32.hpp:23
std::ptrdiff_t ptrdiff
Represent the signed integer type of the result of subtracting two pointers.
Definition ptrdiff.hpp:23
Contains xtd::icomparable interface.
Contains xtd::iequatable interface.
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
bool equals(const object &obj) const noexcept override
Determines whether the specified object is equal to the current object.
Definition read_only_span.hpp:272
Contains xtd::ptrdiff type.
Contains self_ keyword.
Supports a simple iteration over a generic collection.
Definition enumerator.hpp:38
Contains xtd::size type.