xtd 0.2.0
enumerable_iterators.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "../enumerator.hpp"
9#include "../../../size.hpp"
10#include <limits>
11
13namespace xtd {
15 namespace collections {
17 namespace generic {
19 namespace extensions {
47 template<class type_t, class enumerable_t, class iterator_tag_t = std::bidirectional_iterator_tag>
50 class enumerable_iterator : public xtd::icomparable<enumerable_iterator>, public xtd::iequatable<enumerable_iterator> {
51 public:
52 using value_type = type_t;
53 using iterator_category = iterator_tag_t;
54 using iterator_concept = iterator_tag_t;
55 using difference_type = xtd::ptrdiff;
56 using pointer = value_type*;
57 using const_pointer = const value_type*;
58 using reference = value_type&;
59 using const_reference = const value_type&;
60
61 static constexpr xtd::size npos() {return std::numeric_limits<xtd::size>::max();}
62
63 enumerable_iterator() = default;
64 enumerable_iterator(const 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 enumerable_iterator& operator =(enumerable_iterator&& value) noexcept = default;
68 const enumerable_iterator& operator =(const enumerable_iterator& value) const noexcept {
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 enumerable_iterator& operator =(const enumerable_iterator& value) noexcept {
76 enumerable_ = value.enumerable_;
77 enumerator_ = value.enumerable_->get_enumerator();
78 pos_ = value.pos_;
79 reset();
80 return const_cast<enumerable_iterator&>(*this);
81 }
82
83 int32 compare_to(const enumerable_iterator& rhs) const noexcept override {return pos_ < rhs.pos_ ? -1 : pos_ > rhs.pos_ ? 1 : 0;}
84 bool equals(const enumerable_iterator& rhs) const noexcept override {return pos_ == rhs.pos_;}
85
86 const_reference operator *() const {return enumerator_.current();}
87 reference operator *() {return const_cast<reference>(enumerator_.current());}
88 const_pointer operator ->() const {return &operator*();}
89 pointer operator ->() {return &operator*();}
90
91 const enumerable_iterator& operator ++() const noexcept {
92 if (pos_ != std::numeric_limits<xtd::size>::max()) pos_ = enumerator_.move_next() ? pos_ + 1 : std::numeric_limits<xtd::size>::max();
93 return const_cast<enumerable_iterator&>(*this);
94 }
95 const enumerable_iterator operator ++(int) const noexcept {
96 auto current = *this;
97 operator ++();
98 return current;
99 }
100
101 enumerable_iterator& operator ++() noexcept {
102 if (pos_ != std::numeric_limits<xtd::size>::max()) pos_ = enumerator_.move_next() ? pos_ + 1 : std::numeric_limits<xtd::size>::max();
103 return const_cast<enumerable_iterator&>(*this);
104 }
105 enumerable_iterator operator ++(int) noexcept {
106 auto current = *this;
107 operator ++();
108 return current;
109 }
110
111 const enumerable_iterator& operator --() const noexcept {
112 if (pos_ != 0) pos_ = enumerator_.move_next() ? pos_ - 1 : std::numeric_limits<xtd::size>::max();
113 return const_cast<enumerable_iterator&>(*this);
114 }
115 const enumerable_iterator operator --(int) const noexcept {
116 auto current = *this;
117 operator --();
118 return current;
119 }
120
121 enumerable_iterator& operator --() noexcept {
122 if (pos_ != 0) pos_ = enumerator_.move_next() ? pos_ - 1 : std::numeric_limits<xtd::size>::max();
123 return const_cast<enumerable_iterator&>(*this);
124 }
125 enumerable_iterator operator --(int) noexcept {
126 auto current = *this;
127 operator --();
128 return current;
129 }
130
131 template<class value_t>
132 enumerable_iterator operator +(value_t value) const noexcept {return enumerable_iterator {enumerable_, pos_ + value};}
133 template<class value_t>
134 enumerable_iterator& operator +=(value_t value) noexcept {
135 *this = *this + value;
136 return *this;
137 }
138 difference_type operator -(enumerable_iterator value) const noexcept {
139 if (pos_ == std::numeric_limits<xtd::size>::max()) return std::numeric_limits<xtd::size>::max();
140 return static_cast<difference_type>(pos_ - value.pos_);
141 }
142
143 private:
144 void reset() const {
145 if (pos_ == std::numeric_limits<xtd::size>::max()) return;
146 enumerator_.reset();
147 for (auto index = xtd::size {}; index <= pos_; ++index)
148 if (enumerator_.move_next() == false) {
149 pos_ = std::numeric_limits<xtd::size>::max();
150 break;
151 }
152 }
153
154 mutable const enumerable_t* enumerable_ = nullptr;
155 mutable enumerator<type_t> enumerator_;
156 mutable xtd::size pos_ = 0;
157 };
159
160 public:
162
165 using iterator = enumerable_iterator;
167 using const_iterator = const enumerable_iterator;
169
171
175 virtual const_iterator begin() const {return cbegin();}
178 virtual iterator begin() {return iterator {static_cast<enumerable_t*>(this), 0};}
179
182 virtual const_iterator cbegin() const {return const_iterator {static_cast<const enumerable_t*>(this), 0};}
183
186 virtual const_iterator cend() const {return const_iterator {static_cast<const enumerable_t*>(this), const_iterator::npos()};}
187
190 virtual const_iterator end() const {return cend();}
193 virtual iterator end() {return iterator {static_cast<enumerable_t*>(this), iterator::npos()};}
195
197
207 template<class source_collection_t, class target_collection_t>
208 static typename target_collection_t::const_iterator to_const_iterator(typename source_collection_t::const_iterator& value, const source_collection_t& source_collection, const target_collection_t& target_collection) noexcept {
209 if (value == source_collection.cbegin()) return target_collection.cbegin();
210 if (value == source_collection.cend()) return target_collection.cend();
211
212 auto result = target_collection.cbegin();
213 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
214 return result;
215 }
216
225 template<class source_collection_t, class target_collection_t>
226 static typename target_collection_t::const_iterator to_const_iterator(typename source_collection_t::const_iterator& value, source_collection_t& source_collection, target_collection_t& target_collection) noexcept {
227 if (value == source_collection.cbegin()) return target_collection.cbegin();
228 if (value == source_collection.cend()) return target_collection.cend();
229
230 auto result = target_collection.cbegin();
231 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
232 return result;
233 }
234
243 template<class source_collection_t, class target_collection_t>
244 static typename target_collection_t::const_iterator to_iterator(typename source_collection_t::const_iterator& value, const source_collection_t& source_collection, const target_collection_t& target_collection) noexcept {
245 if (value == source_collection.cbegin()) return target_collection.cbegin();
246 if (value == source_collection.cend()) return target_collection.cend();
247
248 auto result = target_collection.cbegin();
249 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
250 return result;
251 }
252
261 template<class source_collection_t, class target_collection_t>
262 static typename target_collection_t::iterator to_iterator(typename source_collection_t::iterator& value, const source_collection_t& source_collection, const target_collection_t& target_collection) noexcept {
263 if (value == source_collection.begin()) return target_collection.begin();
264 if (value == source_collection.end()) return target_collection.end();
265
266 auto result = target_collection.begin();
267 for (auto index = ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
268 return result;
269 }
270
279 template<class source_collection_t, class target_collection_t>
280 static typename target_collection_t::const_iterator to_iterator(typename source_collection_t::const_iterator& value, source_collection_t& source_collection, target_collection_t& target_collection) noexcept {
281 if (value == source_collection.cbegin()) return target_collection.cbegin();
282 if (value == source_collection.cend()) return target_collection.cend();
283
284 auto result = target_collection.cbegin();
285 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
286 return result;
287 }
288
297 template<class source_collection_t, class target_collection_t>
298 static typename target_collection_t::iterator to_iterator(typename source_collection_t::iterator& value, source_collection_t& source_collection, target_collection_t& target_collection) noexcept {
299 if (value == source_collection.begin()) return target_collection.begin();
300 if (value == source_collection.end()) return target_collection.end();
301
302 auto result = target_collection.begin();
303 for (auto index = ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
304 return result;
305 }
306
307 };
308 }
309 }
310 }
311}
Internal enumerable iterators definition.
Definition enumerable_iterators.hpp:48
virtual iterator end()
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:193
static target_collection_t::const_iterator to_const_iterator(typename source_collection_t::const_iterator &value, source_collection_t &source_collection, target_collection_t &target_collection) noexcept
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:226
static target_collection_t::iterator to_iterator(typename source_collection_t::iterator &value, source_collection_t &source_collection, target_collection_t &target_collection) noexcept
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:298
static target_collection_t::const_iterator to_iterator(typename source_collection_t::const_iterator &value, const source_collection_t &source_collection, const target_collection_t &target_collection) noexcept
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:244
virtual const_iterator end() const
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:190
const enumerable_iterator const_iterator
Represents the const iterator of enumerable value type.
Definition enumerable_iterators.hpp:167
virtual const_iterator begin() const
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:175
enumerable_iterator iterator
Represents the iterator of enumerable value type.
Definition enumerable_iterators.hpp:165
static target_collection_t::const_iterator to_const_iterator(typename source_collection_t::const_iterator &value, const source_collection_t &source_collection, const target_collection_t &target_collection) noexcept
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:208
virtual const_iterator cbegin() const
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:182
static target_collection_t::const_iterator to_iterator(typename source_collection_t::const_iterator &value, source_collection_t &source_collection, target_collection_t &target_collection) noexcept
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:280
virtual const_iterator cend() const
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:186
virtual iterator begin()
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:178
static target_collection_t::iterator to_iterator(typename source_collection_t::iterator &value, const source_collection_t &source_collection, const target_collection_t &target_collection) noexcept
Converts source iterator to target iterator.
Definition enumerable_iterators.hpp:262
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.
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
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_operators.hpp:13
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.
Supports a simple iteration over a generic collection.
Definition enumerator.hpp:38
Contains xtd::size type.