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"
8#include "../../../npos.hpp"
10#include "../../../self.hpp"
11#include "../../../size.hpp"
12#include <limits>
13
15namespace xtd {
17 namespace collections {
19 namespace generic {
21 namespace extensions {
49 template<class type_t, class enumerable_t>
52 template<class iterator_enumerable_t>
53 class enumerable_iterator : public xtd::icomparable<enumerable_iterator<iterator_enumerable_t>>, public xtd::iequatable<enumerable_iterator<iterator_enumerable_t >> {
54 public:
55 using value_type = type_t;
56 using iterator_category = std::forward_iterator_tag;
57 using iterator_concept = std::forward_iterator_tag;
59 using pointer = value_type*;
60 using reference = value_type&;
61
62 static constexpr auto npos() -> xtd::size {return std::numeric_limits<xtd::size>::max();}
63
64 enumerable_iterator() = default;
65 enumerable_iterator(iterator_enumerable_t& enumerable, xtd::size pos) : enumerable_ {&enumerable}, enumerator_ {enumerable.get_enumerator()}, pos_ {pos} {reset();}
66 enumerable_iterator(enumerable_iterator&& value) noexcept = default;
67 enumerable_iterator(const enumerable_iterator& value) noexcept : enumerable_(value.enumerable_), enumerator_(value.enumerable_->get_enumerator()), pos_ {value.pos_} {reset();}
68 auto operator =(enumerable_iterator&& value) noexcept -> enumerable_iterator& = default;
69 auto operator =(const enumerable_iterator& value) noexcept -> enumerable_iterator& {
70 enumerable_ = value.enumerable_;
71 enumerator_ = value.enumerable_->get_enumerator();
72 pos_ = value.pos_;
73 reset();
74 return const_cast<enumerable_iterator&>(*this);
75 }
76
77 auto compare_to(const enumerable_iterator& rhs) const noexcept -> xtd::int32 override {return pos_ < rhs.pos_ ? -1 : pos_ > rhs.pos_ ? 1 : 0;}
78 auto equals(const enumerable_iterator& rhs) const noexcept -> bool override {return pos_ == rhs.pos_;}
79
80 auto operator *() const -> reference {return const_cast<value_type&>(enumerator_.current());}
81 auto operator ->() const -> pointer {return &operator*();}
82
83 auto operator ++() -> enumerable_iterator& {
84 if (pos_ != npos()) pos_ = enumerator_.move_next() ? pos_ + 1 : npos();
85 return const_cast<enumerable_iterator&>(*this);
86 }
87 auto operator ++(int) -> enumerable_iterator {
88 auto current = *this;
89 operator ++();
90 return current;
91 }
92
93 template<class value_t>
94 auto operator +(value_t value) const noexcept -> const enumerable_iterator {return enumerable_iterator {*enumerable_, pos_ + value};}
95 template<class value_t>
96 auto operator +(value_t value) noexcept -> enumerable_iterator {return enumerable_iterator {*enumerable_, pos_ + value};}
97 template<class value_t>
98 auto operator +=(value_t value) noexcept -> enumerable_iterator& {
99 *this = *this + value;
100 return *this;
101 }
102 auto operator -(enumerable_iterator value) const noexcept -> difference_type {
103 if (pos_ == npos()) return npos();
104 return static_cast<difference_type>(pos_ - value.pos_);
105 }
106
107 explicit operator enumerable_iterator<const iterator_enumerable_t>() const noexcept {return enumerable_iterator<const iterator_enumerable_t>(*enumerable_, pos_);}
108
109 private:
110 auto reset() -> void {
111 if (pos_ == npos()) return;
112 try {
113 enumerator_.reset();
114 } catch(...) {
115 if (pos_ != 0 && pos_ != npos()) throw;
116 if (enumerator_.move_next() == false) pos_ = npos();
117 return;
118 }
119 for (auto index = xtd::size {}; index <= pos_; ++index)
120 if (enumerator_.move_next() == false) {
121 pos_ = npos();
122 break;
123 }
124 }
125
126 iterator_enumerable_t* enumerable_ = nullptr;
127 enumerator<type_t> enumerator_;
128 xtd::size pos_ = 0;
129 };
131
132 public:
134
137 using iterator = enumerable_iterator<enumerable_t>;
139 using const_iterator = enumerable_iterator<const enumerable_t>;
141
143
147 virtual auto begin() const -> const_iterator {return cbegin();}
150 virtual auto begin() -> iterator {return iterator {self(), 0};}
151
154 virtual auto cbegin() const -> const_iterator {return const_iterator {self(), 0};}
155
158 virtual auto cend() const -> const_iterator {return const_iterator {self(), const_iterator::npos()};}
159
162 virtual auto end() const -> const_iterator {return cend();}
165 virtual auto end() -> iterator {return iterator {self(), iterator::npos()};}
167
169
179 template<class source_collection_t, class target_collection_t>
180 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 {
181 if (value == source_collection.cbegin()) return target_collection.cbegin();
182 if (value == source_collection.cend()) return target_collection.cend();
183
184 auto result = target_collection.cbegin();
185 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
186 return result;
187 }
188
197 template<class source_collection_t, class target_collection_t>
198 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 {
199 if (value == source_collection.cbegin()) return target_collection.cbegin();
200 if (value == source_collection.cend()) return target_collection.cend();
201
202 auto result = target_collection.cbegin();
203 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
204 return result;
205 }
206
215 template<class source_collection_t, class target_collection_t>
216 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 {
217 if (value == source_collection.cbegin()) return target_collection.cbegin();
218 if (value == source_collection.cend()) return target_collection.cend();
219
220 auto result = target_collection.cbegin();
221 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
222 return result;
223 }
224
233 template<class source_collection_t, class target_collection_t>
234 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 {
235 if (value == source_collection.begin()) return target_collection.begin();
236 if (value == source_collection.end()) return target_collection.end();
237
238 auto result = target_collection.begin();
239 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
240 return result;
241 }
242
251 template<class source_collection_t, class target_collection_t>
252 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 {
253 if (value == source_collection.cbegin()) return target_collection.cbegin();
254 if (value == source_collection.cend()) return target_collection.cend();
255
256 auto result = target_collection.cbegin();
257 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
258 return result;
259 }
260
269 template<class source_collection_t, class target_collection_t>
270 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 {
271 if (value == source_collection.begin()) return target_collection.begin();
272 if (value == source_collection.end()) return target_collection.end();
273
274 auto result = target_collection.begin();
275 for (auto index = xtd::ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
276 return result;
277 }
278
279
280 private:
281 auto self() const noexcept -> const enumerable_t& {return static_cast<const enumerable_t&>(self_);}
282 auto self() noexcept -> enumerable_t& {return static_cast<enumerable_t&>(self_);}
283 };
284 }
285 }
286 }
287}
288
290namespace std {
291 template<typename type_t, typename enumerable_t>
292 struct iterator_traits<typename xtd::collections::generic::extensions::enumerable_iterators<type_t, enumerable_t>> {
293 using value_type = type_t;
294 using reference = const type_t&;
295 using pointer = const type_t*;
296 using difference_type = std::ptrdiff_t;
297 using iterator_category = std::input_iterator_tag;
298 };
299}
Internal enumerable iterators definition.
Definition enumerable_iterators.hpp:50
virtual auto begin() -> iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:150
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:252
enumerable_iterator< const enumerable_t > const_iterator
Represents the const iterator of enumerable value type.
Definition enumerable_iterators.hpp:139
virtual auto begin() const -> const_iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:147
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:216
virtual auto end() -> iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:165
enumerable_iterator< enumerable_t > iterator
Represents the iterator of enumerable value type.
Definition enumerable_iterators.hpp:137
virtual auto cbegin() const -> const_iterator
Returns an iterator to the first element of the enumerable.
Definition enumerable_iterators.hpp:154
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:180
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:234
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:198
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:270
virtual auto end() const -> const_iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:162
virtual auto cend() const -> const_iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:158
Defines a generalized comparison method that a value type or class implements to create a type-specif...
Definition icomparable.hpp:22
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition iequatable.hpp:23
Definition enumerable.hpp:35
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
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
const type_t & reference
Represents the read_only_span reference type.
Definition read_only_span.hpp:70
const type_t * pointer
Represents the read_only_span pointer type.
Definition read_only_span.hpp:66
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
xtd::ptrdiff difference_type
Represents the read_only_span difference type (usually xtd::ptrdiff).
Definition read_only_span.hpp:64
Contains xtd::npos constant.
Contains xtd::ptrdiff type.
Contains self_ keyword.
Supports a simple iteration over a generic collection.
Definition enumerator.hpp:38
Contains xtd::size type.