Stroika Library 3.0d24
 
Loading...
Searching...
No Matches
Iterator.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
5
6namespace Stroika::Foundation::Traversal {
7
8 /**
9 */
10 struct [[deprecated ("Since Stroika v3.0d1")]] IteratorBase {
11 public:
12 template <typename SHARED_T>
13 using PtrImplementationTemplate [[deprecated ("Since Stroika v3.0d1 - use unique_ptr directly")]] = unique_ptr<SHARED_T>;
14
15 public:
16 template <typename SHARED_T, typename... ARGS_TYPE>
17 [[deprecated ("Since Stroika v3.0d1 - make_unique directly")]] static unique_ptr<SHARED_T> MakeSmartPtr (ARGS_TYPE&&... args)
18 {
19 return make_unique<SHARED_T> (forward<ARGS_TYPE> (args)...);
20 }
21 };
22
23 /*
24 ********************************************************************************
25 ********************** Iterator<T, ITERATOR_TRAITS>::IRep **********************
26 ********************************************************************************
27 */
28#if qStroika_Foundation_Debug_AssertionsChecked
29 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
30 inline void Iterator<T, ITERATOR_TRAITS>::IRep::Invariant () const noexcept
31 {
32 }
33#endif
34
35 /*
36 ********************************************************************************
37 *************************** Iterator<T, ITERATOR_TRAITS> ***********************
38 ********************************************************************************
39 */
40 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
41 inline Iterator<T, ITERATOR_TRAITS>::Iterator (const unique_ptr<IRep>& rep) noexcept
42 : fRep_{rep}
43 , _fCurrentValue{fRep_->Current ()}
44 {
45 RequireNotNull (fRep_);
46 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
47 }
48 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
49 inline Iterator<T, ITERATOR_TRAITS>::Iterator (unique_ptr<IRep>&& rep) noexcept
50 : fRep_{move (rep)}
51 , _fCurrentValue{fRep_->Current ()}
52 {
53 RequireNotNull (fRep_);
54 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
55 }
56 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
57 inline Iterator<T, ITERATOR_TRAITS>::Iterator (const Iterator& src)
58 : fRep_{src.fRep_ == nullptr ? nullptr : Clone_ (*src.fRep_)}
59 , _fCurrentValue{src._fCurrentValue}
60 {
61 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
62 }
63 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
64 inline Iterator<T, ITERATOR_TRAITS>::Iterator (Iterator&& src) noexcept
65 : fRep_{move (src.fRep_)}
66 , _fCurrentValue{move (src._fCurrentValue)}
67 {
68 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
69 }
70 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
71 constexpr Iterator<T, ITERATOR_TRAITS>::Iterator (const default_sentinel_t&) noexcept
72 : fRep_{nullptr}
73 {
74 Assert (AtEnd ());
75 }
76 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
77 constexpr Iterator<T, ITERATOR_TRAITS>::Iterator (nullptr_t) noexcept
78 : Iterator{default_sentinel}
79 {
80 }
81 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
82 constexpr Iterator<T, ITERATOR_TRAITS>::Iterator () noexcept
83 : Iterator{default_sentinel}
84 {
85 }
86 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
87 inline Iterator<T, ITERATOR_TRAITS>& Iterator<T, ITERATOR_TRAITS>::operator= (const Iterator& rhs)
88 {
89 if (&rhs != this) [[likely]] {
90 fRep_ = rhs.fRep_ == nullptr ? nullptr : Clone_ (*rhs.fRep_);
91 _fCurrentValue = rhs._fCurrentValue;
92 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
93 }
94 return *this;
95 }
96 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
98 {
99 if (&rhs != this) [[likely]] {
100 fRep_ = move (rhs.fRep_);
101 _fCurrentValue = move (rhs._fCurrentValue);
102 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
103 }
104 return *this;
105 }
106 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
108 {
109 EnsureNotNull (fRep_);
110 return *fRep_;
111 }
112 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
114 {
115 EnsureNotNull (fRep_);
116 return *fRep_;
117 }
118 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
120 {
121 this->_fCurrentValue = fRep_->Current ();
122 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
123 }
124 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
125 inline void Iterator<T, ITERATOR_TRAITS>::Invariant () const noexcept
126 {
128 if (fRep_) {
129 fRep_->Invariant ();
130 Assert ((not this->_fCurrentValue.has_value ()) == fRep_->AtEnd ()); // Iterator<> caches result of rep - make sure in sync
131 }
132 }
133 }
134 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
136 {
137 RequireNotNull (fRep_);
138 Require (_fCurrentValue.has_value ());
139 this->Invariant ();
140 return *_fCurrentValue;
141 }
142 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
144 {
145 this->Invariant ();
146 return not _fCurrentValue.has_value ();
147 }
148 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
150 {
151 *this = GetEmptyIterator ();
152 }
153 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
155 {
156 *this = GetEmptyIterator ();
157 }
158 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
160 {
161 Require (not AtEnd ());
162 RequireNotNull (fRep_);
163 this->Invariant ();
164 return *_fCurrentValue;
165 }
166 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
168 {
169 Require (not AtEnd ());
170 RequireNotNull (fRep_);
171 this->Invariant ();
172 return _fCurrentValue.operator->();
173 }
174 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
176 {
177 Require (not AtEnd ());
178 RequireNotNull (fRep_);
179 _fCurrentValue = fRep_->More ();
180 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
181 return *this;
182 }
183 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
185 {
186 Iterator<T, ITERATOR_TRAITS> result = *this;
187 this->operator++ ();
188 return result;
189 }
190 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
192 {
193 Require (i >= 0);
195 while (i > 0) {
196 --i;
197 ++tmp;
198 }
199 return tmp;
200 }
201 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
203 {
204 return not AtEnd ();
205 }
206 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
208 {
209 /*
210 * Equals is checked by first checking handling the case of special 'AtEnd' iterators. If two
211 * iterators differ on AtEnd () - they cannot be equal. And if they are both AtEnd (this is special -
212 * even if from different sources) they are considered equal.
213 *
214 * But then - we check that they are the same dynamic type, and if so, hand to one,
215 * and let it do the dynamic/concrete type specific checks for equality.
216 */
217 bool lDone = AtEnd ();
218 bool rDone = rhs.AtEnd ();
219 if (lDone != rDone) [[likely]] {
220 return false;
221 }
222 if (lDone) {
223 Assert (rDone);
224 return true;
225 }
226 Assert (not lDone and not rDone);
227 const Iterator<T, ITERATOR_TRAITS>::IRep* lhsRep = fRep_.get ();
228 const Iterator<T, ITERATOR_TRAITS>::IRep* rhsRep = rhs.fRep_.get ();
229 Ensure (lhsRep->Equals (rhsRep) == rhsRep->Equals (lhsRep));
230 return lhsRep->Equals (rhsRep);
231 }
232 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
233 inline bool Iterator<T, ITERATOR_TRAITS>::operator== (const default_sentinel_t&) const
234 {
235 return this->AtEnd ();
236 }
237 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
238 inline auto Iterator<T, ITERATOR_TRAITS>::Clone_ (const typename Iterator<T, ITERATOR_TRAITS>::IRep& rep) -> unique_ptr<IRep>
239 {
240 return rep.Clone ();
241 }
242 template <typename T, Support::IIteratorTraits ITERATOR_TRAITS>
243 constexpr inline default_sentinel_t Iterator<T, ITERATOR_TRAITS>::GetEmptyIterator () noexcept
244 {
245 return default_sentinel;
246 }
247
248 /*
249 ********************************************************************************
250 ***************************** Iterator2Pointer *********************************
251 ********************************************************************************
252 */
253 template <typename ITERATOR>
254 constexpr inline typename iterator_traits<ITERATOR>::pointer Iterator2Pointer (ITERATOR i)
255 {
256 // this overload wont always work.. I hope it gives good compiler error message??? --LGP 2014-10-07
257 //
258 // note Traversal::Iterator2Pointer (s.end ()) generally crashes in debug mode - windows - _ITERATOR_DEBUG_LEVEL >= 1, but I can find no better way which is portable
259 return &*i;
260 }
261
262}
#define EnsureNotNull(p)
Definition Assertions.h:341
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
Definition Assertions.h:49
#define RequireNotNull(p)
Definition Assertions.h:348
constexpr iterator_traits< ITERATOR >::pointer Iterator2Pointer(ITERATOR i)
More clear way of writing '&*' - convert iterator to pointer.
Definition Iterator.inl:254
Implementation detail for iterator implementors.
Definition Iterator.h:616
virtual bool Equals(const IRep *rhs) const =0
two iterators must be iterating over the same source, and be up to the same position.
An Iterator<T> is a copyable object which allows traversing the contents of some container.
Definition Iterator.h:253
nonvirtual void reset()
Set to AtEnd and disassociate with owner.
Definition Iterator.inl:149
nonvirtual IRep & GetRep()
Get a reference to the IRep owned by the iterator. This is an implementation detail,...
Definition Iterator.inl:107
nonvirtual const IRep & ConstGetRep() const
Get a reference to the IRep owned by the iterator. This is an implementation detail,...
Definition Iterator.inl:113
nonvirtual Iterator operator+(ptrdiff_t i) const
Definition Iterator.inl:191
nonvirtual void clear()
Set to AtEnd and disassociate with owner.
Definition Iterator.inl:154
typename ITERATOR_TRAITS::value_type value_type
value_type = typename ITERATOR_TRAITS::value_type;
Definition Iterator.h:269
nonvirtual void Invariant() const noexcept
Invariant does nothing if !qStroika_Foundation_Debug_AssertionsChecked, but if qStroika_Foundation_De...
Definition Iterator.inl:125
nonvirtual const T & Current() const
Returns the value of the current item visited by the Iterator<T>, and is illegal to call if AtEnd()
Definition Iterator.inl:135
nonvirtual const value_type * operator->() const
Return a pointer to the current value pointed to by the Iterator<T> (like Current())
Definition Iterator.inl:167
static constexpr default_sentinel_t GetEmptyIterator() noexcept
Used by someContainer::end ()
Definition Iterator.inl:243
nonvirtual bool operator==(const Iterator &rhs) const
Equals () checks if two iterators are equal to one another (point to the same position in the sequenc...
Definition Iterator.inl:207
nonvirtual Iterator & operator=(Iterator &&rhs) noexcept
Iterators are safely copyable, preserving their current position. Copy-Assigning could throw since it...
Definition Iterator.inl:97
nonvirtual Iterator & operator++()
Advance iterator; support for range-based-for, and STL style iteration in general (containers must al...
Definition Iterator.inl:175
nonvirtual const T & operator*() const
Return the Current value pointed to by the Iterator<T> (same as Current())
Definition Iterator.inl:159
nonvirtual bool AtEnd() const
AtEnd () means there is nothing left in this iterator (a synonym for (it == container....
Definition Iterator.inl:143
nonvirtual void Refresh()
Refresh the current iterator state based on what is in the underlying IRep.
Definition Iterator.inl:119