#pragma once #include "CoreTypes.h" #include "Iterator/Utility.h" #include "Iterator/Sentinel.h" #include "Iterator/BidirectionalIterator.h" #include "Iterator/RandomAccessIterator.h" #include "Iterator/ContiguousIterator.h" #include "Miscellaneous/Compare.h" #include "TypeTraits/TypeTraits.h" #include "Templates/Utility.h" #include "Memory/Address.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) /** * An iterator adaptor for reverse-order traversal. * When based on at least a bidirectional iterator, the reverse iterator satisfies at least a bidirectional iterator * up to a random access iterator. When based on an output iterator, the reverse iterator satisfies an output iterator. */ template class TReverseIterator final { public: using IteratorType = I; using ElementType = TIteratorElement; FORCEINLINE constexpr TReverseIterator() = default; FORCEINLINE constexpr TReverseIterator(const TReverseIterator&) = default; FORCEINLINE constexpr TReverseIterator(TReverseIterator&&) = default; FORCEINLINE constexpr TReverseIterator& operator=(const TReverseIterator&) = default; FORCEINLINE constexpr TReverseIterator& operator=(TReverseIterator&&) = default; FORCEINLINE constexpr ~TReverseIterator() = default; FORCEINLINE constexpr explicit TReverseIterator(IteratorType InValue) : Current(InValue) { } template requires (!CSameAs && CConstructibleFrom) FORCEINLINE constexpr explicit (!CConvertibleTo) TReverseIterator(const TReverseIterator& InValue) : Current(InValue.GetBase()) { } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) FORCEINLINE constexpr TReverseIterator& operator=(const TReverseIterator& InValue) { Current = InValue.GetBase(); return *this; } template requires (CSentinelFor) NODISCARD friend FORCEINLINE constexpr bool operator==(const TReverseIterator& LHS, const TReverseIterator& RHS) { return LHS.GetBase() == RHS.GetBase(); } template requires (CThreeWayComparable) NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult operator<=>(const TReverseIterator& LHS, const TReverseIterator& RHS) { return RHS.GetBase() <=> LHS.GetBase(); } NODISCARD FORCEINLINE constexpr TIteratorReference operator*() const { IteratorType Temp = GetBase(); return *--Temp; } NODISCARD FORCEINLINE constexpr auto operator->() const requires (requires(const I Iter) { { ToAddress(Iter) } -> CSameAs>; }) { IteratorType Temp = GetBase(); return ToAddress(--Temp); } NODISCARD FORCEINLINE constexpr TIteratorReference operator[](ptrdiff Index) const requires (CRandomAccessIterator) { return GetBase()[-Index - 1]; } FORCEINLINE constexpr TReverseIterator& operator++() { --Current; return *this; } FORCEINLINE constexpr TReverseIterator& operator--() { ++Current; return *this; } FORCEINLINE constexpr TReverseIterator operator++(int) { TReverseIterator Temp = *this; --Current; return Temp; } FORCEINLINE constexpr TReverseIterator operator--(int) { TReverseIterator Temp = *this; ++Current; return Temp; } FORCEINLINE constexpr TReverseIterator& operator+=(ptrdiff Offset) requires (CRandomAccessIterator) { Current -= Offset; return *this; } FORCEINLINE constexpr TReverseIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator) { Current += Offset; return *this; } NODISCARD FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset) const requires (CRandomAccessIterator) { TReverseIterator Temp = *this; Temp -= Offset; return Temp; } NODISCARD FORCEINLINE constexpr TReverseIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator) { TReverseIterator Temp = *this; Temp += Offset; return Temp; } NODISCARD friend FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset, const TReverseIterator& Iter) requires (CRandomAccessIterator) { return Iter + Offset; } NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TReverseIterator& LHS, const TReverseIterator& RHS) requires (CRandomAccessIterator) { return RHS.GetBase() - LHS.GetBase(); } NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; } NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return MoveTemp(Current); } private: IteratorType Current; }; template requires (!CSizedSentinelFor) inline constexpr bool bDisableSizedSentinelFor, TReverseIterator> = true; static_assert(CBidirectionalIterator>>); static_assert( CRandomAccessIterator>>); static_assert( CRandomAccessIterator>>); static_assert(COutputIterator>, int>); /** Creates a TReverseIterator of type inferred from the argument. */ template requires (CBidirectionalIterator> && CConstructibleFrom, I>) NODISCARD FORCEINLINE constexpr auto MakeReverseIterator(I&& Iter) { return TReverseIterator>(Forward(Iter)); } NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END