refactor(iterator): split iterator library into multiple files
This commit is contained in:
		@@ -5,6 +5,7 @@
 | 
			
		||||
#include "Iterator/Sentinel.h"
 | 
			
		||||
#include "Iterator/RandomAccessIterator.h"
 | 
			
		||||
#include "TypeTraits/TypeTraits.h"
 | 
			
		||||
#include "Memory/Address.h"
 | 
			
		||||
 | 
			
		||||
NAMESPACE_REDCRAFT_BEGIN
 | 
			
		||||
NAMESPACE_MODULE_BEGIN(Redcraft)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										152
									
								
								Redcraft.Utility/Source/Public/Iterator/CountedIterator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								Redcraft.Utility/Source/Public/Iterator/CountedIterator.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
#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/AssertionMacros.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)
 | 
			
		||||
 | 
			
		||||
NAMESPACE_PRIVATE_BEGIN
 | 
			
		||||
 | 
			
		||||
template <typename            T> class TCountedIteratorImpl    {                                                  };
 | 
			
		||||
template <CIndirectlyReadable T> class TCountedIteratorImpl<T> { public: using ElementType = TIteratorElement<T>; };
 | 
			
		||||
 | 
			
		||||
NAMESPACE_PRIVATE_END
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An iterator adaptor that tracks the distance to the end of the range.
 | 
			
		||||
 * When based on an input or output iterator, the counted iterator satisfies at least an input or output iterator
 | 
			
		||||
 * up to a contiguous iterator. When based on an output iterator, the counted iterator satisfies an output iterator.
 | 
			
		||||
 * When based on iterator satisfies sentinel for itself, the counted iterator satisfies sized sentinel for itself.
 | 
			
		||||
 */
 | 
			
		||||
template <CInputOrOutputIterator I>
 | 
			
		||||
class TCountedIterator final : public NAMESPACE_PRIVATE::TCountedIteratorImpl<I>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using IteratorType = I;
 | 
			
		||||
 | 
			
		||||
#	if DO_CHECK
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator() requires (CDefaultConstructible<I>) : Length(1), MaxLength(0) { }
 | 
			
		||||
