408 while (cur-- > end) {
412 fLength_ = newLength;
415#if qStroika_Foundation_Debug_AssertionsChecked
416 template <
typename T>
417 void Array<T>::Invariant_ () const noexcept
419#if qStroika_Foundation_Containers_DataStructures_Array_IncludeSlowDebugChecks_
422 Assert ((fSlotsAllocated_ == 0) == (fItems_ ==
nullptr));
423 Assert (fLength_ <= fSlotsAllocated_);
426 template <
typename T>
427 inline Array<T>::~Array ()
430 if constexpr (kUseMalloc_) {
431 if (fItems_ !=
nullptr) {
436 delete[] (
char*)fItems_;
439 template <
typename T>
440 inline void Array<T>::MoveIteratorHereAfterClone (IteratorBase* pi, [[maybe_unused]]
const Array<T>* movedFrom)
const
445 Require (pi->CurrentIndex () <= this->size ());
446 Require (pi->_fData == movedFrom);
449 template <
typename T>
455 template <
typename T>
461 template <
typename T>
466 Require (i < fLength_);
469 template <
typename T>
474 Require (i < fLength_);
477 template <
typename T>
482 Require (i < fLength_);
485 template <
typename T>
490 Require (i < fLength_);
493 template <
typename T>
498 Require (i < fLength_);
501 template <
typename T>
506 Require (i < fLength_);
509 template <
typename T>
515 template <
typename T>
519 return fLength_ == 0;
521 template <
typename T>
525 return fSlotsAllocated_;
527 template <
typename T>
528 inline void Array<T>::shrink_to_fit ()
533 template <
typename T>
537 Require (not i.AtEnd ());
538 Require (i._fData ==
this);
539 this->Remove (i.CurrentIndex ());
541 template <
typename T>
545 Require (not i.AtEnd ());
546 Require (i._fData ==
this);
547 size_t idx = i.CurrentIndex ();
549 if (idx == this->fLength_) {
556 template <
typename T>
560 Require (not i.AtEnd ());
561 this->Remove (i.CurrentIndex ());
563 template <
typename T>
564 inline void Array<T>::SetAt (
const ForwardIterator& i, ArgByValueType<T> newValue)
567 Require (i._fData ==
this);
568 Require (not i.AtEnd ());
569 SetAt (i.CurrentIndex (), newValue);
571 template <
typename T>
572 inline void Array<T>::SetAt (
const BackwardIterator& i, ArgByValueType<T> newValue)
575 Require (not i.AtEnd ());
576 SetAt (i.CurrentIndex (), newValue);
584 template <
typename T>
585 inline Array<T>::IteratorBase::IteratorBase (
const Array* data)
590#if qStroika_Foundation_Debug_AssertionsChecked
591 template <
typename T>
592 inline Array<T>::IteratorBase::~IteratorBase ()
594#if qStroika_Foundation_Debug_AssertionsChecked
596 _fData =
reinterpret_cast<Array<T>*
> (-1);
597 _fCurrentIdx = numeric_limits<size_t>::max ();
601 template <
typename T>
602 inline size_t Array<T>::IteratorBase::CurrentIndex ()
const
611 template <
typename T>
612 inline const T& Array<T>::IteratorBase::operator* ()
const
617 Require (0 <= _fCurrentIdx and _fCurrentIdx < _fData->fLength_);
618 return _fData->fItems_[_fCurrentIdx];
620 template <
typename T>
621 inline const T* Array<T>::IteratorBase::operator->()
const
626 Require (0 <= _fCurrentIdx and _fCurrentIdx < _fData->fLength_);
627 return _fData->PeekAt (_fCurrentIdx);
629 template <
typename T>
630 inline void Array<T>::IteratorBase::SetIndex (
size_t i)
634 Require (i <= _fData->fLength_);
637 template <
typename T>
647 template <
typename T>
652 Require (i <= _fData->fLength_);
655 template <
typename T>
658#if qStroika_Foundation_Debug_AssertionsChecked
659 Require (
data == _fData);
662 template <
typename T>
665#if qStroika_Foundation_Debug_AssertionsChecked
669#if qStroika_Foundation_Debug_AssertionsChecked
670 template <
typename T>
673 Assert (0 <= _fCurrentIdx);
674 if (_fData !=
nullptr) {
675#if qStroika_Foundation_Containers_DataStructures_Array_IncludeSlowDebugChecks_
678 Assert (_fCurrentIdx <= _fData->fLength_);
688 template <
typename T>
693 this->_fCurrentIdx = startAt;
696 template <
typename T>
699 this->_fData = -src._fData;
700 this->_fCurrentIdx = src._fCurrentIdx;
701 src._fData =
nullptr;
703 template <
typename T>
708 template <
typename T>
711 if (this->_fData ==
nullptr) {
712 Assert (this->_fCurrentIdx == 0);
715#if qStroika_Foundation_Containers_DataStructures_Array_IncludeSlowDebugChecks_
721 template <
typename T>
722 inline bool Array<T>::ForwardIterator::AtEnd () const noexcept
724 if (this->_fData ==
nullptr) {
725 Assert (this->_fCurrentIdx == 0);
728#if qStroika_Foundation_Containers_DataStructures_Array_IncludeSlowDebugChecks_
734 template <
typename T>
735 inline auto Array<T>::ForwardIterator::operator++ () noexcept -> ForwardIterator&
738 Require (not this->AtEnd ());
740 Assert (this->_fCurrentIdx < this->_fData->fLength_);
741 ++this->_fCurrentIdx;
745 template <
typename T>
746 inline auto Array<T>::ForwardIterator::operator++ (
int)
noexcept -> ForwardIterator
748 ForwardIterator result = *
this;
752 template <
typename T>
753 inline auto Array<T>::ForwardIterator::operator-- () noexcept -> ForwardIterator&
756 Require (not this->AtStart ());
758 Assert (this->_fCurrentIdx <= this->_fData->fLength_);
759 --this->_fCurrentIdx;
763 template <
typename T>
764 inline auto Array<T>::ForwardIterator::operator-- (
int)
noexcept -> ForwardIterator
766 ForwardIterator result = *
this;
770 template <
typename T>
773 size_t newIdx =
static_cast<difference_type
> (this->_fCurrentIdx) + i;
774 Require (newIdx <= this->_fData->fLength_);
775 return ForwardIterator{this->_fData, newIdx};
777 template <
typename T>
780 size_t newIdx =
static_cast<difference_type
> (this->_fCurrentIdx) - i;
781 Require (newIdx <= this->_fData->fLength_);
782 return ForwardIterator{this->_fData, newIdx};
784 template <
typename T>
785 inline auto Array<T>::ForwardIterator::operator+= (difference_type i) -> ForwardIterator&
787 this->_fCurrentIdx += i;
788 Require (this->_fCurrentIdx <= this->_fData->fLength_);
791 template <
typename T>
792 inline auto Array<T>::ForwardIterator::operator-= (difference_type i) -> ForwardIterator&
794 this->_fCurrentIdx -= i;
795 Require (this->_fCurrentIdx <= this->_fData->fLength_);
798 template <
typename T>
799 inline const T& Array<T>::ForwardIterator::operator[] (difference_type i)
const
801 size_t newIdx =
static_cast<difference_type
> (this->_fCurrentIdx) + i;
802 Require (newIdx < this->_fData->fLength_);
803 return this->_fData->fItems_[newIdx];
805 template <
typename T>
806 inline bool Array<T>::ForwardIterator::operator== (
const ForwardIterator& rhs)
const
808 auto thisDone = this->AtEnd ();
809 bool rhsDone = rhs.AtEnd ();
810 if (thisDone or rhsDone) {
811 return thisDone and rhsDone;
813 Require (this->_fData == rhs._fData);
814 return this->_fCurrentIdx == rhs._fCurrentIdx;
816 template <
typename T>
817 inline strong_ordering Array<T>::ForwardIterator::operator<=> (
const ForwardIterator& rhs)
const
819 auto thisDone = this->AtEnd ();
820 bool rhsDone = rhs.AtEnd ();
822 return rhsDone ? strong_ordering::equal : strong_ordering::less;
825 Assert (not thisDone);
826 return strong_ordering::greater;
828 Require (this->_fData == rhs._fData);
829 return this->_fCurrentIdx <=> rhs._fCurrentIdx;
831 template <
typename T>
832 inline typename Array<T>::ForwardIterator operator+ (
typename Array<T>::ForwardIterator::difference_type i,
833 const typename Array<T>::ForwardIterator& it)
837 template <
typename T>
838 inline typename Array<T>::ForwardIterator operator- (
typename Array<T>::ForwardIterator::difference_type i,
839 const typename Array<T>::ForwardIterator& it)
843 template <
typename T>
844 auto Array<T>::ForwardIterator::OPERATOR_MINUS_BWA_ (
const ForwardIterator& lhs,
const ForwardIterator& rhs) -> difference_type
846 using difference_type =
typename Array<T>::ForwardIterator::difference_type;
857 difference_type lhsIdx =
static_cast<difference_type
> (rhs._fData->size ());
858 difference_type rhsIdx =
static_cast<difference_type
> (rhs.CurrentIndex ());
859 return lhsIdx - rhsIdx;
864 difference_type lhsIdx =
static_cast<difference_type
> (lhs.CurrentIndex ());
865 difference_type rhsIdx =
static_cast<difference_type
> (lhs._fData->size ());
866 return lhsIdx - rhsIdx;
869 difference_type lhsIdx =
static_cast<difference_type
> (lhs.CurrentIndex ());
870 difference_type rhsIdx =
static_cast<difference_type
> (rhs.CurrentIndex ());
871 return lhsIdx - rhsIdx;
883 template <
typename T>
888 this->_fCurrent = startAt;
891 template <
typename T>
892 inline Array<T>::BackwardIterator::BackwardIterator (
const Array*
data)
896 template <
typename T>
897 inline bool Array<T>::BackwardIterator::AtEnd () const noexcept
899#if qStroika_Foundation_Containers_DataStructures_Array_IncludeSlowDebugChecks_
903 return bool (this->
CurrentIndex () == this->_fData->fLength_);
905 template <
typename T>
906 inline auto Array<T>::BackwardIterator::operator++ () noexcept -> BackwardIterator&
909 Require (not this->AtEnd ());
911 if (this->_fCurrent == this->_fStart) {
912 this->_fCurrent = this->_fEnd;
913 Ensure (this->AtEnd ());
917 Ensure (not this->AtEnd ());
922 template <
typename T>
923 inline bool Array<T>::BackwardIterator::operator== (
const BackwardIterator& rhs)
const
925 auto thisDone = this->AtEnd ();
926 bool rhsDone = rhs.AtEnd ();
927 if (thisDone or rhsDone) {
928 return thisDone and rhsDone;
930 Require (this->_fData == rhs._fData);
931 return this->_fCurrentIdx == rhs._fCurrentIdx;