refactor(iterator): split iterator library into multiple files
This commit is contained in:
parent
a55f03fea0
commit
cd7adbfd46
@ -5,6 +5,7 @@
|
|||||||
#include "Iterator/Sentinel.h"
|
#include "Iterator/Sentinel.h"
|
||||||
#include "Iterator/RandomAccessIterator.h"
|
#include "Iterator/RandomAccessIterator.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
|
#include "Memory/Address.h"
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
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/BidirectionalIterator.h"
|
||||||
#include "Iterator/RandomAccessIterator.h"
|
#include "Iterator/RandomAccessIterator.h"
|
||||||
#include "Iterator/ContiguousIterator.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
|
#if PLATFORM_COMPILER_GCC
|
||||||
# pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
#include "Memory/Address.h"
|
|
||||||
#include "Templates/Invoke.h"
|
|
||||||
#include "Iterator/Iterator.h"
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
|
||||||
#include "Templates/Noncopyable.h"
|
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
@ -116,491 +111,6 @@ concept CIndirectlySwappable = CIndirectlyReadable<I> && CIndirectlyReadable<J>
|
|||||||
IndirectlySwap(Jter, Iter);
|
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)
|
NAMESPACE_BEGIN(Iteration)
|
||||||
|
|
||||||
/** @return The iterator to the beginning of a container. */
|
/** @return The iterator to the beginning of a container. */
|
||||||
@ -685,12 +195,6 @@ FORCEINLINE constexpr auto REnd(initializer_list<T> Container)
|
|||||||
|
|
||||||
NAMESPACE_END(Iteration)
|
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(Utility)
|
||||||
NAMESPACE_MODULE_END(Redcraft)
|
NAMESPACE_MODULE_END(Redcraft)
|
||||||
NAMESPACE_REDCRAFT_END
|
NAMESPACE_REDCRAFT_END
|
||||||
|
Loading…
Reference in New Issue
Block a user