#	else
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator() requires (CDefaultConstructible<I>) = default;
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator(const TCountedIterator&)            = default;
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator(TCountedIterator&&)                 = default;
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator&) = default;
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator&&)      = default;
 | 
			
		||||
	FORCEINLINE constexpr ~TCountedIterator()                                  = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr explicit TCountedIterator(IteratorType InValue, ptrdiff N) : Current(MoveTemp(InValue)) { check_code({ MaxLength = N; }); }
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (!CSameAs<I, J> && CConstructibleFrom<I, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<const J&, I>) TCountedIterator(const TCountedIterator<J>& InValue)
 | 
			
		||||
		: Current(InValue.GetBase()), Length(InValue.Num())
 | 
			
		||||
	{
 | 
			
		||||
		check_code({ MaxLength = InValue.MaxLength; });
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (!CSameAs<I, J> && CConvertibleTo<const J&, I> && CAssignableFrom<I&, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator<J>& InValue)
 | 
			
		||||
	{
 | 
			
		||||
		Current = InValue.GetBase();
 | 
			
		||||
		Length  = InValue.Num();
 | 
			
		||||
 | 
			
		||||
		check_code({ MaxLength = InValue.MaxLength; });
 | 
			
		||||
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (CCommonType<I, J>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr bool operator==(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Length == RHS.Length; }
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (CCommonType<I, J>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Length <=> RHS.Length; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr bool operator==(FDefaultSentinel) const& { return Length == static_cast<ptrdiff>(0); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(FDefaultSentinel) const& { return static_cast<ptrdiff>(0) <=> Length; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReference<I> operator*()                                             { CheckThis(true); return *GetBase();  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReference<I> operator*()  const requires (CDereferenceable<const I>) { CheckThis(true); return *GetBase();  }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr auto operator->() const requires (requires(const I Iter) { { ToAddress(Iter) } -> CSameAs<TIteratorPointer<I>>; }) { return ToAddress(GetBase()); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReference<I> operator[](ptrdiff Index) const requires (CRandomAccessIterator<I>) { TCountedIterator Temp = *this + Index; return *Temp; }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator++()                                      { ++Current; --Length; CheckThis(); return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator--() requires (CBidirectionalIterator<I>) { --Current; ++Length; CheckThis(); return *this; }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr auto             operator++(int)                                      {                                           --Length; CheckThis(); return Current++; }
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator operator++(int) requires       (CForwardIterator<I>) { TCountedIterator Temp = *this; ++Current; --Length; CheckThis(); return Temp;      }
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator operator--(int) requires (CBidirectionalIterator<I>) { TCountedIterator Temp = *this; --Current; ++Length; CheckThis(); return Temp;      }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator+=(ptrdiff Offset) requires (CRandomAccessIterator<I>) { Current += Offset; Length -= Offset; CheckThis(); return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator<I>) { Current -= Offset; Length += Offset; CheckThis(); return *this; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TCountedIterator operator+(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TCountedIterator Temp = *this; Temp += Offset; return Temp; }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TCountedIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TCountedIterator Temp = *this; Temp -= Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TCountedIterator operator+(ptrdiff Offset, TCountedIterator Iter) requires (CRandomAccessIterator<I>) { return Iter + Offset; }
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (CCommonType<I, J>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { LHS.CheckThis(); RHS.CheckThis(); return LHS.Length - RHS.Length; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, FDefaultSentinel) { LHS.CheckThis(); return -LHS.Num(); }
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(FDefaultSentinel, const TCountedIterator& RHS) { RHS.CheckThis(); return  RHS.Num(); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { CheckThis(); return          Current;  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       IteratorType  GetBase() &&     { CheckThis(); return MoveTemp(Current); }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       ptrdiff           Num() const  { CheckThis(); return          Length;   }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	IteratorType Current;
 | 
			
		||||
	ptrdiff      Length;
 | 
			
		||||
 | 
			
		||||
#	if DO_CHECK
 | 
			
		||||
	ptrdiff MaxLength;
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE void CheckThis(bool bExceptEnd = false) const
 | 
			
		||||
	{
 | 
			
		||||
		checkf(static_cast<ptrdiff>(0) <= Length && Length <= MaxLength, TEXT("Read access violation. Please check Num()."));
 | 
			
		||||
		checkf(!(bExceptEnd && Length == static_cast<ptrdiff>(0)),       TEXT("Read access violation. Please check Num()."));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J>
 | 
			
		||||
	friend class TCountedIterator;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(        CInputIterator<TCountedIterator<        IInputIterator<int&>>>);
 | 
			
		||||
static_assert(      CForwardIterator<TCountedIterator<      IForwardIterator<int&>>>);
 | 
			
		||||
static_assert(CBidirectionalIterator<TCountedIterator<IBidirectionalIterator<int&>>>);
 | 
			
		||||
static_assert( CRandomAccessIterator<TCountedIterator< IRandomAccessIterator<int&>>>);
 | 
			
		||||
static_assert(   CContiguousIterator<TCountedIterator<   IContiguousIterator<int&>>>);
 | 
			
		||||
 | 
			
		||||
//static_assert(COutputIterator<TCountedIterator<IOutputIterator<int&>>, int>);
 | 
			
		||||
 | 
			
		||||
static_assert(CSizedSentinelFor<TCountedIterator<IForwardIterator<int>>, TCountedIterator<IForwardIterator<int>>>);
 | 
			
		||||
 | 
			
		||||
/** Creates a TCountedIterator of type inferred from the argument. */
 | 
			
		||||
template <typename I> requires (CInputOrOutputIterator<TDecay<I>> && CConstructibleFrom<TDecay<I>, I>)
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeCountedIterator(I&& Iter, ptrdiff N)
 | 
			
		||||
{
 | 
			
		||||
	return TCountedIterator<TDecay<I>>(Forward<I>(Iter), N);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NAMESPACE_MODULE_END(Utility)
 | 
			
		||||
NAMESPACE_MODULE_END(Redcraft)
 | 
			
		||||
NAMESPACE_REDCRAFT_END
 | 
			
		||||
							
								
								
									
										150
									
								
								Redcraft.Utility/Source/Public/Iterator/InsertIterator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								Redcraft.Utility/Source/Public/Iterator/InsertIterator.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "CoreTypes.h"
 | 
			
		||||
#include "Iterator/Utility.h"
 | 
			
		||||
#include "TypeTraits/TypeTraits.h"
 | 
			
		||||
#include "Templates/Noncopyable.h"
 | 
			
		||||
#include "Templates/Utility.h"
 | 
			
		||||
 | 
			
		||||
NAMESPACE_REDCRAFT_BEGIN
 | 
			
		||||
NAMESPACE_MODULE_BEGIN(Redcraft)
 | 
			
		||||
NAMESPACE_MODULE_BEGIN(Utility)
 | 
			
		||||
 | 
			
		||||
NAMESPACE_PRIVATE_BEGIN
 | 
			
		||||
 | 
			
		||||
template <typename F> class TInsertProxy;
 | 
			
		||||
template <typename F> class TPostIncrementProxy;
 | 
			
		||||
template <typename F> class TInsertIterator;
 | 
			
		||||
 | 
			
		||||
template <typename F>
 | 
			
		||||
class TInsertProxy final : private FSingleton
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#	if	DO_CHECK
 | 
			
		||||
	FORCEINLINE ~TInsertProxy() { checkf(bIsProduced, TEXT("Exception insert, Ensures that the value is assigned to the inserter.")); }
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	template <typename T> requires (CInvocable<F, T>)
 | 
			
		||||
	FORCEINLINE constexpr void operator=(T&& InValue) const
 | 
			
		||||
	{
 | 
			
		||||
		checkf(!bIsProduced, TEXT("Exception insert, Ensure that no multiple values are assigned to the inserter."));
 | 
			
		||||
		Invoke(Iter.Storage, Forward<T>(InValue));
 | 
			
		||||
		check_code({ bIsProduced = true; });
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	TInsertIterator<F>& Iter;
 | 
			
		||||
 | 
			
		||||
#	if	DO_CHECK
 | 
			
		||||
	mutable bool bIsProduced;
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TInsertProxy(TInsertIterator<F>& InIter) : Iter(InIter) { check_code({ bIsProduced = false; }); }
 | 
			
		||||
 | 
			
		||||
	template <typename> friend class TPostIncrementProxy;
 | 
			
		||||
	template <typename> friend class TInsertIterator;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(CAssignableFrom<TInsertProxy<void(*)(int)>, int>);
 | 
			
		||||
 | 
			
		||||
template <typename F>
 | 
			
		||||
class TPostIncrementProxy : private FSingleton
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#	if	DO_CHECK
 | 
			
		||||
	FORCEINLINE ~TPostIncrementProxy() { checkf(bIsProduced, TEXT("Exception insert, Ensures that the value is assigned to the inserter.")); }
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TInsertProxy<F> operator*() const
 | 
			
		||||
	{
 | 
			
		||||
		checkf(!bIsProduced, TEXT("Exception insert, Ensure that no multiple values are assigned to the inserter."));
 | 
			
		||||
		check_code({ bIsProduced = true; });
 | 
			
		||||
		return TInsertProxy(Iter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	TInsertIterator<F>& Iter;
 | 
			
		||||
 | 
			
		||||
#	if	DO_CHECK
 | 
			
		||||
	mutable bool bIsProduced;
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TPostIncrementProxy(TInsertIterator<F>& InIter) : Iter(InIter) { check_code({ bIsProduced = false; }); }
 | 
			
		||||
 | 
			
		||||
	template <typename> friend class TInsertProxy;
 | 
			
		||||
	template <typename> friend class TInsertIterator;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(CIndirectlyWritable<TPostIncrementProxy<void(*)(int)>, int>);
 | 
			
		||||
 | 
			
		||||
template <typename F>
 | 
			
		||||
class TInsertIterator final : private FNoncopyable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TInsertIterator() requires (CDefaultConstructible<F>) = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr explicit TInsertIterator(F InInserter) : Storage(MoveTemp(InInserter)) { check_code({ bIsProduced = false; }); }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TInsertIterator(TInsertIterator&&)            = default;
 | 
			
		||||
	FORCEINLINE constexpr TInsertIterator& operator=(TInsertIterator&&) = default;
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TInsertProxy<F> operator*()
 | 
			
		||||
	{
 | 
			
		||||
		checkf(!bIsProduced, TEXT("Exception insert, Ensure that no multiple values are assigned to the inserter."));
 | 
			
		||||
		check_code({ bIsProduced = true; });
 | 
			
		||||
		return TInsertProxy<F>(*this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TInsertIterator& operator++() { check_code({ bIsProduced = false; }); return *this; }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TPostIncrementProxy<F> operator++(int)
 | 
			
		||||
	{
 | 
			
		||||
		checkf(!bIsProduced, TEXT("Exception insert, Ensure that no multiple values are assigned to the inserter."));
 | 
			
		||||
		return TPostIncrementProxy<F>(*this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	F Storage;
 | 
			
		||||
 | 
			
		||||
#	if DO_CHECK
 | 
			
		||||
	bool bIsProduced;
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	template <typename> friend class TInsertProxy;
 | 
			
		||||
	template <typename> friend class TPostIncrementProxy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(COutputIterator<TInsertIterator<void(*)(int)>, int>);
 | 
			
		||||
 | 
			
		||||
NAMESPACE_PRIVATE_END
 | 
			
		||||
 | 
			
		||||
/** Creates an iterator adapter inserted in the front of the container. */
 | 
			
		||||
template <typename C>
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeFrontInserter(C& Container)
 | 
			
		||||
{
 | 
			
		||||
	return NAMESPACE_PRIVATE::TInsertIterator([&Container]<typename T>(T&& A) { Container.PushFront(Forward<T>(A)); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates an iterator adapter inserted in the back of the container. */
 | 
			
		||||
template <typename C>
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeBackInserter(C& Container)
 | 
			
		||||
{
 | 
			
		||||
	return NAMESPACE_PRIVATE::TInsertIterator([&Container]<typename T>(T&& A) { Container.PushBack(Forward<T>(A)); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates an iterator adapter inserted in the container. */
 | 
			
		||||
template <typename C>
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeInserter(C& Container, const typename C::ConstIterator& InIter)
 | 
			
		||||
{
 | 
			
		||||
	return NAMESPACE_PRIVATE::TInsertIterator([&Container, Iter = InIter]<typename T>(T&& A) mutable { Iter = Container.Insert(Iter, Forward<T>(A)); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NAMESPACE_MODULE_END(Utility)
 | 
			
		||||
NAMESPACE_MODULE_END(Redcraft)
 | 
			
		||||
NAMESPACE_REDCRAFT_END
 | 
			
		||||
@@ -7,3 +7,7 @@
 | 
			
		||||
#include "Iterator/BidirectionalIterator.h"
 | 
			
		||||
#include "Iterator/RandomAccessIterator.h"
 | 
			
		||||
#include "Iterator/ContiguousIterator.h"
 | 
			
		||||
#include "Iterator/ReverseIterator.h"
 | 
			
		||||
#include "Iterator/MoveIterator.h"
 | 
			
		||||
#include "Iterator/CountedIterator.h"
 | 
			
		||||
#include "Iterator/InsertIterator.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										156
									
								
								Redcraft.Utility/Source/Public/Iterator/MoveIterator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								Redcraft.Utility/Source/Public/Iterator/MoveIterator.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,156 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "CoreTypes.h"
 | 
			
		||||
#include "Iterator/Utility.h"
 | 
			
		||||
#include "Iterator/Sentinel.h"
 | 
			
		||||
#include "Iterator/ForwardIterator.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 which dereferences to a rvalue reference.
 | 
			
		||||
 * When based on at least an input iterator, the move iterator satisfies at least an input iterator
 | 
			
		||||
 * up to a random access iterator.
 | 
			
		||||
 */
 | 
			
		||||
template <CInputIterator I>
 | 
			
		||||
class TMoveIterator final
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using IteratorType = I;
 | 
			
		||||
 | 
			
		||||
	using ElementType = TIteratorElement<I>;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator()                                = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator(const TMoveIterator&)            = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator(TMoveIterator&&)                 = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator=(const TMoveIterator&) = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator=(TMoveIterator&&)      = default;
 | 
			
		||||
	FORCEINLINE constexpr ~TMoveIterator()                               = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr explicit TMoveIterator(IteratorType InValue) : Current(MoveTemp(InValue)) { }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (!CSameAs<I, J> && CConstructibleFrom<I, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<const J&, I>) TMoveIterator(const TReverseIterator<J>& InValue) : Current(InValue.GetBase()) { }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (!CSameAs<I, J> && CConvertibleTo<const J&, I> && CAssignableFrom<I&, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator=(const TMoveIterator<J>& InValue) { Current = InValue.GetBase(); return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (CSentinelFor<J, I>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr bool operator==(const TMoveIterator& LHS, const TMoveIterator<J>& RHS) { return LHS.GetBase() == RHS.GetBase(); }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (CThreeWayComparable<I, J>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult<I, J> operator<=>(const TMoveIterator& LHS, const TMoveIterator<J>& RHS) { return RHS.GetBase() <=> LHS.GetBase(); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorRValueReference<I> operator*() const { return MoveTemp(*GetBase()); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorRValueReference<I> operator[](ptrdiff Index) const requires (CRandomAccessIterator<I>) { return MoveTemp(GetBase()[Index]); }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator++()                                      { ++Current; return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator--() requires (CBidirectionalIterator<I>) { --Current; return *this; }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr void          operator++(int)                                      {                      Current++;  }
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator operator++(int) requires       (CForwardIterator<I>) { return TMoveIterator(Current++); }
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator operator--(int) requires (CBidirectionalIterator<I>) { return TMoveIterator(Current--); }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator+=(ptrdiff Offset) requires (CRandomAccessIterator<I>) { Current += Offset; return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator<I>) { Current -= Offset; return *this; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TMoveIterator operator+(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TMoveIterator Temp = *this; Temp += Offset; return Temp; }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TMoveIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TMoveIterator Temp = *this; Temp -= Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TMoveIterator operator+(ptrdiff Offset, const TMoveIterator& Iter) requires (CRandomAccessIterator<I>) { return Iter + Offset; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator& LHS, const TMoveIterator& RHS) requires (CRandomAccessIterator<I>) { return LHS.GetBase() - RHS.GetBase(); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return          Current;  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       IteratorType  GetBase() &&     { return MoveTemp(Current); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	IteratorType Current;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename I, typename J> requires (!CSizedSentinelFor<I, J>)
 | 
			
		||||
inline constexpr bool bDisableSizedSentinelFor<TMoveIterator<I>, TMoveIterator<J>> = true;
 | 
			
		||||
 | 
			
		||||
static_assert(        CInputIterator<TMoveIterator<        IInputIterator<int&>>>);
 | 
			
		||||
static_assert(      CForwardIterator<TMoveIterator<      IForwardIterator<int&>>>);
 | 
			
		||||
static_assert(CBidirectionalIterator<TMoveIterator<IBidirectionalIterator<int&>>>);
 | 
			
		||||
static_assert( CRandomAccessIterator<TMoveIterator< IRandomAccessIterator<int&>>>);
 | 
			
		||||
static_assert( CRandomAccessIterator<TMoveIterator<   IContiguousIterator<int&>>>);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A sentinel adaptor for use with TMoveIterator.
 | 
			
		||||
 * Whether based on un-sized or sized sentinel, the move sentinel satisfies the corresponding concept.
 | 
			
		||||
 */
 | 
			
		||||
template <CSemiregular S>
 | 
			
		||||
class TMoveSentinel
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using SentinelType = S;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel()                                = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel(const TMoveSentinel&)            = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel(TMoveSentinel&&)                 = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel& operator=(const TMoveSentinel&) = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel& operator=(TMoveSentinel&&)      = default;
 | 
			
		||||
	FORCEINLINE constexpr ~TMoveSentinel()                               = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr explicit TMoveSentinel(SentinelType InValue) : Last(InValue) { }
 | 
			
		||||
 | 
			
		||||
	template <CSemiregular T> requires (!CSameAs<S, T> && CConstructibleFrom<S, const T&>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<const T&, S>) TMoveSentinel(const TMoveSentinel<T>& InValue) : Last(InValue.Last) { }
 | 
			
		||||
 | 
			
		||||
	template <CSemiregular T> requires (!CSameAs<S, T> && CConvertibleTo<const T&, S> && CAssignableFrom<S&, const T&>)
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel& operator=(const TMoveSentinel<T>& InValue) { Last = InValue.GetBase(); return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator I> requires (CSentinelFor<S, I>)
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr bool operator==(const TMoveIterator<I>& InValue) const& { return GetBase() == InValue.GetBase(); }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator I> requires (CSizedSentinelFor<S, I>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveSentinel& Sentinel, const TMoveIterator<I>& Iter) { return Sentinel.GetBase() - Iter.GetBase(); }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator I> requires (CSizedSentinelFor<S, I>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator<I>& Iter, const TMoveSentinel& Sentinel) { return Iter.GetBase() - Sentinel.GetBase(); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr const SentinelType& GetBase() const& { return          Last;  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       SentinelType  GetBase() &&     { return MoveTemp(Last); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	SentinelType Last;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(     CSentinelFor<TMoveSentinel<     ISentinelFor<IInputIterator<int>>>, TMoveIterator<IInputIterator<int>>>);
 | 
			
		||||
static_assert(CSizedSentinelFor<TMoveSentinel<ISizedSentinelFor<IInputIterator<int>>>, TMoveIterator<IInputIterator<int>>>);
 | 
			
		||||
 | 
			
		||||
/** Creates a TMoveIterator of type inferred from the argument. */
 | 
			
		||||
template <typename I> requires (CInputIterator<TDecay<I>> && CConstructibleFrom<TDecay<I>, I>)
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeMoveIterator(I&& Iter)
 | 
			
		||||
{
 | 
			
		||||
	return TMoveIterator<TDecay<I>>(Forward<I>(Iter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates a TMoveSentinel of type inferred from the argument. */
 | 
			
		||||
template <typename I> requires (CSemiregular<TDecay<I>> && CConstructibleFrom<TDecay<I>, I>)
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeMoveSentinel(I&& Iter)
 | 
			
		||||
{
 | 
			
		||||
	return TMoveSentinel<TDecay<I>>(Forward<I>(Iter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NAMESPACE_MODULE_END(Utility)
 | 
			
		||||
NAMESPACE_MODULE_END(Redcraft)
 | 
			
		||||
NAMESPACE_REDCRAFT_END
 | 
			
		||||
							
								
								
									
										102
									
								
								Redcraft.Utility/Source/Public/Iterator/ReverseIterator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								Redcraft.Utility/Source/Public/Iterator/ReverseIterator.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
#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 <CBidirectionalIterator I>
 | 
			
		||||
class TReverseIterator final
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using IteratorType = I;
 | 
			
		||||
 | 
			
		||||
	using ElementType = TIteratorElement<I>;
 | 
			
		||||
 | 
			
		||||
	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 <CBidirectionalIterator J> requires (!CSameAs<I, J> && CConstructibleFrom<I, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<const J&, I>) TReverseIterator(const TReverseIterator<J>& InValue) : Current(InValue.GetBase()) { }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (!CSameAs<I, J> && CConvertibleTo<const J&, I> && CAssignableFrom<I&, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr TReverseIterator& operator=(const TReverseIterator<J>& InValue) { Current = InValue.GetBase(); return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (CSentinelFor<J, I>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr bool operator==(const TReverseIterator& LHS, const TReverseIterator<J>& RHS) { return LHS.GetBase() == RHS.GetBase(); }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (CThreeWayComparable<I, J>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult<I, J> operator<=>(const TReverseIterator& LHS, const TReverseIterator<J>& RHS) { return RHS.GetBase() <=> LHS.GetBase(); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReference<I> operator*() const { IteratorType Temp = GetBase(); return *--Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr auto operator->() const requires (requires(const I Iter) { { ToAddress(Iter) } -> CSameAs<TIteratorPointer<I>>; }) { IteratorType Temp = GetBase(); return ToAddress(--Temp); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReference<I> operator[](ptrdiff Index) const requires (CRandomAccessIterator<I>) { 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<I>) { Current -= Offset; return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TReverseIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator<I>) { Current += Offset; return *this; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TReverseIterator Temp = *this; Temp -= Offset; return Temp; }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TReverseIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TReverseIterator Temp = *this; Temp += Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset, const TReverseIterator& Iter) requires (CRandomAccessIterator<I>) { return Iter + Offset; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TReverseIterator& LHS, const TReverseIterator& RHS) requires (CRandomAccessIterator<I>) { 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 <typename I, typename J> requires (!CSizedSentinelFor<I, J>)
 | 
			
		||||
inline constexpr bool bDisableSizedSentinelFor<TReverseIterator<I>, TReverseIterator<J>> = true;
 | 
			
		||||
 | 
			
		||||
static_assert(CBidirectionalIterator<TReverseIterator<IBidirectionalIterator<int&>>>);
 | 
			
		||||
static_assert( CRandomAccessIterator<TReverseIterator< IRandomAccessIterator<int&>>>);
 | 
			
		||||
static_assert( CRandomAccessIterator<TReverseIterator<   IContiguousIterator<int&>>>);
 | 
			
		||||
 | 
			
		||||
static_assert(COutputIterator<TReverseIterator<IBidirectionalIterator<int&>>, int>);
 | 
			
		||||
 | 
			
		||||
/** Creates a TReverseIterator of type inferred from the argument. */
 | 
			
		||||
template <typename I> requires (CBidirectionalIterator<TDecay<I>> && CConstructibleFrom<TDecay<I>, I>)
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeReverseIterator(I&& Iter)
 | 
			
		||||
{
 | 
			
		||||
	return TReverseIterator<TDecay<I>>(Forward<I>(Iter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NAMESPACE_MODULE_END(Utility)
 | 
			
		||||
NAMESPACE_MODULE_END(Redcraft)
 | 
			
		||||
NAMESPACE_REDCRAFT_END
 | 
			
		||||
@@ -92,6 +92,20 @@ static_assert(
 | 
			
		||||
	}
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
struct FDefaultSentinel { explicit FDefaultSentinel() = default; };
 | 
			
		||||
 | 
			
		||||
inline constexpr FDefaultSentinel DefaultSentinel{ };
 | 
			
		||||
 | 
			
		||||
struct FUnreachableSentinel
 | 
			
		||||
{
 | 
			
		||||
	explicit FUnreachableSentinel() = default;
 | 
			
		||||
 | 
			
		||||
	template <CWeaklyIncrementable I>
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr bool operator==(const I&) const& { return false; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline constexpr FUnreachableSentinel UnreachableSentinel{ };
 | 
			
		||||
 | 
			
		||||
#if PLATFORM_COMPILER_GCC
 | 
			
		||||
#	pragma GCC diagnostic pop
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,8 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "CoreTypes.h"
 | 
			
		||||
#include "Memory/Address.h"
 | 
			
		||||
#include "Templates/Invoke.h"
 | 
			
		||||
#include "Iterator/Iterator.h"
 | 
			
		||||
#include "Templates/Utility.h"
 | 
			
		||||
#include "Templates/Noncopyable.h"
 | 
			
		||||
#include "TypeTraits/TypeTraits.h"
 | 
			
		||||
#include "Miscellaneous/Compare.h"
 | 
			
		||||
#include "Miscellaneous/AssertionMacros.h"
 | 
			
		||||
 | 
			
		||||
NAMESPACE_REDCRAFT_BEGIN
 | 
			
		||||
@@ -116,491 +111,6 @@ concept CIndirectlySwappable = CIndirectlyReadable<I> && CIndirectlyReadable<J>
 | 
			
		||||
		IndirectlySwap(Jter, Iter);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
/** A iterator adaptor for reverse-order traversal. */
 | 
			
		||||
template <CBidirectionalIterator I>
 | 
			
		||||
class TReverseIterator final
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using IteratorType = I;
 | 
			
		||||
 | 
			
		||||
	using ElementType = TIteratorElementType<I>;
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
	template <typename T = IteratorType> requires (!CSameAs<TReverseIterator, TRemoveCVRef<T>> && CConstructibleFrom<IteratorType, T>)
 | 
			
		||||
	FORCEINLINE constexpr explicit TReverseIterator(T&& InValue) : Current(Forward<T>(InValue)) { }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (!CSameAs<IteratorType, J> && CConstructibleFrom<IteratorType, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<const J&, IteratorType>) TReverseIterator(const TReverseIterator<J>& InValue) : Current(InValue.Current) { }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (!CSameAs<IteratorType, J> && CConstructibleFrom<IteratorType, J>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<J&&, IteratorType>) TReverseIterator(TReverseIterator<J>&& InValue) : Current(MoveTemp(InValue).Current) { }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (!CSameAs<IteratorType, J> && CConvertibleTo<const J&, IteratorType> && CAssignableFrom<IteratorType&, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr TReverseIterator& operator=(const TReverseIterator<J>& InValue) { Current = InValue.Current; return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (!CSameAs<IteratorType, J> && CConvertibleTo<J&&, IteratorType> && CAssignableFrom<IteratorType&, J&&>)
 | 
			
		||||
	FORCEINLINE constexpr TReverseIterator& operator=(TReverseIterator<J>&& InValue) { Current = MoveTemp(InValue).Current; return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (CSentinelFor<J, IteratorType>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr bool operator==(const TReverseIterator& LHS, const TReverseIterator<J>& RHS) { return LHS.Current == RHS.Current; }
 | 
			
		||||
 | 
			
		||||
	template <CBidirectionalIterator J> requires (CSizedSentinelFor<J, IteratorType>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult<J, IteratorType> operator<=>(const TReverseIterator& LHS, const TReverseIterator<J>& RHS) { return RHS.Current <=> LHS.Current; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReferenceType<IteratorType> operator*()  const { IteratorType Temp = Current; return          *--Temp;  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorPointerType<IteratorType>   operator->() const { IteratorType Temp = Current; return ToAddress(--Temp); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReferenceType<IteratorType> operator[](ptrdiff Index) const requires (CRandomAccessIterator<IteratorType>) { return Current[-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<IteratorType>) { Current -= Offset; return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TReverseIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { Current += Offset; return *this; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TReverseIterator operator+(TReverseIterator Iter, ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { TReverseIterator Temp = Iter; Temp -= Offset; return Temp; }
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset, TReverseIterator Iter) requires (CRandomAccessIterator<IteratorType>) { TReverseIterator Temp = Iter; Temp -= Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TReverseIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<IteratorType>) { TReverseIterator Temp = *this; Temp += Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TReverseIterator& LHS, const TReverseIterator& RHS) { return RHS.Current - LHS.Current; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return          Current;  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       IteratorType  GetBase() &&     { return MoveTemp(Current); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	IteratorType Current;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(CRandomAccessIterator<TReverseIterator<int32*>>);
 | 
			
		||||
 | 
			
		||||
template <typename I, typename J> requires (!CSizedSentinelFor<I, J>)
 | 
			
		||||
inline constexpr bool bDisableSizedSentinelFor<TReverseIterator<I>, TReverseIterator<J>> = true;
 | 
			
		||||
 | 
			
		||||
/** An iterator adaptor which dereferences to a rvalue reference. */
 | 
			
		||||
template <CInputIterator I>
 | 
			
		||||
class TMoveIterator final
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using IteratorType = I;
 | 
			
		||||
 | 
			
		||||
	using ElementType = TIteratorElementType<I>;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator() = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator(const TMoveIterator&)            = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator(TMoveIterator&&)                 = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator=(const TMoveIterator&) = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator=(TMoveIterator&&)      = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr ~TMoveIterator() = default;
 | 
			
		||||
 | 
			
		||||
	template <typename T = IteratorType> requires (!CSameAs<TMoveIterator, TRemoveCVRef<T>> && CConstructibleFrom<IteratorType, T>)
 | 
			
		||||
	FORCEINLINE constexpr explicit TMoveIterator(T&& InValue) : Current(Forward<T>(InValue)) { }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (!CSameAs<IteratorType, J> && CConstructibleFrom<IteratorType, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<const J&, IteratorType>) TMoveIterator(const TMoveIterator<J>& InValue) : Current(InValue.Current) { }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (!CSameAs<IteratorType, J> && CConstructibleFrom<IteratorType, J>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<J&&, IteratorType>) TMoveIterator(TMoveIterator<J>&& InValue) : Current(MoveTemp(InValue).Current) { }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (!CSameAs<IteratorType, J> && CConvertibleTo<const J&, IteratorType> && CAssignableFrom<IteratorType&, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator=(const TMoveIterator<J>& InValue) { Current = InValue.Current; return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (!CSameAs<IteratorType, J> && CConvertibleTo<J&&, IteratorType> && CAssignableFrom<IteratorType&, J&&>)
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator=(TMoveIterator<J>&& InValue) { Current = MoveTemp(InValue).Current; return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (CSentinelFor<J, IteratorType>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr bool operator==(const TMoveIterator& LHS, const TMoveIterator<J>& RHS) { return LHS.Current == RHS.Current; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator J> requires (CSizedSentinelFor<J, IteratorType>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult<J, IteratorType> operator<=>(const TMoveIterator& LHS, const TMoveIterator<J>& RHS) { return LHS.Current <=> RHS.Current; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorRValueReferenceType<IteratorType> operator*()  const { return MoveTemp(*Current); }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorPointerType<IteratorType>         operator->() const = delete;
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorRValueReferenceType<IteratorType> operator[](ptrdiff Index) const requires (CRandomAccessIterator<IteratorType>) { return MoveTemp(Current[Index]); }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator++()                                                 { ++Current; return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator--() requires (CBidirectionalIterator<IteratorType>) { --Current; return *this; }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr void          operator++(int)                                                 {                      Current++;  }
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator operator++(int) requires       (CForwardIterator<IteratorType>) { return TMoveIterator(Current++); }
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator operator--(int) requires (CBidirectionalIterator<IteratorType>) { return TMoveIterator(Current--); }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator+=(ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { Current += Offset; return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TMoveIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { Current -= Offset; return *this; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TMoveIterator operator+(TMoveIterator Iter, ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { TMoveIterator Temp = Iter; Temp += Offset; return Temp; }
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TMoveIterator operator+(ptrdiff Offset, TMoveIterator Iter) requires (CRandomAccessIterator<IteratorType>) { TMoveIterator Temp = Iter; Temp += Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TMoveIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<IteratorType>) { TMoveIterator Temp = *this; Temp -= Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator& LHS, const TMoveIterator& RHS) requires (CSizedSentinelFor<I, I>) { return LHS.Current - RHS.Current; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return          Current;  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       IteratorType  GetBase() &&     { return MoveTemp(Current); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	IteratorType Current;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(CRandomAccessIterator<TMoveIterator<int32*>>);
 | 
			
		||||
 | 
			
		||||
/** A sentinel adaptor for use with TMoveIterator. */
 | 
			
		||||
template <CSemiregular S>
 | 
			
		||||
class TMoveSentinel
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using SentinelType = S;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel() = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel(const TMoveSentinel&)            = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel(TMoveSentinel&&)                 = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel& operator=(const TMoveSentinel&) = default;
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel& operator=(TMoveSentinel&&)      = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr ~TMoveSentinel() = default;
 | 
			
		||||
 | 
			
		||||
	template <typename T = SentinelType> requires (!CSameAs<TMoveSentinel, TRemoveCVRef<T>> && CConstructibleFrom<SentinelType, T>)
 | 
			
		||||
	FORCEINLINE constexpr explicit TMoveSentinel(T&& InValue) : Current(Forward<T>(InValue)) { }
 | 
			
		||||
 | 
			
		||||
	template <CSemiregular T> requires (!CSameAs<SentinelType, T> && CConstructibleFrom<SentinelType, const T&>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<const T&, SentinelType>) TMoveSentinel(const TMoveSentinel<T>& InValue) : Current(InValue.Current) { }
 | 
			
		||||
 | 
			
		||||
	template <CSemiregular T> requires (!CSameAs<SentinelType, T> && CConstructibleFrom<SentinelType, T>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<T&&, SentinelType>) TMoveSentinel(TMoveSentinel<T>&& InValue) : Current(MoveTemp(InValue).Current) { }
 | 
			
		||||
 | 
			
		||||
	template <CSemiregular T> requires (!CSameAs<SentinelType, T> && CConvertibleTo<const T&, SentinelType> && CAssignableFrom<SentinelType&, const T&>)
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel& operator=(const TMoveSentinel<T>& InValue) { Current = InValue.Current; return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CSemiregular T> requires (!CSameAs<SentinelType, T> && CConvertibleTo<T&&, SentinelType> && CAssignableFrom<SentinelType&, T&&>)
 | 
			
		||||
	FORCEINLINE constexpr TMoveSentinel& operator=(TMoveSentinel<T>&& InValue) { Current = MoveTemp(InValue).Current; return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator I> requires (CSentinelFor<SentinelType, I>)
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr bool operator==(const TMoveIterator<I>& InValue) const& { return Current == InValue.Current; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator I> requires (CSizedSentinelFor<SentinelType, I>)
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TCompareThreeWayResult<SentinelType, I> operator<=>(const TMoveIterator<I>& InValue) const& { return Current <=> InValue.Current; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator I> requires (CSizedSentinelFor<SentinelType, I>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveSentinel& Sentinel, const TMoveIterator<I>& Iter) { return Sentinel.Current - Iter.Current; }
 | 
			
		||||
 | 
			
		||||
	template <CInputIterator I> requires (CSizedSentinelFor<SentinelType, I>)
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator<I>& Iter, const TMoveSentinel& Sentinel) { return Iter.Current - Sentinel.Current; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr const SentinelType& GetBase() const& { return          Current;  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       SentinelType  GetBase() &&     { return MoveTemp(Current); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	SentinelType Current;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(CSizedSentinelFor<TMoveSentinel<int32*>, TMoveIterator<int32*>>);
 | 
			
		||||
 | 
			
		||||
struct FDefaultSentinel { explicit FDefaultSentinel() = default; };
 | 
			
		||||
 | 
			
		||||
inline constexpr FDefaultSentinel DefaultSentinel{ };
 | 
			
		||||
 | 
			
		||||
struct FUnreachableSentinel
 | 
			
		||||
{
 | 
			
		||||
	explicit FUnreachableSentinel() = default;
 | 
			
		||||
 | 
			
		||||
	template <CWeaklyIncrementable I>
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr bool operator==(const I&) const& { return false; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline constexpr FUnreachableSentinel UnreachableSentinel{ };
 | 
			
		||||
 | 
			
		||||
/** An iterator adaptor that tracks the distance to the end of the range. */
 | 
			
		||||
template <CInputOrOutputIterator I>
 | 
			
		||||
class TCountedIterator final
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using IteratorType = I;
 | 
			
		||||
 | 
			
		||||
	using ElementType = TIteratorElementType<I>;
 | 
			
		||||
 | 
			
		||||
#	if DO_CHECK
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator() requires (CDefaultConstructible<IteratorType>) : Length(1), MaxLength(0) { }
 | 
			
		||||
#	else
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator() requires (CDefaultConstructible<IteratorType>) = default;
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator(const TCountedIterator&)            = default;
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator(TCountedIterator&&)                 = default;
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator&) = default;
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator&&)      = default;
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr ~TCountedIterator() = default;
 | 
			
		||||
 | 
			
		||||
	template <typename T = IteratorType> requires (!CSameAs<TCountedIterator, TRemoveCVRef<T>> && CConstructibleFrom<IteratorType, T>)
 | 
			
		||||
	FORCEINLINE constexpr explicit TCountedIterator(T&& InValue, ptrdiff N) : Current(Forward<T>(InValue)), Length(N) { check_code({ MaxLength = N; }); }
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (!CSameAs<IteratorType, J> && CConstructibleFrom<IteratorType, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<const J&, IteratorType>) TCountedIterator(const TCountedIterator<J>& InValue) : Current(InValue.Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); }
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (!CSameAs<IteratorType, J> && CConstructibleFrom<IteratorType, J>)
 | 
			
		||||
	FORCEINLINE constexpr explicit (!CConvertibleTo<J&&, IteratorType>) TCountedIterator(TCountedIterator<J>&& InValue) : Current(MoveTemp(InValue).Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); }
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (!CSameAs<IteratorType, J> && CConvertibleTo<const J&, IteratorType> && CAssignableFrom<IteratorType&, const J&>)
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator<J>& InValue) { Current = InValue.Current; Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J> requires (!CSameAs<IteratorType, J> && CConvertibleTo<J&&, IteratorType> && CAssignableFrom<IteratorType&, J&&>)
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator<J>&& InValue) { Current = MoveTemp(InValue).Current; Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; }
 | 
			
		||||
 | 
			
		||||
	template <CCommonType<IteratorType> J>
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr bool operator==(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Length == RHS.Length; }
 | 
			
		||||
 | 
			
		||||
	template <CCommonType<IteratorType> J>
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Length <=> RHS.Length; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr bool operator==(FDefaultSentinel) const& { return Length == static_cast<ptrdiff>(0); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(FDefaultSentinel) const& { return static_cast<ptrdiff>(0) <=> Length; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReferenceType<IteratorType> operator*() { CheckThis(true); return *Current; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReferenceType<IteratorType> operator*() const requires (CDereferenceable<const IteratorType>) { CheckThis(true); return *Current; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorPointerType<IteratorType> operator->() const requires (CContiguousIterator<IteratorType>) { CheckThis(false); return ToAddress(Current); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TIteratorReferenceType<IteratorType> operator[](ptrdiff Index) const requires (CRandomAccessIterator<IteratorType>) { TCountedIterator Temp = *this + Index; return *Temp; }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator++()                                                 { ++Current; --Length; CheckThis(); return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator--() requires (CBidirectionalIterator<IteratorType>) { --Current; ++Length; CheckThis(); return *this; }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr auto             operator++(int)                                                 {                                           --Length; CheckThis(); return Current++; }
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator operator++(int) requires       (CForwardIterator<IteratorType>) { TCountedIterator Temp = *this; ++Current; --Length; CheckThis(); return Temp;      }
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator operator--(int) requires (CBidirectionalIterator<IteratorType>) { TCountedIterator Temp = *this; --Current; ++Length; CheckThis(); return Temp;      }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator+=(ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { Current += Offset; Length -= Offset; CheckThis(); return *this; }
 | 
			
		||||
	FORCEINLINE constexpr TCountedIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { Current -= Offset; Length += Offset; CheckThis(); return *this; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TCountedIterator operator+(TCountedIterator Iter, ptrdiff Offset) requires (CRandomAccessIterator<IteratorType>) { TCountedIterator Temp = Iter; Temp += Offset; return Temp; }
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr TCountedIterator operator+(ptrdiff Offset, TCountedIterator Iter) requires (CRandomAccessIterator<IteratorType>) { TCountedIterator Temp = Iter; Temp += Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr TCountedIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<IteratorType>) { TCountedIterator Temp = *this; Temp -= Offset; return Temp; }
 | 
			
		||||
 | 
			
		||||
	template <CCommonType<IteratorType> J>
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { LHS.CheckThis(); RHS.CheckThis(); return LHS.Length - RHS.Length; }
 | 
			
		||||
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, FDefaultSentinel) { LHS.CheckThis(); return -LHS.Num(); }
 | 
			
		||||
	NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(FDefaultSentinel, const TCountedIterator& RHS) { RHS.CheckThis(); return  RHS.Num(); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { CheckThis(); return          Current;  }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       IteratorType  GetBase() &&     { CheckThis(); return MoveTemp(Current); }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       ptrdiff           Num() const  { CheckThis(); return          Length;   }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	IteratorType Current;
 | 
			
		||||
	ptrdiff      Length;
 | 
			
		||||
 | 
			
		||||
#	if DO_CHECK
 | 
			
		||||
	ptrdiff MaxLength;
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE void CheckThis(bool bExceptEnd = false) const
 | 
			
		||||
	{
 | 
			
		||||
		checkf(static_cast<ptrdiff>(0) <= Length && Length <= MaxLength, TEXT("Read access violation. Please check Num()."));
 | 
			
		||||
		checkf(!(bExceptEnd && Length == static_cast<ptrdiff>(0)),       TEXT("Read access violation. Please check Num()."));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	template <CInputOrOutputIterator J>
 | 
			
		||||
	friend class TCountedIterator;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(CContiguousIterator<TCountedIterator<int32*>>);
 | 
			
		||||
static_assert(CSizedSentinelFor<FDefaultSentinel, TCountedIterator<int32*>>);
 | 
			
		||||
 | 
			
		||||
NAMESPACE_PRIVATE_BEGIN
 | 
			
		||||
 | 
			
		||||
/** An output iterator adapter that wraps a callable object. */
 | 
			
		||||
template <CMoveConstructible F>
 | 
			
		||||
class TOutputIterator final : private FNoncopyable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	using Outputer = F;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	class FIndirectionProxy : private FSingleton
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
 | 
			
		||||
		FORCEINLINE constexpr FIndirectionProxy(TOutputIterator& InIter) : Iter(InIter) { check_code({ bIsProduced = false; }); }
 | 
			
		||||
 | 
			
		||||
#		if	DO_CHECK
 | 
			
		||||
		FORCEINLINE ~FIndirectionProxy()
 | 
			
		||||
		{
 | 
			
		||||
			checkf(bIsProduced, TEXT("Exception output, Ensures that the value is assigned to the output iterator."));
 | 
			
		||||
		}
 | 
			
		||||
#		endif
 | 
			
		||||
 | 
			
		||||
		template <typename T> requires (CInvocable<Outputer, T>)
 | 
			
		||||
		FORCEINLINE constexpr void operator=(T&& InValue) const
 | 
			
		||||
		{
 | 
			
		||||
			checkf(!bIsProduced, TEXT("Exception output, Ensure that no multiple values are assigned to the output iterator."));
 | 
			
		||||
			Invoke(Iter.Storage, Forward<T>(InValue));
 | 
			
		||||
			check_code({ bIsProduced = true; });
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
 | 
			
		||||
		TOutputIterator& Iter;
 | 
			
		||||
 | 
			
		||||
#		if	DO_CHECK
 | 
			
		||||
		mutable bool bIsProduced;
 | 
			
		||||
#		endif
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class FPostIncrementProxy : private FSingleton
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
 | 
			
		||||
		FORCEINLINE constexpr FPostIncrementProxy(TOutputIterator& InIter) : Iter(InIter) { check_code({ bIsProduced = false; }); }
 | 
			
		||||
 | 
			
		||||
#		if	DO_CHECK
 | 
			
		||||
		FORCEINLINE ~FPostIncrementProxy()
 | 
			
		||||
		{
 | 
			
		||||
			checkf(bIsProduced, TEXT("Exception output, Ensures that the value is assigned to the output iterator."));
 | 
			
		||||
		}
 | 
			
		||||
#		endif
 | 
			
		||||
 | 
			
		||||
		NODISCARD FORCEINLINE constexpr FIndirectionProxy operator*() const
 | 
			
		||||
		{
 | 
			
		||||
			checkf(!bIsProduced, TEXT("Exception output, Ensure that no multiple values are assigned to the output iterator."));
 | 
			
		||||
			check_code({ bIsProduced = true; });
 | 
			
		||||
			return FIndirectionProxy(Iter);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
 | 
			
		||||
		TOutputIterator& Iter;
 | 
			
		||||
 | 
			
		||||
#		if	DO_CHECK
 | 
			
		||||
		mutable bool bIsProduced;
 | 
			
		||||
#		endif
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TOutputIterator() requires (CDefaultConstructible<Outputer>) { check_code({ bIsProduced = false; }); }
 | 
			
		||||
 | 
			
		||||
	template <typename T> requires (!CSameAs<TOutputIterator, TRemoveCVRef<T>> && CConstructibleFrom<Outputer, T>)
 | 
			
		||||
	FORCEINLINE constexpr explicit TOutputIterator(T&& InOutputer) : Storage(Forward<T>(InOutputer)) { check_code({ bIsProduced = false; }); }
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr FIndirectionProxy operator*()
 | 
			
		||||
	{
 | 
			
		||||
		checkf(!bIsProduced, TEXT("Exception output, Ensure that no multiple values are assigned to the output iterator."));
 | 
			
		||||
		check_code({ bIsProduced = true; });
 | 
			
		||||
		return FIndirectionProxy(*this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr TOutputIterator& operator++() { check_code({ bIsProduced = false; }); return *this; }
 | 
			
		||||
 | 
			
		||||
	FORCEINLINE constexpr FPostIncrementProxy operator++(int)
 | 
			
		||||
	{
 | 
			
		||||
		checkf(!bIsProduced, TEXT("Exception output, Ensure that no multiple values are assigned to the output iterator."));
 | 
			
		||||
		return FPostIncrementProxy(*this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr const Outputer& GetOutputer() const& { return Storage; }
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr       Outputer  GetOutputer() &&     { return Storage; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	Outputer Storage;
 | 
			
		||||
 | 
			
		||||
#	if DO_CHECK
 | 
			
		||||
	bool bIsProduced;
 | 
			
		||||
#	endif
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static_assert(COutputIterator<TOutputIterator<void(*)(int32)>, int32>);
 | 
			
		||||
 | 
			
		||||
template <typename F>
 | 
			
		||||
TOutputIterator(F) -> TOutputIterator<F>;
 | 
			
		||||
 | 
			
		||||
NAMESPACE_PRIVATE_END
 | 
			
		||||
 | 
			
		||||
/** Creates a TReverseIterator of type inferred from the argument. */
 | 
			
		||||
template <typename I> requires (CBidirectionalIterator<TDecay<I>> && CConstructibleFrom<TDecay<I>, I>)
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeReverseIterator(I&& Iter)
 | 
			
		||||
{
 | 
			
		||||
	return TReverseIterator<TDecay<I>>(Forward<I>(Iter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates a TMoveIterator of type inferred from the argument. */
 | 
			
		||||
template <typename I> requires (CInputIterator<TDecay<I>> && CConstructibleFrom<TDecay<I>, I>)
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeMoveIterator(I&& Iter)
 | 
			
		||||
{
 | 
			
		||||
	return TMoveIterator<TDecay<I>>(Forward<I>(Iter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates a TMoveSentinel of type inferred from the argument. */
 | 
			
		||||
template <typename I> requires (CSemiregular<TDecay<I>> && CConstructibleFrom<TDecay<I>, I>)
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeMoveSentinel(I&& Iter)
 | 
			
		||||
{
 | 
			
		||||
	return TMoveSentinel<TDecay<I>>(Forward<I>(Iter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates a TCountedIterator of type inferred from the argument. */
 | 
			
		||||
template <typename I> requires (CInputOrOutputIterator<TDecay<I>> && CConstructibleFrom<TDecay<I>, I>)
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeCountedIterator(I&& Iter, ptrdiff N)
 | 
			
		||||
{
 | 
			
		||||
	return TCountedIterator<TDecay<I>>(Forward<I>(Iter), N);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates an iterator adapter inserted in the front of the container. */
 | 
			
		||||
template <typename C>
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeFrontInserter(C& Container)
 | 
			
		||||
{
 | 
			
		||||
	return NAMESPACE_PRIVATE::TOutputIterator([&Container]<typename T>(T&& A) { Container.PushFront(Forward<T>(A)); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates an iterator adapter inserted in the back of the container. */
 | 
			
		||||
template <typename C>
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeBackInserter(C& Container)
 | 
			
		||||
{
 | 
			
		||||
	return NAMESPACE_PRIVATE::TOutputIterator([&Container]<typename T>(T&& A) { Container.PushBack(Forward<T>(A)); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Creates an iterator adapter inserted in the container. */
 | 
			
		||||
template <typename C>
 | 
			
		||||
NODISCARD FORCEINLINE constexpr auto MakeInserter(C& Container, const typename C::ConstIterator& InIter)
 | 
			
		||||
{
 | 
			
		||||
	return NAMESPACE_PRIVATE::TOutputIterator([&Container, Iter = InIter]<typename T>(T&& A) mutable { Iter = Container.Insert(Iter, Forward<T>(A)); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NAMESPACE_BEGIN(Iteration)
 | 
			
		||||
 | 
			
		||||
/** @return The iterator to the beginning of a container. */
 | 
			
		||||
@@ -685,12 +195,6 @@ FORCEINLINE constexpr auto REnd(initializer_list<T> Container)
 | 
			
		||||
 | 
			
		||||
NAMESPACE_END(Iteration)
 | 
			
		||||
 | 
			
		||||
#define ENABLE_RANGE_BASED_FOR_LOOP_SUPPORT public:                        \
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr auto begin()       { return Begin(); } \
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr auto begin() const { return Begin(); } \
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr auto end()         { return End();   } \
 | 
			
		||||
	NODISCARD FORCEINLINE constexpr auto end()   const { return End();   }
 | 
			
		||||
 | 
			
		||||
NAMESPACE_MODULE_END(Utility)
 | 
			
		||||
NAMESPACE_MODULE_END(Redcraft)
 | 
			
		||||
NAMESPACE_REDCRAFT_END
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user