Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Sequence.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
8#include "Stroika/Foundation/Containers/Private/IterableUtils.h"
10
12
13 /*
14 ********************************************************************************
15 ******************** Sequence<T>::TemporaryElementReference_ *******************
16 ********************************************************************************
17 */
18 /*
19 * TemporaryElementReference_ is a private implementation detail, so we can do:
20 * Sequence<int> x; // and initialize with several items, and then
21 * x[3] = 4;
22 *
23 * We need two templated variants - one inheriting and one not - to handle the fact that some people want to call a method
24 * on T, as in:
25 *
26 * Sequence<String> x;
27 * size_t a = x[3].length (); // wont work if we use aggregating variant of TemporaryElementReference_
28 * // e.g: error: �struct Stroika::Foundation::Containers::Sequence<Stroika::Foundation::Characters::String>::TemporaryElementReference_� has no member named �Trim�
29 */
30 template <typename T>
31 struct Sequence<T>::TemporaryElementReference_ : conditional_t<is_class_v<T> or is_union_v<T>, T, Common::Empty> {
32 private:
33 static constexpr bool kSubClass_ = is_class_v<T> or is_union_v<T>;
34 Sequence<T>* fV;
35 size_t fIndex_;
36 [[no_unique_address]] conditional_t<kSubClass_, Common::Empty, T> fValue_;
37
38 public:
39 TemporaryElementReference_ (const TemporaryElementReference_&) = default;
40 TemporaryElementReference_ (TemporaryElementReference_&& src)
41 : fV{move (src.fV)}
42 , fIndex_{src.fIndex_}
43 , fValue_{move (src.fValue_)}
44 {
45 src.fV = nullptr; // it no longer writes on its DTOR
46 }
47 TemporaryElementReference_ (Sequence<T>* s, size_t i)
48 : fV{(RequireExpression (s != nullptr), s)}
49 , fIndex_{i}
50 {
51 if constexpr (kSubClass_) {
52 *static_cast<T*> (this) = s->GetAt (i);
53 }
54 else {
55 fValue_ = s->GetAt (i);
56 }
57 }
58 TemporaryElementReference_& operator= (const TemporaryElementReference_&) = delete;
59 TemporaryElementReference_& operator= (TemporaryElementReference_&&) = delete;
60 TemporaryElementReference_& operator= (ArgByValueType<T> v)
61 {
62 RequireNotNull (fV);
63 if constexpr (kSubClass_) {
64 *static_cast<T*> (this) = v;
65 }
66 else {
67 fValue_ = v;
68 }
69 return *this;
70 }
71 operator T () const
72 requires (not(kSubClass_))
73 {
74 RequireNotNull (fV);
75 if constexpr (kSubClass_) {
76 return *static_cast<T*> (this);
77 }
78 else {
79 return fValue_;
80 }
81 }
82 operator T& ()
83 requires (not(kSubClass_))
84 {
85 RequireNotNull (fV);
86 if constexpr (kSubClass_) {
87 return *static_cast<T*> (this);
88 }
89 else {
90 return fValue_;
91 }
92 }
93 // Tried this for https://stroika.atlassian.net/browse/STK-1024 - but didn't help
94 // and dont much like anyhow
95 //auto ToString () const
96 //{
97 // RequireNotNull (fV);
98 // if constexpr (kSubClass_) {
99 // return Characters::UnoverloadedToString (*static_cast<T*> (this));
100 // }
101 // else {
102 // return Characters::UnoverloadedToString (fValue_);
103 // }
104 //}
105 ~TemporaryElementReference_ ()
106 {
107 // now remaining problem with this strategy is that if we have
108 // String a = sequence[i] = the temporary may get MOVE()d to 'a', and so *this is now invalid, and cannot be used in a set.
109 // We don't need to set in that case, but we have no way to reliably tell that we got moved.
110
111 // needed cuz modifications CAN come from from something like Sequence<String> x; x[1].clear ();
112 if (fV != nullptr) {
113 if constexpr (kSubClass_) {
114 IgnoreExceptionsForCall (fV->SetAt (fIndex_, *((T*)this)));
115 }
116 else {
117 IgnoreExceptionsForCall (fV->SetAt (fIndex_, fValue_));
118 }
119 }
120 }
121 };
122
123 /*
124 ********************************************************************************
125 ******************************** Sequence<T> ***********************************
126 ********************************************************************************
127 */
128 template <typename T>
130 : inherited{Factory::Sequence_Factory<T>::Default () ()}
131 {
132 _AssertRepValidType ();
133 }
134 template <typename T>
135 inline Sequence<T>::Sequence (const initializer_list<value_type>& src)
136 : Sequence{}
137 {
138 AppendAll (src);
139 _AssertRepValidType ();
140 }
141#if !qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
142 template <typename T>
143 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
144 requires (not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, Sequence<T>>)
145 inline Sequence<T>::Sequence (ITERABLE_OF_ADDABLE&& src)
146 : Sequence{}
147 {
148 AppendAll (forward<ITERABLE_OF_ADDABLE> (src));
149 _AssertRepValidType ();
150 }
151#endif
152 template <typename T>
153 inline Sequence<T>::Sequence (const shared_ptr<_IRep>& rep) noexcept
154 : inherited{(RequireExpression (rep != nullptr), rep)}
155 {
156 _AssertRepValidType ();
157 }
158 template <typename T>
159 inline Sequence<T>::Sequence (shared_ptr<_IRep>&& rep) noexcept
160 : inherited{(RequireExpression (rep != nullptr), move (rep))}
161 {
162 _AssertRepValidType ();
163 }
164 template <typename T>
165 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
166 inline Sequence<T>::Sequence (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
167 : Sequence{}
168 {
169 AppendAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (end));
170 _AssertRepValidType ();
171 }
172 template <typename T>
173 template <typename RESULT_CONTAINER, invocable<T> ELEMENT_MAPPER>
174 nonvirtual RESULT_CONTAINER Sequence<T>::Map (ELEMENT_MAPPER&& elementMapper) const
175 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, typename RESULT_CONTAINER::value_type> or
176 convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, optional<typename RESULT_CONTAINER::value_type>>)
177 {
178 if constexpr (same_as<RESULT_CONTAINER, Sequence>) {
179 // clone the rep so we retain the rep type
180 return inherited::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper),
181 RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().CloneEmpty ()});
182 }
183 else {
184 return inherited ::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper));
185 }
186 }
187 template <typename T>
188 template <derived_from<Iterable<T>> RESULT_CONTAINER, predicate<T> INCLUDE_PREDICATE>
189 inline RESULT_CONTAINER Sequence<T>::Where (INCLUDE_PREDICATE&& includeIfTrue) const
190 {
191 if constexpr (same_as<RESULT_CONTAINER, Sequence>) {
192 // clone the rep so we retain the rep type
193 return inherited::template Where<RESULT_CONTAINER> (
194 forward<INCLUDE_PREDICATE> (includeIfTrue), RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().CloneEmpty ()});
195 }
196 else {
197 return inherited::template Where<RESULT_CONTAINER> (forward<INCLUDE_PREDICATE> (includeIfTrue));
198 }
199 }
200 template <typename T>
201 template <IPotentiallyComparer<T> INORDER_COMPARER_TYPE>
202 auto Sequence<T>::OrderBy (INORDER_COMPARER_TYPE&& inorderComparer) const -> Sequence
203 {
204 vector<T> tmp{this->begin (), Iterator<T>{this->end ()}}; // due to Sequence_stdvector move constructor, a not very expensive implementation (but @todo must implement random-access-iterators for Sequence to avoid)
205 stable_sort (tmp.begin (), tmp.end (), forward<INORDER_COMPARER_TYPE> (inorderComparer));
206 return Concrete::Sequence_stdvector<T>{move (tmp)};
207 }
208 template <typename T>
210 {
211 _SafeReadRepAccessor<_IRep> accessor{this}; // important to use READ not WRITE accessor, because write accessor would have already cloned the data
212 if (not accessor._ConstGetRep ().empty ()) {
213 this->_fRep = accessor._ConstGetRep ().CloneEmpty ();
214 }
215 }
216 template <typename T>
217 template <predicate<T> PREDICATE>
218 size_t Sequence<T>::RemoveAll (PREDICATE&& p)
219 {
220 // @todo Consider migrating this method to _IRep? Doing so would allow for different (e.g. vector) implementations
221 // to be more efficient (for example, bubbling last to first); but at a small code-bloat cost, so not likely
222 // worthwhile tradeoff; if this is a performance issue, convert to Sequence_LinkedList{s}.RemoveAll(p) and then convert
223 // back to whatever backend-implementation sequence you wish... --LGP 2022-12-14
224 size_t nRemoved{};
225 for (Iterator<T> i = this->begin (); i != this->end ();) {
226 if (p (*i)) {
227 Remove (i, &i);
228 ++nRemoved;
229 }
230 else {
231 ++i;
232 }
233 }
234 return nRemoved;
235 }
236 template <typename T>
237 inline auto Sequence<T>::GetAt (size_t i) const -> value_type
238 {
239 _SafeReadRepAccessor<_IRep> accessor{this};
240 Require (i < accessor._ConstGetRep ().size ());
241 return accessor._ConstGetRep ().GetAt (i);
242 }
243 template <typename T>
244 inline void Sequence<T>::SetAt (size_t i, ArgByValueType<value_type> item)
245 {
246 _SafeReadWriteRepAccessor<_IRep> accessor{this};
247 Require (i < accessor._ConstGetRep ().size ());
248 accessor._GetWriteableRep ().SetAt (i, item);
249 }
250 template <typename T>
251 inline auto Sequence<T>::operator[] (size_t i) const -> const value_type
252 {
253 _SafeReadRepAccessor<_IRep> accessor{this};
254 Require (i < accessor._ConstGetRep ().size ());
255 return accessor._ConstGetRep ().GetAt (i);
256 }
257 template <typename T>
258 inline auto Sequence<T>::operator() (size_t i) -> TemporaryElementReference_
259 {
260 return TemporaryElementReference_{this, i};
262 template <typename T>
263 template <Common::IEqualsComparer<T> EQUALS_COMPARER>
264 inline optional<size_t> Sequence<T>::IndexOf (ArgByValueType<value_type> item, EQUALS_COMPARER&& equalsComparer) const
265 {
266 return Private::IndexOf_<T, EQUALS_COMPARER> (*this, item, forward<EQUALS_COMPARER> (equalsComparer));
267 }
268 template <typename T>
269 template <Common::IEqualsComparer<T> EQUALS_COMPARER>
270 inline optional<size_t> Sequence<T>::IndexOf (const Sequence& s, EQUALS_COMPARER&& equalsComparer) const
271 {
272 return Private::IndexOf_<T, EQUALS_COMPARER> (*this, s, forward<EQUALS_COMPARER> (equalsComparer));
273 }
274 template <typename T>
275 template <typename IGNORED>
276 inline size_t Sequence<T>::IndexOf (const Iterator<value_type>& i) const
277 {
278 return _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().IndexOf (i);
279 }
280 template <typename T>
281 inline void Sequence<T>::Insert (size_t i, ArgByValueType<value_type> item)
282 {
283 _SafeReadWriteRepAccessor<_IRep> accessor{this};
284 Require (i <= accessor._ConstGetRep ().size ());
285 return accessor._GetWriteableRep ().Insert (i, &item, &item + 1);
286 }
287 template <typename T>
288 inline void Sequence<T>::Insert (const Iterator<value_type>& i, ArgByValueType<value_type> item)
289 {
290 _SafeReadWriteRepAccessor<_IRep> accessor{this};
291 size_t idx = accessor._ConstGetRep ().IndexOf (i);
292 Require (idx <= accessor._ConstGetRep ().size ()); // if equals end, we append
293 return accessor._GetWriteableRep ().Insert (idx, &item, &item + 1);
294 }
295 template <typename T>
296 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<ITERATOR_OF_ADDABLE> ITERATOR_OF_ADDABLE2>
297 void Sequence<T>::InsertAll (size_t i, ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
298 {
299 Require (i <= this->size ());
300 size_t insertAt = i;
301 for (auto ii = forward<ITERATOR_OF_ADDABLE> (start); ii != forward<ITERATOR_OF_ADDABLE2> (end); ++ii) {
302 Insert (insertAt++, *ii);
303 }
304 }
305 template <typename T>
306 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
307 inline void Sequence<T>::InsertAll (size_t i, ITERABLE_OF_ADDABLE&& s)
308 {
309 Require (i <= this->size ());
310 InsertAll (i, s.begin (), s.end ());
311 }
312 template <typename T>
313 inline void Sequence<T>::Prepend (ArgByValueType<value_type> item)
314 {
315 Insert (0, item);
316 }
317 template <typename T>
318 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
319 inline void Sequence<T>::PrependAll (ITERABLE_OF_ADDABLE&& s)
320 {
321 InsertAll (0, forward<ITERABLE_OF_ADDABLE> (s));
322 }
323 template <typename T>
324 template <IInputIterator<T> ITERATOR_OF_ADDABLE>
325 inline void Sequence<T>::PrependAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end)
326 {
327 InsertAll (0, forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE> (end));
328 }
329 template <typename T>
330 inline void Sequence<T>::Append (ArgByValueType<value_type> item)
331 {
332 _SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ().Insert (_IRep::_kSentinelLastItemIndex, &item, &item + 1);
333 }
334 template <typename T>
335 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
336 inline void Sequence<T>::AppendAll (ITERABLE_OF_ADDABLE&& s)
337 {
338 AppendAll (s.begin (), s.end ());
340 template <typename T>
341 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
342 inline void Sequence<T>::AppendAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
343 {
344 _SafeReadWriteRepAccessor<_IRep> accessor = {this};
345 for (auto i = forward<ITERATOR_OF_ADDABLE> (start); i != forward<ITERATOR_OF_ADDABLE2> (end); ++i) {
346 const T& tmp = *i;
347 accessor._GetWriteableRep ().Insert (_IRep::_kSentinelLastItemIndex, &tmp, &tmp + 1);
348 }
349 }
350 template <typename T>
351 inline void Sequence<T>::Update (const Iterator<value_type>& i, ArgByValueType<value_type> newValue, Iterator<value_type>* nextI)
352 {
353 Require (not i.Done ());
354 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
355 writerRep->Update (patchedIterator, newValue, nextI);
356 }
357 template <typename T>
358 inline void Sequence<T>::Remove (size_t i)
360 Require (i < this->size ());
361 _SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ().Remove (i, i + 1);
362 }
363 template <typename T>
364 inline void Sequence<T>::Remove (size_t start, size_t end)
365 {
366 Require (start <= end and end <= this->size ());
367 _SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ().Remove (start, end);
368 }
369 template <typename T>
370 inline void Sequence<T>::Remove (const Iterator<value_type>& i, Iterator<value_type>* nextI)
371 {
372 Require (not i.Done ());
373 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
374 writerRep->Remove (patchedIterator, nextI);
376 template <typename T>
377 template <typename CONTAINER_OF_ADDABLE>
378 inline CONTAINER_OF_ADDABLE Sequence<T>::As () const
379 {
380 // some containers require two iterators as arguments, but Stroika ones work with default_sentinel_t or iterator
381 if constexpr (derived_from<CONTAINER_OF_ADDABLE, Iterable<T>>) {
382 return CONTAINER_OF_ADDABLE{this->begin (), this->end ()};
383 }
384 else {
385 return CONTAINER_OF_ADDABLE{this->begin (), Iterator<T>{this->end ()}};
386 }
387 }
388 template <typename T>
389 template <typename CONTAINER_OF_ADDABLE>
390 inline void Sequence<T>::As (CONTAINER_OF_ADDABLE* into) const
391 {
392 RequireNotNull (into);
393 // @todo change this to constructible_from....
394 if constexpr (derived_from<CONTAINER_OF_ADDABLE, Iterable<T>>) {
395 *into = CONTAINER_OF_ADDABLE{this->begin (), this->end ()};
396 }
397 else {
398 // STL containers may require the two iterator arguments to be of the same type
399 *into = CONTAINER_OF_ADDABLE{this->begin (), Iterator<T>{this->end ()}};
400 }
401 }
402 template <typename T>
403 inline auto Sequence<T>::First () const -> optional<value_type>
404 {
405 return this->empty () ? optional<T>{} : GetAt (0);
406 }
407 template <typename T>
408 inline auto Sequence<T>::First (const function<bool (ArgByValueType<value_type>)>& that) const -> optional<value_type>
409 {
410 return inherited::First (that);
411 }
412 template <typename T>
413 inline auto Sequence<T>::FirstValue (ArgByValueType<value_type> defaultValue) const -> value_type
414 {
415 return this->empty () ? defaultValue : GetAt (0);
416 }
417 template <typename T>
418 inline auto Sequence<T>::Last () const -> optional<value_type>
419 {
420 // IRep::GetAt() defined to allow special _IRep::_kSentinelLastItemIndex
421 return this->empty () ? optional<T>{} : _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().GetAt (_IRep::_kSentinelLastItemIndex);
422 }
423 template <typename T>
424 inline auto Sequence<T>::Last (const function<bool (ArgByValueType<value_type>)>& that) const -> optional<value_type>
425 {
426 // @todo when we have reverse iterators - we could implement this more efficiently by walking the sequence backwards
427 return inherited::Last (that);
428 }
429 template <typename T>
430 inline auto Sequence<T>::LastValue (ArgByValueType<value_type> defaultValue) const -> value_type
432 // IRep::GetAt() defined to allow special _IRep::_kSentinelLastItemIndex
433 return this->empty () ? defaultValue : _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().GetAt (_IRep::_kSentinelLastItemIndex);
434 }
435 template <typename T>
436 inline void Sequence<T>::push_back (ArgByValueType<value_type> item)
437 {
438 Append (item);
439 }
440 template <typename T>
441 inline auto Sequence<T>::back () const -> value_type
442 {
443 return *Last ();
444 }
445 template <typename T>
446 inline auto Sequence<T>::front () const -> value_type
447 {
448 return *First ();
449 }
450 template <typename T>
451 inline void Sequence<T>::clear ()
452 {
453 RemoveAll ();
454 }
455 template <typename T>
456 inline void Sequence<T>::erase (size_t i)
457 {
458 this->Remove (i);
459 }
460 template <typename T>
462 {
463 Iterator<T> nextI{nullptr};
464 this->Remove (i, &nextI);
465 return nextI;
466 }
467 template <typename T>
468 inline auto Sequence<T>::operator+= (ArgByValueType<value_type> item) -> Sequence&
470 Append (item);
471 return *this;
472 }
473 template <typename T>
474 inline auto Sequence<T>::operator+= (const Sequence& items) -> Sequence&
475 {
476 AppendAll (items);
477 return *this;
478 }
479 template <typename T>
480 auto Sequence<T>::_GetWritableRepAndPatchAssociatedIterator (const Iterator<value_type>& i) -> tuple<_IRep*, Iterator<value_type>>
481 {
482 Require (not i.Done ());
483 using element_type = typename inherited::_SharedByValueRepType::element_type;
484 Iterator<value_type> patchedIterator = i;
485 element_type* writableRep = this->_fRep.rwget ([&] (const element_type& prevRepPtr) -> typename inherited::_SharedByValueRepType::shared_ptr_type {
486 return Debug::UncheckedDynamicCast<const _IRep&> (prevRepPtr).CloneAndPatchIterator (&patchedIterator);
487 });
488 AssertNotNull (writableRep);
489 return make_tuple (Debug::UncheckedDynamicCast<_IRep*> (writableRep), move (patchedIterator));
490 }
491 template <typename T>
492 inline void Sequence<T>::_AssertRepValidType () const
493 {
495 _SafeReadRepAccessor<_IRep>{this};
496 }
497 }
498 template <typename T>
499 inline bool Sequence<T>::operator== (const Sequence& rhs) const
500 requires (equality_comparable<T>)
501 {
502 return EqualsComparer<>{}(*this, rhs);
503 }
504 template <typename T>
505 inline auto Sequence<T>::operator<=> (const Sequence& rhs) const
506 requires (three_way_comparable<T>)
508 return ThreeWayComparer<>{}(*this, rhs);
509 }
510
511 /*
512 ********************************************************************************
513 ********************************* operator+ ************************************
514 ********************************************************************************
515 */
516 template <typename T>
518 {
519 Sequence<T> result{lhs};
520 result += rhs;
521 return result;
522 }
523 template <typename T>
524 Sequence<T> operator+ (const Sequence<T>& lhs, const Iterable<T>& rhs)
525 {
526 Sequence<T> result{lhs};
527 result += rhs;
528 return result;
529 }
530 template <typename T>
531 Sequence<T> operator+ (const Sequence<T>& lhs, const Sequence<T>& rhs)
532 {
533 Sequence<T> result{lhs};
534 result += rhs;
535 return result;
537
538}
#define AssertNotNull(p)
Definition Assertions.h:333
#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
#define RequireExpression(c)
Definition Assertions.h:267
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Definition Sequence.h:187
nonvirtual value_type FirstValue(ArgByValueType< value_type > defaultValue={}) const
Definition Sequence.inl:413
nonvirtual void InsertAll(size_t i, ITERATOR_OF_ADDABLE &&start, ITERATOR_OF_ADDABLE2 &&end)
Insert all the given items into this sequence, starting at offset 'i'.
nonvirtual Sequence OrderBy(INORDER_COMPARER_TYPE &&inorderComparer=INORDER_COMPARER_TYPE{}) const
nonvirtual TemporaryElementReference_ operator()(size_t i)
operator() is similar to operator[] - but returning TemporaryElementReference_, and so is updatable/w...
Definition Sequence.inl:258
nonvirtual void PrependAll(ITERABLE_OF_ADDABLE &&s)
typename Iterable< value_type >::template SequentialEqualsComparer< T_EQUALS_COMPARER > EqualsComparer
Definition Sequence.h:327
nonvirtual void push_back(ArgByValueType< value_type > item)
Definition Sequence.inl:436
typename inherited::value_type value_type
Definition Sequence.h:198
nonvirtual bool operator==(const Sequence &rhs) const
Definition Sequence.inl:499
nonvirtual optional< value_type > First() const
Definition Sequence.inl:403
nonvirtual auto operator<=>(const Sequence &rhs) const
Definition Sequence.inl:505
nonvirtual void Insert(size_t i, ArgByValueType< value_type > item)
Definition Sequence.inl:281
nonvirtual optional< size_t > IndexOf(ArgByValueType< value_type > i, EQUALS_COMPARER &&equalsComparer={}) const
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to Sequence, and improve that cas...
Definition Sequence.inl:174
nonvirtual void RemoveAll()
RemoveAll removes all, or all matching (predicate, iterator range, equals comparer or whatever) items...
Definition Sequence.inl:209
nonvirtual value_type LastValue(ArgByValueType< value_type > defaultValue={}) const
Definition Sequence.inl:430
nonvirtual RESULT_CONTAINER Where(INCLUDE_PREDICATE &&includeIfTrue) const
nonvirtual void SetAt(size_t i, ArgByValueType< value_type > item)
Definition Sequence.inl:244
nonvirtual void Prepend(ArgByValueType< value_type > item)
Definition Sequence.inl:313
nonvirtual value_type back() const
Definition Sequence.inl:441
nonvirtual Sequence & operator+=(ArgByValueType< value_type > item)
Alias for Append/AppendAll ().
Definition Sequence.inl:468
nonvirtual value_type GetAt(size_t i) const
Definition Sequence.inl:237
nonvirtual tuple< _IRep *, Iterator< value_type > > _GetWritableRepAndPatchAssociatedIterator(const Iterator< value_type > &i)
Utility to get WRITABLE underlying shared_ptr (replacement for what we normally do - _SafeReadWriteRe...
Definition Sequence.inl:480
nonvirtual void Update(const Iterator< value_type > &i, ArgByValueType< value_type > newValue, Iterator< value_type > *nextI=nullptr)
Definition Sequence.inl:351
nonvirtual optional< value_type > Last() const
Definition Sequence.inl:418
nonvirtual const value_type operator[](size_t i) const
alias for GetAt (i) - but returning const T
Definition Sequence.inl:251
nonvirtual void AppendAll(ITERABLE_OF_ADDABLE &&s)
nonvirtual void Append(ArgByValueType< value_type > item)
Definition Sequence.inl:330
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
static constexpr default_sentinel_t end() noexcept
Support for ranged for, and STL syntax in general.
An Iterator<T> is a copyable object which allows traversing the contents of some container....
Definition Iterator.h:225
nonvirtual bool Done() const
Done () means there is nothing left in this iterator (a synonym for (it == container....
Definition Iterator.inl:147
Collection< T > operator+(const Iterable< T > &lhs, const Collection< T > &rhs)