Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Iterator.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. 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, typename 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, typename ITERATOR_TRAITS>
41 inline Iterator<T, ITERATOR_TRAITS>::Iterator (const unique_ptr<IRep>& rep) noexcept
42 : fRep_{rep}
43 {
44 RequireNotNull (fRep_);
45 fRep_->More (&fCurrentValue_, false);
46 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
47 }
48 template <typename T, typename ITERATOR_TRAITS>
49 inline Iterator<T, ITERATOR_TRAITS>::Iterator (unique_ptr<IRep>&& rep) noexcept
50 : fRep_{move (rep)}
51 {
52 RequireNotNull (fRep_);
53 fRep_->More (&fCurrentValue_, false);
54 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
55 }
56 template <typename T, typename 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, typename 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, typename ITERATOR_TRAITS>
71 constexpr Iterator<T, ITERATOR_TRAITS>::Iterator (const default_sentinel_t&) noexcept
72 : Iterator{ConstructionFlagForceAtEnd_::ForceAtEnd}
73 {
74 }
75 template <typename T, typename ITERATOR_TRAITS>
76 constexpr Iterator<T, ITERATOR_TRAITS>::Iterator (nullptr_t) noexcept
77 : Iterator{ConstructionFlagForceAtEnd_::ForceAtEnd}
78 {
79 }
80 template <typename T, typename ITERATOR_TRAITS>
81 constexpr Iterator<T, ITERATOR_TRAITS>::Iterator () noexcept
82 : Iterator{ConstructionFlagForceAtEnd_::ForceAtEnd}
83 {
84 }
85 template <typename T, typename ITERATOR_TRAITS>
86 constexpr Iterator<T, ITERATOR_TRAITS>::Iterator (ConstructionFlagForceAtEnd_) noexcept
87 : fRep_{nullptr}
88 {
89 Assert (Done ());
90 }
91 template <typename T, typename ITERATOR_TRAITS>
92 inline Iterator<T, ITERATOR_TRAITS>& Iterator<T, ITERATOR_TRAITS>::operator= (const Iterator& rhs)
93 {
94 if (&rhs != this) [[likely]] {
95 fRep_ = rhs.fRep_ == nullptr ? nullptr : Clone_ (*rhs.fRep_);
96 fCurrentValue_ = rhs.fCurrentValue_;
97 this->Invariant (); // could do before and after but this is a good cost/benfit trade-off
98 }
99 return *this;
100 }
101 template <typename T, typename ITERATOR_TRAITS>
103 {
104 if (&rhs != this) [[likely]] {
105 fRep_ = move (rhs.fRep_);
106 fCurrentValue_ = move (rhs.fCurrentValue_);
107 this->Invariant (); // could do before and after but this is a good cost/benfit trade-off
108 }
109 return *this;
110 }
111 template <typename T, typename ITERATOR_TRAITS>
113 {
114 EnsureNotNull (fRep_);
115 return *fRep_;
116 }
117 template <typename T, typename ITERATOR_TRAITS>
119 {
120 EnsureNotNull (fRep_);
121 return *fRep_;
122 }
123 template <typename T, typename ITERATOR_TRAITS>
125 {
126 fRep_->More (&this->fCurrentValue_, false);
127 this->Invariant (); // could do before and after but this is a good cost/benfit trade-off
128 }
129 template <typename T, typename ITERATOR_TRAITS>
130 inline void Iterator<T, ITERATOR_TRAITS>::Invariant () const noexcept
131 {
133 if (fRep_) {
134 fRep_->Invariant ();
135 }
136 }
137 }
138 template <typename T, typename ITERATOR_TRAITS>
140 {
141 RequireNotNull (fRep_);
142 Require (fCurrentValue_.has_value ());
143 this->Invariant ();
144 return *fCurrentValue_;
145 }
146 template <typename T, typename ITERATOR_TRAITS>
148 {
149 this->Invariant ();
150 return not fCurrentValue_.has_value ();
151 }
152 template <typename T, typename ITERATOR_TRAITS>
154 {
155 *this = GetEmptyIterator ();
156 }
157 template <typename T, typename ITERATOR_TRAITS>
159 {
160 *this = GetEmptyIterator ();
161 }
162 template <typename T, typename ITERATOR_TRAITS>
164 {
165 Require (not Done ());
166 RequireNotNull (fRep_);
167 this->Invariant ();
168 return *fCurrentValue_;
169 }
170 template <typename T, typename ITERATOR_TRAITS>
172 {
173 Require (not Done ());
174 RequireNotNull (fRep_);
175 this->Invariant ();
176 return fCurrentValue_.operator->();
177 }
178 template <typename T, typename ITERATOR_TRAITS>
180 {
181 Require (not Done ());
182 RequireNotNull (fRep_);
183 fRep_->More (&fCurrentValue_, true);
184 this->Invariant (); // could do before and after but this is a good cost/benefit trade-off
185 return *this;
186 }
187 template <typename T, typename ITERATOR_TRAITS>
189 {
190 Iterator<T, ITERATOR_TRAITS> result = *this;
191 this->operator++ ();
192 return result;
193 }
194 template <typename T, typename ITERATOR_TRAITS>
195 inline Iterator<T, ITERATOR_TRAITS> Iterator<T, ITERATOR_TRAITS>::operator+ (int i) const
196 {
197 Require (i >= 0);
198 Iterator<T, ITERATOR_TRAITS> tmp{*this};
199 while (i > 0) {
200 --i;
201 ++tmp;
202 }
203 return tmp;
204 }
205 template <typename T, typename ITERATOR_TRAITS>
206 inline Iterator<T, ITERATOR_TRAITS>::operator bool () const
207 {
208 return not Done ();
209 }
210 template <typename T, typename ITERATOR_TRAITS>
212 {
213 /*
214 * Equals is checked by first checking handling the case of special 'done' iterators. If two
215 * iterators differ on Done () - they cannot be equal. And if they are both done (this is special -
216 * even if from different sources) they are considered equal.
217 *
218 * But then - we check that they are the same dynamic type, and if so, hand to one,
219 * and let it do the dynamic/concrete type specific checks for equality.
220 */
221 bool lDone = Done ();
222 bool rDone = rhs.Done ();
223 if (lDone != rDone) [[likely]] {
224 return false;
225 }
226 if (lDone) {
227 Assert (rDone);
228 return true;
229 }
230 Assert (not lDone and not rDone);
231 const Iterator<T, ITERATOR_TRAITS>::IRep* lhsRep = fRep_.get ();
232 const Iterator<T, ITERATOR_TRAITS>::IRep* rhsRep = rhs.fRep_.get ();
233 Ensure (lhsRep->Equals (rhsRep) == rhsRep->Equals (lhsRep));
234 return lhsRep->Equals (rhsRep);
235 }
236 template <typename T, typename ITERATOR_TRAITS>
237 inline bool Iterator<T, ITERATOR_TRAITS>::operator== (const default_sentinel_t&) const
238 {
239 return this->Done ();
240 }
241 template <typename T, typename ITERATOR_TRAITS>
242 inline auto Iterator<T, ITERATOR_TRAITS>::Clone_ (const typename Iterator<T, ITERATOR_TRAITS>::IRep& rep) -> unique_ptr<IRep>
243 {
244 return rep.Clone ();
245 }
246 template <typename T, typename ITERATOR_TRAITS>
247 constexpr inline default_sentinel_t Iterator<T, ITERATOR_TRAITS>::GetEmptyIterator () noexcept
248 {
249 return default_sentinel;
250 }
251
252 /*
253 ********************************************************************************
254 ***************************** Iterator2Pointer *********************************
255 ********************************************************************************
256 */
257 template <typename ITERATOR>
258 constexpr inline typename iterator_traits<ITERATOR>::pointer Iterator2Pointer (ITERATOR i)
259 {
260 // this overload wont always work.. I hope it gives good compiler error message??? --LGP 2014-10-07
261 //
262 // 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
263 return &*i;
264 }
265
266}
#define EnsureNotNull(p)
Definition Assertions.h:340
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
Definition Assertions.h:48
#define RequireNotNull(p)
Definition Assertions.h:347
constexpr iterator_traits< ITERATOR >::pointer Iterator2Pointer(ITERATOR i)
More clear way of writing '&*' - convert iterator to pointer.
Definition Iterator.inl:258
Implementation detail for iterator implementors.
Definition Iterator.h:599
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:225
nonvirtual void reset()
Set to done and disassociate with owner.
Definition Iterator.inl:153
nonvirtual IRep & GetRep()
Get a reference to the IRep owned by the iterator. This is an implementation detail,...
Definition Iterator.inl:112
nonvirtual const IRep & ConstGetRep() const
Get a reference to the IRep owned by the iterator. This is an implementation detail,...
Definition Iterator.inl:118
nonvirtual void clear()
Set to done and disassociate with owner.
Definition Iterator.inl:158
typename ITERATOR_TRAITS::value_type value_type
value_type = typename ITERATOR_TRAITS::value_type;
Definition Iterator.h:241
nonvirtual void Invariant() const noexcept
, does nothing if !qStroika_Foundation_Debug_AssertionsChecked, but if qStroika_Foundation_Debug_Asse...
Definition Iterator.inl:130
nonvirtual const T & Current() const
Returns the value of the current item visited by the Iterator<T>, and is illegal to call if Done()
Definition Iterator.inl:139
nonvirtual const value_type * operator->() const
Return a pointer to the current value pointed to by the Iterator<T> (like Current())
Definition Iterator.inl:171
static constexpr default_sentinel_t GetEmptyIterator() noexcept
Used by someContainer::end ()
Definition Iterator.inl:247
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:211
nonvirtual Iterator & operator=(Iterator &&rhs) noexcept
Iterators are safely copyable, preserving their current position. Copy-Assigning could throw since it...
Definition Iterator.inl:102
nonvirtual Iterator & operator++()
preincrement
Definition Iterator.inl:179
nonvirtual bool Done() const
Done () means there is nothing left in this iterator (a synonym for (it == container....
Definition Iterator.inl:147
nonvirtual const T & operator*() const
Return the Current value pointed to by the Iterator<T> (same as Current())
Definition Iterator.inl:163