11#include "Stroika/Foundation/Containers/Private/IterableUtils.h"
36 struct Sequence<T>::TemporaryElementReference_ : conditional_t<is_class_v<T> or is_union_v<T>, T, Common::Empty> {
44 TemporaryElementReference_ (
const TemporaryElementReference_&) =
default;
45 TemporaryElementReference_ (TemporaryElementReference_&&
src)
47 , fIndex_{
src.fIndex_}
52 TemporaryElementReference_ (Sequence<T>*
s,
size_t i)
56 if constexpr (kSubClass_) {
57 *
static_cast<T*
> (
this) =
s->GetAt (i);
60 fValue_ =
s->GetAt (i);
63 TemporaryElementReference_& operator= (
const TemporaryElementReference_&) =
delete;
64 TemporaryElementReference_& operator= (TemporaryElementReference_&&) =
delete;
68 if constexpr (kSubClass_) {
69 *
static_cast<T*
> (
this) = v;
80 if constexpr (kSubClass_) {
81 return *
static_cast<T*
> (
this);
88 requires (
not(kSubClass_))
91 if constexpr (kSubClass_) {
92 return *
static_cast<T*
> (
this);
110 ~TemporaryElementReference_ ()
118 if constexpr (kSubClass_) {
119 IgnoreExceptionsForCall (fV->SetAt (fIndex_, *((T*)
this)));
122 IgnoreExceptionsForCall (fV->SetAt (fIndex_, fValue_));
138 template <
typename T>
139 class Sequence<T>::_IRep::IndexBasedRandomAccessIteratorRep_ :
public RandomAccessIterator<T>::IRep {
141 IndexBasedRandomAccessIteratorRep_ (
const _IRep* rep,
size_t idx)
148 IndexBasedRandomAccessIteratorRep_ (
const IndexBasedRandomAccessIteratorRep_&) =
default;
155 virtual bool AtEnd ()
const override
157 return fIdx_ >= fRep_->size ();
161 if (fIdx_ >= fRep_->size ()) {
164 return fRep_->GetAt (fIdx_);
168 Require (
not AtEnd ());
172 virtual bool Equals (
const typename Iterator<T>::IRep*
rhs)
const override
175 const auto*
r = Debug::UncheckedDynamicCast<const IndexBasedRandomAccessIteratorRep_*> (
rhs);
176 return fIdx_ ==
r->fIdx_;
181 virtual bool AtStart ()
const override
185 virtual T Back ()
override
187 Require (
not AtStart ());
189 return fRep_->GetAt (fIdx_);
194 virtual void Advance (
ptrdiff_t i)
override
196 Require (i >= 0
or static_cast<size_t> (-i) <= fIdx_);
197 fIdx_ =
static_cast<size_t> (
static_cast<ptrdiff_t> (fIdx_) + i);
199 virtual ptrdiff_t Difference (
const typename RandomAccessIterator<T>::IRep*
rhs)
const override
201 if (
rhs ==
nullptr) {
204 const auto*
r = Debug::UncheckedDynamicCast<const IndexBasedRandomAccessIteratorRep_*> (
rhs);
207 virtual const T* PeekAtElement (
ptrdiff_t i)
const override
209 fPeekCache_ = fRep_->GetAt (
static_cast<size_t> (
static_cast<ptrdiff_t> (fIdx_) + i));
210 return &*fPeekCache_;
224 template <
typename T>
229 template <
typename T>
240 template <
typename T>
242 :
inherited{Factory::Sequence_Factory<T>::Default () ()}
244 _AssertRepValidType ();
246 template <
typename T>
251 _AssertRepValidType ();
253#if !qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
254 template <
typename T>
255 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
256 requires (not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>,
Sequence<T>>)
260 AppendAll (forward<ITERABLE_OF_ADDABLE> (src));
261 _AssertRepValidType ();
264 template <
typename T>
268 _AssertRepValidType ();
270 template <
typename T>
274 _AssertRepValidType ();
276 template <
typename T>
277 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
281 AppendAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (end));
282 _AssertRepValidType ();
284 template <
typename T>
287 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().GetBidirectionalIterator ();
289 template <
typename T>
292 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().GetRandomAccessIterator ();
294 template <
typename T>
295 template <
typename RESULT_CONTAINER, invocable<T> ELEMENT_MAPPER>
297 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, T>,
typename RESULT_CONTAINER::value_type> or
298 convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, optional<typename RESULT_CONTAINER::value_type>>)
300 if constexpr (same_as<RESULT_CONTAINER, Sequence>) {
302 return inherited::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper),
303 RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().CloneEmpty ()});
306 return inherited ::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper));
309 template <
typename T>
310 template <derived_from<Iterable<T>> RESULT_CONTAINER, predicate<T> INCLUDE_PREDICATE>
313 if constexpr (same_as<RESULT_CONTAINER, Sequence>) {
315 return inherited::template Where<RESULT_CONTAINER> (
316 forward<INCLUDE_PREDICATE> (includeIfTrue), RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().CloneEmpty ()});
319 return inherited::template Where<RESULT_CONTAINER> (forward<INCLUDE_PREDICATE> (includeIfTrue));
322 template <
typename T>
323 template <IPotentiallyComparer<T> INORDER_COMPARER_TYPE>
324 inline auto Sequence<T>::OrderBy (INORDER_COMPARER_TYPE&& inorderComparer)
const -> Sequence
327 return OrderBy (forward<INORDER_COMPARER_TYPE> (inorderComparer), Execution::SequencePolicy::eSeq);
329 template <
typename T>
330 template <IPotentiallyComparer<T> INORDER_COMPARER_TYPE>
331 auto Sequence<T>::OrderBy (INORDER_COMPARER_TYPE&& inorderComparer, [[maybe_unused]] Execution::SequencePolicy seq)
const -> Sequence
346 vector<T> tmp = this->As<vector<T>> ();
348#if __cpp_lib_execution >= 201603L
349 case Execution::SequencePolicy::ePar:
350 stable_sort (std::execution::par, tmp.begin (), tmp.end (), forward<INORDER_COMPARER_TYPE> (inorderComparer));
355 stable_sort (tmp.begin (), tmp.end (), forward<INORDER_COMPARER_TYPE> (inorderComparer));
360 template <
typename T>
363 _SafeReadRepAccessor<_IRep> accessor{
this};
364 if (not accessor._ConstGetRep ().empty ()) {
365 this->_fRep = accessor._ConstGetRep ().CloneEmpty ();
368 template <
typename T>
369 template <predicate<T> PREDICATE>
377 for (
Iterator<T> i = this->begin (); i != this->end ();) {
388 template <
typename T>
391 _SafeReadRepAccessor<_IRep> accessor{
this};
392 Require (i < accessor._ConstGetRep ().size ());
393 return accessor._ConstGetRep ().GetAt (i);
395 template <
typename T>
398 _SafeReadWriteRepAccessor<_IRep> accessor{
this};
399 Require (i < accessor._ConstGetRep ().size ());
400 accessor._GetWriteableRep ().SetAt (i, item);
402 template <
typename T>
405 _SafeReadRepAccessor<_IRep> accessor{
this};
406 Require (i < accessor._ConstGetRep ().size ());
407 return accessor._ConstGetRep ().GetAt (i);
409 template <
typename T>
412 return TemporaryElementReference_{
this, i};
414 template <
typename T>
415 template <Common::IEqualsComparer<T> EQUALS_COMPARER>
416 inline optional<size_t>
Sequence<T>::IndexOf (ArgByValueType<value_type> item, EQUALS_COMPARER&& equalsComparer)
const
433 _SafeReadRepAccessor<_IRep> accessor{
this};
434 if (
auto s = accessor._ConstGetRep ().PeekContiguousStorage ()) {
436 if constexpr (same_as<remove_cvref_t<EQUALS_COMPARER>, equal_to<T>> or same_as<remove_cvref_t<EQUALS_COMPARER>, equal_to<>>) {
437 return std::find (s->begin (), s->end (), item);
440 return std::find_if (s->begin (), s->end (), [&] (
const T& e) { return equalsComparer (e, item); });
443 if (i == s->end ()) {
444 return optional<size_t>{};
446 return static_cast<size_t> (i - s->begin ());
449 return Private::IndexOf_<T, EQUALS_COMPARER> (*
this, item, forward<EQUALS_COMPARER> (equalsComparer));
451 template <
typename T>
452 template <Common::IEqualsComparer<T> EQUALS_COMPARER>
455 return Private::IndexOf_<T, EQUALS_COMPARER> (*
this, s, forward<EQUALS_COMPARER> (equalsComparer));
457 template <
typename T>
458 template <
typename IGNORED>
459 inline size_t Sequence<T>::IndexOf (
const Iterator<value_type>& i)
const
461 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().IndexOf (i);
463 template <
typename T>
466 _SafeReadWriteRepAccessor<_IRep> accessor{
this};
467 Require (i <= accessor._ConstGetRep ().size ());
468 return accessor._GetWriteableRep ().Insert (i, span{&item, 1u});
470 template <
typename T>
479 _SafeReadWriteRepAccessor<_IRep> accessor{
this};
480 size_t idx = accessor._ConstGetRep ().IndexOf (i);
481 Require (idx <= accessor._ConstGetRep ().size ());
482 return accessor._GetWriteableRep ().Insert (idx, span{&item, 1u});
484 template <
typename T>
489 template <
typename T>
490 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<ITERATOR_OF_ADDABLE> ITERATOR_OF_ADDABLE2>
493 Require (i <= this->size ());
506 if constexpr (contiguous_iterator<remove_cvref_t<ITERATOR_OF_ADDABLE>> and
507 sized_sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE2>, remove_cvref_t<ITERATOR_OF_ADDABLE>> and
508 same_as<remove_cvref_t<iter_value_t<remove_cvref_t<ITERATOR_OF_ADDABLE>>>, T>) {
509 if (start != end) [[likely]] {
510 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Insert (
511 i, span<const T>{to_address (start),
static_cast<size_t> (end - start)});
524 _SafeReadWriteRepAccessor<_IRep> accessor{
this};
526 for (
auto ii = forward<ITERATOR_OF_ADDABLE> (start); ii != forward<ITERATOR_OF_ADDABLE2> (end); ++ii) {
528 if (buf.
size () == kChunkSize_) [[unlikely]] {
529 accessor._GetWriteableRep ().Insert (insertAt, span<const T>{buf.begin (), buf.
size ()});
530 insertAt += buf.
size ();
534 if (buf.
size () != 0) [[likely]] {
535 accessor._GetWriteableRep ().Insert (insertAt, span<const T>{buf.begin (), buf.
size ()});
539 template <
typename T>
540 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
541 inline void Sequence<T>::InsertAll (
size_t i, ITERABLE_OF_ADDABLE&& s)
543 Require (i <= this->size ());
573 if constexpr (derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>,
Iterable<T>>) {
575 bool handled =
false;
577 _SafeReadWriteRepAccessor<_IRep> destAccessor{
this};
578 _IRep& destRep = destAccessor._GetWriteableRep ();
582 _SafeReadRepAccessor<typename Iterable<T>::_IRep> srcAccessor{&s};
583 if (
auto srcSpan = srcAccessor._ConstGetRep ().PeekContiguousStorage ()) {
584 if (not srcSpan->empty ()) [[likely]] {
585 destRep.Insert (i, *srcSpan);
595 InsertAll (i, s.begin (), s.end ());
597 template <
typename T>
602 template <
typename T>
603 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
606 InsertAll (0, forward<ITERABLE_OF_ADDABLE> (s));
608 template <
typename T>
609 template <IInputIterator<T> ITERATOR_OF_ADDABLE>
612 InsertAll (0, forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE> (end));
614 template <
typename T>
617 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().
Insert (_IRep::_kSentinelLastItemIndex, span{&item, 1});
619 template <
typename T>
620 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
627 if constexpr (derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>,
Iterable<T>>) {
629 bool handled =
false;
631 _SafeReadWriteRepAccessor<_IRep> destAccessor{
this};
632 _IRep& destRep = destAccessor._GetWriteableRep ();
636 _SafeReadRepAccessor<typename Iterable<T>::_IRep> srcAccessor{&s};
637 if (
auto srcSpan = srcAccessor._ConstGetRep ().PeekContiguousStorage ()) {
638 if (not srcSpan->empty ()) [[likely]] {
639 destRep.Insert (_IRep::_kSentinelLastItemIndex, *srcSpan);
649 AppendAll (s.begin (), s.end ());
651 template <
typename T>
652 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
653 inline void Sequence<T>::AppendAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
655 _SafeReadWriteRepAccessor<_IRep> accessor = {
this};
674 if constexpr (contiguous_iterator<remove_cvref_t<ITERATOR_OF_ADDABLE>> and
675 sized_sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE2>, remove_cvref_t<ITERATOR_OF_ADDABLE>> and
676 same_as<remove_cvref_t<iter_value_t<remove_cvref_t<ITERATOR_OF_ADDABLE>>>, T>) {
677 if (start != end) [[likely]] {
678 accessor._GetWriteableRep ().Insert (_IRep::_kSentinelLastItemIndex,
679 span<const T>{to_address (start),
static_cast<size_t> (end - start)});
703 for (
auto i = forward<ITERATOR_OF_ADDABLE> (start); i != forward<ITERATOR_OF_ADDABLE2> (end); ++i) {
705 if (buf.
size () == kChunkSize_) [[unlikely]] {
706 accessor._GetWriteableRep ().Insert (_IRep::_kSentinelLastItemIndex, span<const T>{buf.begin (), buf.
size ()});
710 if (buf.
size () != 0) [[likely]] {
711 accessor._GetWriteableRep ().Insert (_IRep::_kSentinelLastItemIndex, span<const T>{buf.begin (), buf.
size ()});
715 template <
typename T>
718 Require (not i.
AtEnd ());
719 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
720 writerRep->Update (patchedIterator, newValue, nextI);
722 template <
typename T>
725 Require (i < this->size ());
726 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Remove (i, i + 1);
728 template <
typename T>
731 Require (start <= end and end <= this->size ());
732 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Remove (start, end);
734 template <
typename T>
735 inline void Sequence<T>::Remove (
const Iterator<value_type>& i, Iterator<value_type>* nextI)
737 Require (not i.AtEnd ());
738 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
739 writerRep->Remove (patchedIterator, nextI);
741 template <
typename T>
742 template <
typename CONTAINER_OF_ADDABLE>
743 inline void Sequence<T>::As (CONTAINER_OF_ADDABLE* into)
const
746 *into = this->
template As<CONTAINER_OF_ADDABLE> ();
748 template <
typename T>
751 return this->empty () ? optional<T>{} : GetAt (0);
753 template <
typename T>
754 inline auto Sequence<T>::First (
const function<
bool (ArgByValueType<value_type>)>& that)
const -> optional<value_type>
756 return inherited::First (that);
758 template <
typename T>
761 return this->empty () ? defaultValue : GetAt (0);
763 template <
typename T>
767 return this->empty () ? optional<T>{} : _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().
GetAt (_IRep::_kSentinelLastItemIndex);
769 template <
typename T>
770 inline auto Sequence<T>::Last (
const function<
bool (ArgByValueType<value_type>)>& that)
const -> optional<value_type>
773 return inherited::Last (that);
775 template <
typename T>
779 return this->empty () ? defaultValue : _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().
GetAt (_IRep::_kSentinelLastItemIndex);
781 template <
typename T>
786 template <
typename T>
787 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
790 AppendAll (forward<ITERABLE_OF_ADDABLE> (s));
792 template <
typename T>
797 template <
typename T>
802 template <
typename T>
807 template <
typename T>
812 template <
typename T>
816 this->Remove (i, &nextI);
819 template <
typename T>
825 template <
typename T>
831 template <
typename T>
834 Require (not i.AtEnd ());
835 using element_type =
typename inherited::_SharedByValueRepType::element_type;
837 element_type* writableRep = this->_fRep.rwget ([&] (
const element_type& prevRepPtr) ->
typename inherited::_SharedByValueRepType::shared_ptr_type {
838 return Debug::UncheckedDynamicCast<const _IRep&> (prevRepPtr).CloneAndPatchIterator (&patchedIterator);
841 return make_tuple (Debug::UncheckedDynamicCast<_IRep*> (writableRep), move (patchedIterator));
843 template <
typename T>
847 _SafeReadRepAccessor<_IRep>{
this};
850 template <
typename T>
852 requires (equality_comparable<T>)
856 template <
typename T>
858 requires (three_way_comparable<T>)
860 return ThreeWayComparer<>{}(*
this, rhs);
868 template <
typename T>
875 template <
typename T>
876 Sequence<T> operator+ (
const Sequence<T>& lhs,
const Iterable<T>& rhs)
878 Sequence<T> result{lhs};
882 template <
typename T>
883 Sequence<T> operator+ (
const Sequence<T>& lhs,
const Sequence<T>& rhs)
885 Sequence<T> result{lhs};
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
#define RequireExpression(c)
bool Equals(const T *lhs, const T *rhs)
strcmp or wsccmp() as appropriate == 0
#define qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCFORCE
[[msvc::no_unique_address]] isn't always broken in MSVC. Annotate with this on things where its not b...
Sequence_stdvector<T> is an std::vector-based concrete implementation of the Sequence<T> container pa...
nonvirtual BidirectionalIterator< T > _MakeBidirectionalIterator_ViaGetAt() const
Generic (backend-independent) implementations of GetBidirectionalIterator (), implemented purely in t...
nonvirtual RandomAccessIterator< T > _MakeRandomAccessIterator_ViaGetAt() const
Generic (backend-independent) implementations of GetRandomAccessIterator (), implemented purely in te...
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual void As(CONTAINER_OF_ADDABLE *into) const
write this Sequence into an existing container
typename Iterable< value_type >::template SequentialEqualsComparer< T_EQUALS_COMPARER > EqualsComparer
typename inherited::value_type value_type
nonvirtual void Insert(size_t i, ArgByValueType< value_type > item)
nonvirtual value_type GetAt(size_t i) const
nonvirtual void AppendAll(ITERABLE_OF_ADDABLE &&s)
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
nonvirtual void push_back(Common::ArgByValueType< T > e)
nonvirtual size_t size() const noexcept
A BidirectionalIterator is an Iterator that can be moved both forward and backward.
Implementation detail for iterator implementors.
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
nonvirtual size_t size() const
Returns the number of items contained.
An Iterator<T> is a copyable object which allows traversing the contents of some container.
nonvirtual bool AtEnd() const
AtEnd () means there is nothing left in this iterator (a synonym for (it == container....