xtd 0.2.0
enumerable_iterators.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "../enumerator.hpp"
6#include "../../../icomparable.hpp"
7#include "../../../iequatable.hpp"
8#include "../../../ptrdiff.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 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 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 enumerable_iterator operator ++(int) const noexcept {
96 auto current = *this;
97 operator ++();
98 return current;
99 }
100
101 enumerable_iterator& operator --() const noexcept {
102 if (pos_ != 0) 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) const noexcept {
106 auto current = *this;
107 operator --();
108 return current;
109 }
110
111 template<class value_t>
112 enumerable_iterator operator +(value_t value) const noexcept {return enumerable_iterator {enumerable_, pos_ + value};}
113 template<class value_t>
114 enumerable_iterator& operator +=(value_t value) noexcept {
115 *this = *this + value;
116 return *this;
117 }
118 difference_type operator -(enumerable_iterator value) const noexcept {
119 if (pos_ == std::numeric_limits<xtd::size>::max()) return std::numeric_limits<xtd::size>::max();
120 return static_cast<difference_type>(pos_ - value.pos_);
121 }
122
123 private:
124 void reset() const {
125 enumerator_.reset();
126 if (pos_ == std::numeric_limits<xtd::size>::max()) return;
127 for (auto index = xtd::size {}; index <= pos_; ++index)
128 if (enumerator_.move_next() == false) {
129 pos_ = std::numeric_limits<xtd::size>::max();
130 break;
131 }
132 }
133
134 mutable const enumerable_t* enumerable_ = nullptr;
135 mutable enumerator<type_t> enumerator_;
136 mutable xtd::size pos_ = 0;
137 };
139
140 public:
142
145 using iterator = enumerable_iterator;
147 using const_iterator = const enumerable_iterator;
149
151
155 virtual const_iterator begin() const {return cbegin();}
158 virtual iterator begin() {return iterator {static_cast<enumerable_t*>(this), 0};}
159
162 virtual const_iterator cbegin() const {return const_iterator {static_cast<const enumerable_t*>(this), 0};}
163
166 virtual const_iterator cend() const {return const_iterator {static_cast<const enumerable_t*>(this), const_iterator::npos()};}
167
170 virtual const_iterator end() const {return cend();}
173 virtual iterator end() {return iterator {static_cast<enumerable_t*>(this), iterator::npos()};}
175
177
187 template<class source_collection_t, class target_collection_t>
188 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 {
189 if (value == source_collection.cbegin()) return target_collection.cbegin();
190 if (value == source_collection.cend()) return target_collection.cend();
191
192 auto result = target_collection.cbegin();
193 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
194 return result;
195 }
196
205 template<class source_collection_t, class target_collection_t>
206 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 {
207 if (value == source_collection.begin()) return target_collection.begin();
208 if (value == source_collection.end()) return target_collection.end();
209
210 auto result = target_collection.begin();
211 for (auto index = ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
212 return result;
213 }
214
223 template<class source_collection_t, class target_collection_t>
224 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 {
225 if (value == source_collection.cbegin()) return target_collection.cbegin();
226 if (value == source_collection.cend()) return target_collection.cend();
227
228 auto result = target_collection.cbegin();
229 for (auto index = ptrdiff {}; index < std::distance(source_collection.cbegin(), value); ++index, ++result);
230 return result;
231 }
232
241 template<class source_collection_t, class target_collection_t>
242 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 {
243 if (value == source_collection.begin()) return target_collection.begin();
244 if (value == source_collection.end()) return target_collection.end();
245
246 auto result = target_collection.begin();
247 for (auto index = ptrdiff {}; index < std::distance(source_collection.begin(), value); ++index, ++result);
248 return result;
249 }
251 };
252 }
253 }
254 }
255}
Internal enumarable iterators definition.
Definition enumerable_iterators.hpp:48
virtual iterator end()
Returns an iterator to the element following the last element of the enumarable.
Definition enumerable_iterators.hpp:173
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:242
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:188
virtual const_iterator end() const
Returns an iterator to the element following the last element of the enumarable.
Definition enumerable_iterators.hpp:170
const enumerable_iterator const_iterator
Represents the const iterator of enumarable value type.
Definition enumerable_iterators.hpp:147
virtual const_iterator begin() const
Returns an iterator to the first element of the enumarable.
Definition enumerable_iterators.hpp:155
enumerable_iterator iterator
Represents the iterator of enumarable value type.
Definition enumerable_iterators.hpp:145
virtual const_iterator cbegin() const
Returns an iterator to the first element of the enumarable.
Definition enumerable_iterators.hpp:162
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:224
virtual const_iterator cend() const
Returns an iterator to the element following the last element of the enumarable.
Definition enumerable_iterators.hpp:166
virtual iterator begin()
Returns an iterator to the first element of the enumarable.
Definition enumerable_iterators.hpp:158
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:206
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
int32_t int32
Represents a 32-bit signed integer.
Definition int32.hpp:23
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
std::ptrdiff_t ptrdiff
Represent the signed integer type of the result of subtracting two pointers.
Definition ptrdiff.hpp:23
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.hpp:10
Supports a simple iteration over a generic collection.
Definition enumerator.hpp:38