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>
50 template<class iterator_enumerable_t>
51 class enumerable_iterator : public xtd::icomparable<enumerable_iterator<iterator_enumerable_t>>, public xtd::iequatable<enumerable_iterator<iterator_enumerable_t >> {
52 public:
53 using value_type = type_t;
54 using iterator_category = std::forward_iterator_tag;
55 using iterator_concept = std::forward_iterator_tag;
56 using difference_type = xtd::ptrdiff;
57 using pointer = value_type*;
58 using reference = value_type&;
59
60 static constexpr xtd::size npos() {return std::numeric_limits<xtd::size>::max();}
61
62 enumerable_iterator() = default;
63 enumerable_iterator(iterator_enumerable_t* enumerable, xtd::size pos) : enumerable_ {enumerable}, enumerator_ {enumerable->get_enumerator()}, pos_ {pos} {reset();}
64 enumerable_iterator(enumerable_iterator&& value) noexcept = default;
65 enumerable_iterator(const enumerable_iterator& value) noexcept : enumerable_(value.enumerable_), enumerator_(value.enumerable_->get_enumerator()), pos_ {value.pos_} {reset();}
66 enumerable_iterator& operator =(enumerable_iterator&& value) noexcept = default;
67 enumerable_iterator& operator =(const enumerable_iterator& value) noexcept {
68 enumerable_ = value.enumerable_;
69 enumerator_ = value.enumerable_->get_enumerator();
70 pos_ = value.pos_;
71 reset();
72 return const_cast<enumerable_iterator&>(*this);
73 }
74
75 int32 compare_to(const enumerable_iterator& rhs) const noexcept override {return pos_ < rhs.pos_ ? -1 : pos_ > rhs.pos_ ? 1 : 0;}
76 bool equals(const enumerable_iterator& rhs) const noexcept override {return pos_ == rhs.pos_;}
77
78 reference operator *() const {return const_cast<value_type&>(enumerator_.current());}
79 pointer operator ->() const {return &operator*();}
80
81 enumerable_iterator& operator ++() noexcept {
82 if (pos_ != npos()) pos_ = enumerator_.move_next() ? pos_ + 1 : npos();
83 return const_cast<enumerable_iterator&>(*this);
84 }
85 enumerable_iterator operator ++(int) noexcept {
86 auto current = *this;
87 operator ++();
88 return current;
89 }
90
91 template<class value_t>
92 const enumerable_iterator operator +(value_t value) const noexcept {return enumerable_iterator {enumerable_, pos_ + value};}
93 template<class value_t>
94 enumerable_iterator operator +(value_t value) noexcept {return enumerable_iterator {enumerable_, pos_ + value};}
95 template<class value_t>
96 enumerable_iterator& operator +=(value_t value) noexcept {
97 *this = *this + value;
98 return *this;
99 }
100 difference_type operator -(enumerable_iterator value) const noexcept {
101 if (pos_ == npos()) return npos();
102 return static_cast<difference_type>(pos_ - value.pos_);
103 }
104
105 operator enumerable_iterator<const iterator_enumerable_t>() const noexcept {
106 return enumerable_iterator<const iterator_enumerable_t>(enumerable_, pos_);
107 }
108
109 private:
110 void reset() {
111 if (pos_ == npos()) return;
112 enumerator_.reset();
113 for (auto index = xtd::size {}; index <= pos_; ++index)
114 if (enumerator_.move_next() == false) {
115 pos_ = npos();
116 break;
117 }
118 }
119
120 iterator_enumerable_t* enumerable_ = nullptr;
121 enumerator<type_t> enumerator_;
122 xtd::size pos_ = 0;
123 };
125
126 public:
128
131 using iterator = enumerable_iterator<enumerable_t>;
133 using const_iterator = enumerable_iterator<const enumerable_t>;
135
137
141 virtual const_iterator begin() const {return cbegin();}
144 virtual iterator begin() {return iterator {static_cast<enumerable_t*>(this), 0};}
145
148 virtual const_iterator cbegin() const {return const_iterator {static_cast<const enumerable_t*>(this), 0};}
149
152 virtual const_iterator cend() const {return const_iterator {static_cast<const enumerable_t*>(this), const_iterator::npos()};}
153
156 virtual const_iterator end() const {return cend();}
159 virtual iterator end() {return iterator {static_cast<enumerable_t*>(this), iterator::npos()};}
161
163
173 template<class source_collection_t, class target_collection_t>
174 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 {
175 if (value == source_collection.cbegin()) return target_collection.cbegin();
176 if (value == source_collection.cend()) return target_collection.cend();
177
178 auto result = target_collection.cbegin();
179 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
180 return result;
181 }
182
191 template<class source_collection_t, class target_collection_t>
192 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 {
193 if (value == source_collection.cbegin()) return target_collection.cbegin();
194 if (value == source_collection.cend()) return target_collection.cend();
195
196 auto result = target_collection.cbegin();
197 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
198 return result;
199 }
200
209 template<class source_collection_t, class target_collection_t>
210 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 {
211 if (value == source_collection.cbegin()) return target_collection.cbegin();
212 if (value == source_collection.cend()) return target_collection.cend();
213
214 auto result = target_collection.cbegin();
215 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
216 return result;
217 }
218
227 template<class source_collection_t, class target_collection_t>
228 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 {
229 if (value == source_collection.begin()) return target_collection.begin();
230 if (value == source_collection.end()) return target_collection.end();
231
232 auto result = target_collection.begin();
233 for (auto index = ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
234 return result;
235 }
236
245 template<class source_collection_t, class target_collection_t>
246 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 {
247 if (value == source_collection.cbegin()) return target_collection.cbegin();
248 if (value == source_collection.cend()) return target_collection.cend();
249
250 auto result = target_collection.cbegin();
251 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
252 return result;
253 }
254
263 template<class source_collection_t, class target_collection_t>
264 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 {
265 if (value == source_collection.begin()) return target_collection.begin();
266 if (value == source_collection.end()) return target_collection.end();
267
268 auto result = target_collection.begin();
269 for (auto index = ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
270 return result;
271 }
272
273 };
274 }
275 }
276 }
277}
278
280namespace std {
281 template<typename type_t, typename enumerable_t>
282 struct iterator_traits<typename xtd::collections::generic::extensions::enumerable_iterators<type_t, enumerable_t>> {
283 using value_type = type_t;
284 using reference = const type_t&;
285 using pointer = const type_t*;
286 using difference_type = std::ptrdiff_t;
287 using iterator_category = std::input_iterator_tag;
288 };
289}
Internal enumerable iterators definition.
Definition enumerable_iterators.hpp:48
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:228
virtual const_iterator cbegin() const
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:148
enumerable_iterator< const enumerable_t > const_iterator
Represents the const iterator of enumerable value type.
Definition enumerable_iterators.hpp:133
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:264
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:192
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:174
virtual const_iterator begin() const
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:141
virtual const_iterator cend() const
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:152
virtual const_iterator end() const
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:156
enumerable_iterator< enumerable_t > iterator
Represents the iterator of enumerable value type.
Definition enumerable_iterators.hpp:131
virtual iterator end()
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:159
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:210
virtual iterator begin()
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:144
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:246
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.