Compare commits
6 Commits
9d901df68a
...
ba9d35c1ff
Author | SHA1 | Date | |
---|---|---|---|
ba9d35c1ff | |||
8113d3b39b | |||
89dc5b715e | |||
e3e127752e | |||
8d02b0e0a9 | |||
7525c9a5dd |
@ -4,11 +4,11 @@
|
||||
#include "Memory/Allocator.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "Memory/MemoryOperator.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
#include "Miscellaneous/ConstantIterator.h"
|
||||
|
||||
|
@ -6,11 +6,11 @@
|
||||
#include "Containers/Array.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "Containers/StaticArray.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
|
@ -5,12 +5,12 @@
|
||||
#include "Memory/Allocator.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "Templates/Noncopyable.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "Memory/MemoryOperator.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Containers/StaticArray.h"
|
||||
#include "Containers/ArrayView.h"
|
||||
|
@ -4,11 +4,11 @@
|
||||
#include "Memory/Allocator.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "Memory/MemoryOperator.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
#include "Miscellaneous/ConstantIterator.h"
|
||||
|
||||
|
@ -4,10 +4,10 @@
|
||||
#include "Templates/Meta.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
|
@ -3,12 +3,12 @@
|
||||
#include "CoreTypes.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "Templates/Noncopyable.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "Memory/MemoryOperator.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "CoreTypes.h"
|
||||
#include "Memory/Address.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
|
||||
@ -136,16 +136,16 @@ public:
|
||||
FORCEINLINE constexpr explicit TCountedIterator(U&& InValue, ptrdiff N) : Current(Forward<U>(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.GetBase()), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); }
|
||||
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).GetBase()), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); }
|
||||
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.GetBase(); Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; }
|
||||
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).GetBase(); Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; }
|
||||
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; }
|
||||
@ -182,9 +182,9 @@ public:
|
||||
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 Current; }
|
||||
NODISCARD FORCEINLINE constexpr ptrdiff Num() const { CheckThis(); return Length; }
|
||||
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:
|
||||
|
||||
|
@ -17,13 +17,11 @@ NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename T> using WithReference = T&;
|
||||
|
||||
template <typename I> struct TIteratorElementType { using Type = typename I::ElementType; };
|
||||
template <typename I> struct TIteratorElementType { using Type = typename I::ElementType; };
|
||||
template <typename T> struct TIteratorElementType<T*> { using Type = TRemoveCV<T>; };
|
||||
|
||||
template <typename T> struct TIteratorElementType<T*> { using Type = TRemoveCV<T>; };
|
||||
|
||||
template <typename I> struct TIteratorPointerType { using Type = void; };
|
||||
|
||||
template <typename T> struct TIteratorPointerType<T*> { using Type = T*; };
|
||||
template <typename I> struct TIteratorPointerType { using Type = void; };
|
||||
template <typename T> struct TIteratorPointerType<T*> { using Type = T*; };
|
||||
|
||||
template <typename I> requires (requires(I& Iter) { { Iter.operator->() } -> CPointer; })
|
||||
struct TIteratorPointerType<I> { using Type = decltype(DeclVal<I&>().operator->()); };
|
||||
@ -92,8 +90,13 @@ template <typename S, typename I>
|
||||
inline constexpr bool bDisableSizedSentinelFor = false;
|
||||
|
||||
template <typename S, typename I>
|
||||
concept CSizedSentinelFor = CSentinelFor<S, I> && CPartiallyOrdered<S, I> && !bDisableSizedSentinelFor<TRemoveCV<S>, TRemoveCV<I>>
|
||||
&& requires(const I& Iter, const S& Sentinel) { Sentinel - Iter; Iter - Sentinel; };
|
||||
concept CSizedSentinelFor = CSentinelFor<S, I> && CPartiallyOrdered<S, I>
|
||||
&& !bDisableSizedSentinelFor<TRemoveCV<S>, TRemoveCV<I>>
|
||||
&& requires(const I& Iter, const S& Sentinel)
|
||||
{
|
||||
{ Sentinel - Iter } -> CSameAs<ptrdiff>;
|
||||
{ Iter - Sentinel } -> CSameAs<ptrdiff>;
|
||||
};
|
||||
|
||||
template <typename I>
|
||||
concept CInputIterator = CInputOrOutputIterator<I> && CIndirectlyReadable<I>;
|
||||
@ -133,6 +136,96 @@ concept CContiguousIterator = CRandomAccessIterator<I> && CLValueReference<TIter
|
||||
|
||||
static_assert(CContiguousIterator<int32*>);
|
||||
|
||||
NAMESPACE_BEGIN(Iteration)
|
||||
|
||||
/** Increments given iterator 'Iter' by 'N' elements. */
|
||||
template <CInputIterator I>
|
||||
FORCEINLINE constexpr void Advance(I& Iter, ptrdiff N)
|
||||
{
|
||||
if constexpr (CRandomAccessIterator<I>)
|
||||
{
|
||||
Iter += N;
|
||||
}
|
||||
else if constexpr (CBidirectionalIterator<I>)
|
||||
{
|
||||
for (; N > 0; --N) ++Iter;
|
||||
for (; N < 0; ++N) --Iter;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkf(N >= 0, TEXT("The iterator must satisfy the CBidirectionalIterator in order to be decremented."));
|
||||
for (; N > 0; --N) ++Iter;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The number of hops from 'First' to 'Last'. */
|
||||
template <CInputIterator I, CSentinelFor<I> S>
|
||||
FORCEINLINE constexpr ptrdiff Distance(I First, S Last)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>)
|
||||
{
|
||||
return Last - First;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrdiff Result = 0;
|
||||
for (; First != Last; ++First) ++Result;
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The 'N'-th successor of iterator 'Iter'. */
|
||||
template <CInputIterator I>
|
||||
FORCEINLINE constexpr I Next(I Iter, TMakeUnsigned<ptrdiff> N = 1)
|
||||
{
|
||||
Iteration::Advance(Iter, N);
|
||||
return Iter;
|
||||
}
|
||||
|
||||
/** @return The 'N'-th predecessor of iterator 'Iter'. */
|
||||
template <CBidirectionalIterator I>
|
||||
FORCEINLINE constexpr I Prev(I Iter, TMakeUnsigned<ptrdiff> N = 1)
|
||||
{
|
||||
Iteration::Advance(Iter, -N);
|
||||
return Iter;
|
||||
}
|
||||
|
||||
NAMESPACE_END(Iteration)
|
||||
|
||||
template <CIndirectlyReadable J, CIndirectlyWritable<TIteratorReferenceType<J>> I>
|
||||
FORCEINLINE void IndirectlyCopy(I&& Iter, J&& Jter)
|
||||
{
|
||||
*Iter = *Jter;
|
||||
}
|
||||
|
||||
template <CIndirectlyReadable J, CIndirectlyWritable<TIteratorRValueReferenceType<J>> I>
|
||||
FORCEINLINE void IndirectlyMove(I&& Iter, J&& Jter)
|
||||
{
|
||||
*Iter = MoveTemp(*Jter);
|
||||
}
|
||||
|
||||
template <CIndirectlyReadable I, CIndirectlyReadable J> requires (CSwappable<TIteratorReferenceType<I>, TIteratorReferenceType<J>>)
|
||||
FORCEINLINE void IndirectlySwap(I&& Iter, J&& Jter)
|
||||
{
|
||||
Swap(*Iter, *Jter);
|
||||
}
|
||||
|
||||
template <typename I, typename J>
|
||||
concept CIndirectlyCopyable = requires(const I Iter, const J Jter) { IndirectlyCopy(Iter, Jter); };
|
||||
|
||||
template <typename I, typename J>
|
||||
concept CIndirectlyMovable = requires(const I Iter, const J Jter) { IndirectlyMove(Iter, Jter); };
|
||||
|
||||
template <typename I, typename J>
|
||||
concept CIndirectlySwappable = CIndirectlyReadable<I> && CIndirectlyReadable<J>
|
||||
&& requires(const I Iter, const J Jter)
|
||||
{
|
||||
IndirectlySwap(Iter, Iter);
|
||||
IndirectlySwap(Jter, Jter);
|
||||
IndirectlySwap(Iter, Jter);
|
||||
IndirectlySwap(Jter, Iter);
|
||||
};
|
||||
|
||||
/** A iterator adaptor for reverse-order traversal. */
|
||||
template <CBidirectionalIterator I>
|
||||
class TReverseIterator final
|
||||
@ -156,27 +249,27 @@ public:
|
||||
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.GetBase()) { }
|
||||
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).GetBase()) { }
|
||||
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.GetBase(); return *this; }
|
||||
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).GetBase(); return *this; }
|
||||
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.GetBase() == RHS.GetBase(); }
|
||||
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.GetBase() <=> LHS.GetBase(); }
|
||||
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 = GetBase(); return *--Temp; }
|
||||
NODISCARD FORCEINLINE constexpr TIteratorPointerType<IteratorType> operator->() const { IteratorType Temp = GetBase(); return ToAddress(--Temp); }
|
||||
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 GetBase()[-Index - 1]; }
|
||||
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; }
|
||||
@ -192,10 +285,10 @@ public:
|
||||
|
||||
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.GetBase() - LHS.GetBase(); }
|
||||
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 Current; }
|
||||
NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; }
|
||||
NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return MoveTemp(Current); }
|
||||
|
||||
private:
|
||||
|
||||
@ -231,27 +324,27 @@ public:
|
||||
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.GetBase()) { }
|
||||
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).GetBase()) { }
|
||||
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.GetBase(); return *this; }
|
||||
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).GetBase(); return *this; }
|
||||
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.GetBase() == RHS.GetBase(); }
|
||||
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.GetBase() <=> RHS.GetBase(); }
|
||||
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(*GetBase()); }
|
||||
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(GetBase()[Index]); }
|
||||
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; }
|
||||
@ -268,10 +361,10 @@ public:
|
||||
|
||||
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) { return LHS.GetBase() - RHS.GetBase(); }
|
||||
NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator& LHS, const TMoveIterator& RHS) { return LHS.Current - RHS.Current; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; }
|
||||
NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return Current; }
|
||||
NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; }
|
||||
NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return MoveTemp(Current); }
|
||||
|
||||
private:
|
||||
|
||||
@ -299,38 +392,38 @@ public:
|
||||
FORCEINLINE constexpr ~TMoveSentinel() = default;
|
||||
|
||||
template <typename T = SentinelType> requires (!CSameAs<TMoveSentinel, TRemoveCVRef<T>> && CConstructibleFrom<SentinelType, T>)
|
||||
FORCEINLINE constexpr explicit TMoveSentinel(T&& InValue) : Last(Forward<T>(InValue)) { }
|
||||
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) : Last(InValue.GetBase()) { }
|
||||
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) : Last(MoveTemp(InValue).GetBase()) { }
|
||||
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) { Last = InValue.GetBase(); return *this; }
|
||||
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) { Last = MoveTemp(InValue).GetBase(); return *this; }
|
||||
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 GetBase() == InValue.GetBase(); }
|
||||
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 GetBase() <=> InValue.GetBase(); }
|
||||
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.GetBase() - Iter.GetBase(); }
|
||||
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.GetBase() - Sentinel.GetBase(); }
|
||||
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 Last; }
|
||||
NODISCARD FORCEINLINE constexpr SentinelType GetBase() && { return Last; }
|
||||
NODISCARD FORCEINLINE constexpr const SentinelType& GetBase() const& { return Current; }
|
||||
NODISCARD FORCEINLINE constexpr SentinelType GetBase() && { return MoveTemp(Current); }
|
||||
|
||||
private:
|
||||
|
||||
SentinelType Last;
|
||||
SentinelType Current;
|
||||
|
||||
};
|
||||
|
||||
@ -377,16 +470,16 @@ public:
|
||||
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.GetBase()), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); }
|
||||
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).GetBase()), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); }
|
||||
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.GetBase(); Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; }
|
||||
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).GetBase(); Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; }
|
||||
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; }
|
||||
@ -409,7 +502,7 @@ public:
|
||||
FORCEINLINE constexpr TCountedIterator& operator++() { ++Current; --Length; CheckThis(); return *this; }
|
||||
FORCEINLINE constexpr TCountedIterator& operator--() requires (CBidirectionalIterator<IteratorType>) { --Current; ++Length; CheckThis(); return *this; }
|
||||
|
||||
FORCEINLINE constexpr decltype(auto) operator++(int) { --Length; CheckThis(); return Current++; }
|
||||
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; }
|
||||
|
||||
@ -427,9 +520,9 @@ public:
|
||||
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 Current; }
|
||||
NODISCARD FORCEINLINE constexpr ptrdiff Num() const { CheckThis(); return Length; }
|
||||
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:
|
||||
|
||||
@ -620,61 +713,9 @@ NODISCARD FORCEINLINE constexpr auto MakeInserter(C& Container, const typename C
|
||||
|
||||
NAMESPACE_BEGIN(Iteration)
|
||||
|
||||
/** Increments given iterator 'Iter' by 'N' elements. */
|
||||
template <CInputIterator I>
|
||||
FORCEINLINE constexpr void Advance(I& Iter, ptrdiff N)
|
||||
{
|
||||
if constexpr (CRandomAccessIterator<I>)
|
||||
{
|
||||
Iter += N;
|
||||
}
|
||||
else if constexpr (CBidirectionalIterator<I>)
|
||||
{
|
||||
for (; N > 0; --N) ++Iter;
|
||||
for (; N < 0; ++N) --Iter;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkf(N >= 0, TEXT("The iterator must satisfy the CBidirectionalIterator in order to be decremented."));
|
||||
for (; N > 0; --N) ++Iter;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The number of hops from 'First' to 'Last'. */
|
||||
template <CInputIterator I, CSentinelFor<I> S>
|
||||
FORCEINLINE constexpr ptrdiff Distance(I First, S Last)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>)
|
||||
{
|
||||
return Last - First;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrdiff Result = 0;
|
||||
for (; First != Last; ++First) ++Result;
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The 'N'-th successor of iterator 'Iter'. */
|
||||
template <CInputIterator I>
|
||||
FORCEINLINE constexpr I Next(I Iter, TMakeUnsigned<ptrdiff> N = 1)
|
||||
{
|
||||
Advance(Iter, N);
|
||||
return Iter;
|
||||
}
|
||||
|
||||
/** @return The 'N'-th predecessor of iterator 'Iter'. */
|
||||
template <CBidirectionalIterator I>
|
||||
FORCEINLINE constexpr I Prev(I Iter, TMakeUnsigned<ptrdiff> N = 1)
|
||||
{
|
||||
Advance(Iter, -N);
|
||||
return Iter;
|
||||
}
|
||||
|
||||
/** @return The iterator to the beginning of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.Begin() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr decltype(auto) Begin(T&& Container)
|
||||
FORCEINLINE constexpr auto Begin(T&& Container)
|
||||
{
|
||||
return Container.Begin();
|
||||
}
|
||||
@ -687,14 +728,14 @@ template <typename T, size_t N> FORCEINLINE constexpr const T* Begin(const T(&&
|
||||
|
||||
/** Overloads the Begin algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr decltype(auto) Begin(initializer_list<T> Container)
|
||||
FORCEINLINE constexpr auto Begin(initializer_list<T> Container)
|
||||
{
|
||||
return Container.begin();
|
||||
}
|
||||
|
||||
/** @return The iterator to the end of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.End() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr decltype(auto) End(T&& Container)
|
||||
FORCEINLINE constexpr auto End(T&& Container)
|
||||
{
|
||||
return Container.End();
|
||||
}
|
||||
@ -707,58 +748,58 @@ template <typename T, size_t N> FORCEINLINE constexpr const T* End(const T(&& Co
|
||||
|
||||
/** Overloads the End algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr decltype(auto) End(initializer_list<T> Container)
|
||||
FORCEINLINE constexpr auto End(initializer_list<T> Container)
|
||||
{
|
||||
return Container.end();
|
||||
}
|
||||
|
||||
/** @return The reverse iterator to the beginning of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.RBegin() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr decltype(auto) RBegin(T&& Container)
|
||||
FORCEINLINE constexpr auto RBegin(T&& Container)
|
||||
{
|
||||
return Container.RBegin();
|
||||
}
|
||||
|
||||
/** Overloads the RBegin algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) RBegin( T(& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) RBegin( T(&& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) RBegin(const T(& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) RBegin(const T(&& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto RBegin( T(& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto RBegin( T(&& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto RBegin(const T(& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto RBegin(const T(&& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
|
||||
/** Overloads the RBegin algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr decltype(auto) RBegin(initializer_list<T> Container)
|
||||
FORCEINLINE constexpr auto RBegin(initializer_list<T> Container)
|
||||
{
|
||||
return TReverseIterator(Container.end());
|
||||
}
|
||||
|
||||
/** @return The reverse iterator to the end of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.REnd() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr decltype(auto) REnd(T&& Container)
|
||||
FORCEINLINE constexpr auto REnd(T&& Container)
|
||||
{
|
||||
return Container.REnd();
|
||||
}
|
||||
|
||||
/** Overloads the REnd algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) REnd( T(& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) REnd( T(&& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) REnd(const T(& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr decltype(auto) REnd(const T(&& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto REnd( T(& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto REnd( T(&& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto REnd(const T(& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto REnd(const T(&& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
|
||||
/** Overloads the REnd algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr decltype(auto) REnd(initializer_list<T> Container)
|
||||
FORCEINLINE constexpr auto REnd(initializer_list<T> Container)
|
||||
{
|
||||
return TReverseIterator(Container.begin());
|
||||
}
|
||||
|
||||
NAMESPACE_END(Iteration)
|
||||
|
||||
#define ENABLE_RANGE_BASED_FOR_LOOP_SUPPORT public: \
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) begin() { return Begin(); } \
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) begin() const { return Begin(); } \
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) end() { return End(); } \
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) end() const { return End(); }
|
||||
#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)
|
440
Redcraft.Utility/Source/Public/Miscellaneous/Range.h
Normal file
440
Redcraft.Utility/Source/Public/Miscellaneous/Range.h
Normal file
@ -0,0 +1,440 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Memory/Address.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
// NOTE: The range that holds the object is called a container, and the range that only references the object is called a view.
|
||||
|
||||
template <typename R>
|
||||
inline constexpr bool bEnableBorrowedRange = false;
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
/** @return The iterator to the beginning of a container. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& requires(T&& Container) { { Container.Begin() } -> CInputOrOutputIterator; })
|
||||
NODISCARD FORCEINLINE constexpr auto Begin(T&& Container)
|
||||
{
|
||||
return Container.Begin();
|
||||
}
|
||||
|
||||
/** Overloads the Begin algorithm for arrays. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& CArray<TRemoveReference<T>>)
|
||||
NODISCARD FORCEINLINE constexpr auto Begin(T&& Container)
|
||||
{
|
||||
return Container + 0;
|
||||
}
|
||||
|
||||
/** Overloads the Begin algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
NODISCARD FORCEINLINE constexpr auto Begin(initializer_list<T>& Container)
|
||||
{
|
||||
return Container.begin();
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
template <typename R>
|
||||
using TRangeIteratorType = decltype(Range::Begin(DeclVal<R&>()));
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
/** @return The iterator to the end of a container. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& requires(T&& Container) { { Container.End() } -> CSentinelFor<TRangeIteratorType<T>>; })
|
||||
NODISCARD FORCEINLINE constexpr auto End(T&& Container)
|
||||
{
|
||||
return Container.End();
|
||||
}
|
||||
|
||||
/** Overloads the End algorithm for arrays. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& CBoundedArray<TRemoveReference<T>>)
|
||||
NODISCARD FORCEINLINE constexpr auto End(T&& Container)
|
||||
{
|
||||
return Container + TExtent<TRemoveReference<T>>;
|
||||
}
|
||||
|
||||
/** Overloads the End algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
NODISCARD FORCEINLINE constexpr auto End(initializer_list<T>& Container)
|
||||
{
|
||||
return Container.end();
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
template <typename R>
|
||||
using TRangeSentinelType = decltype(Range::End(DeclVal<R&>()));
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
/** @return The reverse iterator to the beginning of a container. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& requires(T&& Container) { { Container.RBegin() } -> CInputOrOutputIterator; })
|
||||
NODISCARD FORCEINLINE constexpr auto RBegin(T&& Container)
|
||||
{
|
||||
return Container.RBegin();
|
||||
}
|
||||
|
||||
/** Overloads the RBegin algorithm for synthesized. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& !requires(T&& Container) { { Container.RBegin() } -> CInputOrOutputIterator; }
|
||||
&& (CSameAs<TRangeIteratorType<T>, TRangeSentinelType<T>> && CBidirectionalIterator<TRangeIteratorType<T>>))
|
||||
NODISCARD FORCEINLINE constexpr auto RBegin(T&& Container)
|
||||
{
|
||||
return MakeReverseIterator(Range::End(Forward<T>(Container)));
|
||||
}
|
||||
|
||||
/** @return The reverse iterator to the end of a container. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& requires(T&& Container) { { Container.REnd() } -> CSentinelFor<decltype(Range::RBegin(DeclVal<T&>()))>; })
|
||||
NODISCARD FORCEINLINE constexpr auto REnd(T&& Container)
|
||||
{
|
||||
return Container.REnd();
|
||||
}
|
||||
|
||||
/** Overloads the REnd algorithm for synthesized. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& !requires(T&& Container) { { Container.REnd() } -> CSentinelFor<decltype(Range::RBegin(DeclVal<T&>()))>; }
|
||||
&& (CSameAs<TRangeIteratorType<T>, TRangeSentinelType<T>> && CBidirectionalIterator<TRangeIteratorType<T>>))
|
||||
NODISCARD FORCEINLINE constexpr auto REnd(T&& Container)
|
||||
{
|
||||
return MakeReverseIterator(Range::Begin(Forward<T>(Container)));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename R> struct TRangeElementType { using Type = typename R::ElementType; };
|
||||
template <typename T> struct TRangeElementType<T[ ]> { using Type = T; };
|
||||
template <typename T, size_t N> struct TRangeElementType<T[N]> { using Type = T; };
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <typename R>
|
||||
using TRangeElementType = typename NAMESPACE_PRIVATE::TRangeElementType<TRemoveCVRef<R>>::Type;
|
||||
|
||||
template <typename R>
|
||||
using TRangeReferenceType = TIteratorReferenceType<TRangeIteratorType<R>>;
|
||||
|
||||
template <typename R>
|
||||
using TRangeRValueReferenceType = TIteratorRValueReferenceType<TRangeIteratorType<R>>;
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
/** @return The pointer to the container element storage. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& requires(T&& Container) { { Container.GetData() } -> CSameAs<TAddPointer<TRangeReferenceType<T>>>; })
|
||||
NODISCARD FORCEINLINE constexpr auto GetData(T&& Container)
|
||||
{
|
||||
return Container.GetData();
|
||||
}
|
||||
|
||||
/** Overloads the GetData algorithm for synthesized. */
|
||||
template <typename T> requires ((CLValueReference<T> || bEnableBorrowedRange<TRemoveCVRef<T>>)
|
||||
&& !requires(T&& Container) { { Container.GetData() } -> CSameAs<TAddPointer<TRangeReferenceType<T>>>; }
|
||||
&& requires(T&& Container) { { Range::Begin(Forward<T>(Container)) } -> CContiguousIterator; })
|
||||
NODISCARD FORCEINLINE constexpr auto GetData(T&& Container)
|
||||
{
|
||||
return ToAddress(Range::Begin(Forward<T>(Container)));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
template <typename R>
|
||||
inline constexpr bool bDisableSizedRange = false;
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
/** @return The number of elements in the container. */
|
||||
template <typename T> requires (!bDisableSizedRange<TRemoveCVRef<T>>
|
||||
&& requires(T&& Container) { { Container.Num() } -> CSameAs<size_t>; })
|
||||
NODISCARD FORCEINLINE constexpr size_t Num(T&& Container)
|
||||
{
|
||||
return Container.Num();
|
||||
}
|
||||
|
||||
/** Overloads the Num algorithm for arrays. */
|
||||
template <typename T> requires (!bDisableSizedRange<TRemoveCVRef<T>>
|
||||
&& CBoundedArray<TRemoveReference<T>>)
|
||||
NODISCARD FORCEINLINE constexpr size_t Num(T&& Container)
|
||||
{
|
||||
return TExtent<TRemoveReference<T>>;
|
||||
}
|
||||
|
||||
/** Overloads the Num algorithm for synthesized. */
|
||||
template <typename T> requires (!bDisableSizedRange<TRemoveCVRef<T>>
|
||||
&& !requires(T&& Container) { { Container.Num() } -> CSameAs<size_t>; } && !CBoundedArray<TRemoveReference<T>>
|
||||
&& CSizedSentinelFor<TRangeIteratorType<T>, TRangeSentinelType<T>> && CForwardIterator<TRangeIteratorType<T>>)
|
||||
NODISCARD FORCEINLINE constexpr size_t Num(T&& Container)
|
||||
{
|
||||
return Range::End(Forward<T>(Container)) - Range::Begin(Forward<T>(Container));
|
||||
}
|
||||
|
||||
/** @return true if the container is empty, false otherwise. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.IsEmpty() } -> CBooleanTestable; })
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty(T&& Container)
|
||||
{
|
||||
return Container.IsEmpty();
|
||||
}
|
||||
|
||||
/** Overloads the IsEmpty algorithm for synthesized. */
|
||||
template <typename T> requires ((CBoundedArray<TRemoveReference<T>>
|
||||
|| requires(T&& Container) { { Container.Num() } -> CSameAs<size_t>; })
|
||||
&& !requires(T&& Container) { { Container.IsEmpty() } -> CBooleanTestable; })
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty(T&& Container)
|
||||
{
|
||||
return Range::Num(Forward<T>(Container)) == 0;
|
||||
}
|
||||
|
||||
/** Overloads the IsEmpty algorithm for synthesized. */
|
||||
template <typename T> requires (!CBoundedArray<TRemoveReference<T>>
|
||||
&& !requires(T&& Container) { { Container.Num() } -> CSameAs<size_t>; }
|
||||
&& !requires(T&& Container) { { Container.IsEmpty() } -> CBooleanTestable; }
|
||||
&& CForwardIterator<TRangeIteratorType<T>>)
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty(T&& Container)
|
||||
{
|
||||
return Range::End(Forward<T>(Container)) == Range::Begin(Forward<T>(Container));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
template <typename R>
|
||||
concept CRange =
|
||||
requires(R Range)
|
||||
{
|
||||
typename TRangeIteratorType<R>;
|
||||
typename TRangeSentinelType<R>;
|
||||
}
|
||||
&& CInputOrOutputIterator<TRangeIteratorType<R>>
|
||||
&& CSentinelFor<TRangeSentinelType<R>, TRangeIteratorType<R>>;
|
||||
|
||||
template <typename R>
|
||||
concept CBorrowedRange = CRange<R> && (CLValueReference<R> || bEnableBorrowedRange<TRemoveCVRef<R>>);
|
||||
|
||||
template <typename R>
|
||||
concept CSizedRange = CRange<R>
|
||||
&& requires(R Range)
|
||||
{
|
||||
{ Range::Num(Range) } -> CConvertibleTo<size_t>;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
concept CInputRange = CRange<R> && CInputIterator<TRangeIteratorType<R>>;
|
||||
|
||||
template <typename R, typename T>
|
||||
concept COutputRange = CRange<R> && COutputIterator<TRangeIteratorType<R>, T>;
|
||||
|
||||
template <typename R>
|
||||
concept CForwardRange = CInputRange<R> && CForwardIterator<TRangeIteratorType<R>>;
|
||||
|
||||
template <typename R>
|
||||
concept CBidirectionalRange = CForwardRange<R> && CBidirectionalIterator<TRangeIteratorType<R>>;
|
||||
|
||||
template <typename R>
|
||||
concept CRandomAccessRange = CBidirectionalRange<R> && CRandomAccessIterator<TRangeIteratorType<R>>;
|
||||
|
||||
template <typename R>
|
||||
concept CContiguousRange = CRandomAccessRange<R> && CContiguousIterator<TRangeIteratorType<R>>
|
||||
&& requires(R& Range)
|
||||
{
|
||||
{ Range::GetData(Range) } -> CSameAs<TAddPointer<TRangeReferenceType<R>>>;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
concept CCommonRange = CRange<R> && CSameAs<TRangeIteratorType<R>, TRangeSentinelType<R>>;
|
||||
|
||||
static_assert(CContiguousRange<int[8]>);
|
||||
static_assert( CCommonRange<int[8]>);
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
template <typename T> requires (CClass<T> && CSameAs<T, TRemoveCV<T>>)
|
||||
class TViewInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** @return The pointer to the underlying element storage. */
|
||||
NODISCARD FORCEINLINE constexpr auto Data() requires (CContiguousRange< T>) { return Range::GetData(static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr auto Data() const requires (CContiguousRange<const T>) { return Range::GetData(static_cast<const T&>(*this)); }
|
||||
|
||||
/** @return The reverse iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() requires (CRange< T>) { return Range::Begin(static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr auto End() requires (CRange< T>) { return Range::End (static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() const requires (CRange<const T>) { return Range::Begin(static_cast<const T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr auto End() const requires (CRange<const T>) { return Range::End (static_cast<const T&>(*this)); }
|
||||
|
||||
/** @return The reverse iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE constexpr auto RBegin() requires (CBidirectionalRange< T> && CCommonRange< T>) { return Range::RBegin(static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr auto REnd() requires (CBidirectionalRange< T> && CCommonRange< T>) { return Range::REnd (static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr auto RBegin() const requires (CBidirectionalRange<const T> && CCommonRange<const T>) { return Range::RBegin(static_cast<const T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr auto REnd() const requires (CBidirectionalRange<const T> && CCommonRange<const T>) { return Range::REnd (static_cast<const T&>(*this)); }
|
||||
|
||||
/** @return The number of elements in the container. */
|
||||
NODISCARD FORCEINLINE constexpr size_t Num() requires (CSizedRange< T>) { return Range::Num(static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr size_t Num() const requires (CSizedRange<const T>) { return Range::Num(static_cast<const T&>(*this)); }
|
||||
|
||||
/** @return true if the container is empty, false otherwise. */
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty() requires (CSizedRange< T> || CForwardRange< T>) { return Range::IsEmpty(static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty() const requires (CSizedRange<const T> || CForwardRange<const T>) { return Range::IsEmpty(static_cast<const T&>(*this)); }
|
||||
|
||||
/** @return true if the container is empty, false otherwise. */
|
||||
NODISCARD FORCEINLINE constexpr explicit operator bool() requires (CSizedRange< T> || CForwardRange< T>) { return !Range::IsEmpty(static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr explicit operator bool() const requires (CSizedRange<const T> || CForwardRange<const T>) { return !Range::IsEmpty(static_cast<const T&>(*this)); }
|
||||
|
||||
/** @return The reference to the requested element. */
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) operator[](size_t Index) requires (CRandomAccessRange< T>) { return Range::Begin(static_cast< T&>(*this))[Index]; }
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) operator[](size_t Index) const requires (CRandomAccessRange<const T>) { return Range::Begin(static_cast<const T&>(*this))[Index]; }
|
||||
|
||||
/** @return The reference to the first or last element. */
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) Front() requires (CForwardRange< T>) { return *Range::Begin(static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) Front() const requires (CForwardRange<const T>) { return *Range::Begin(static_cast<const T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) Back() requires (CBidirectionalRange< T> && CCommonRange< T>) { return *Range::RBegin(static_cast< T&>(*this)); }
|
||||
NODISCARD FORCEINLINE constexpr decltype(auto) Back() const requires (CBidirectionalRange<const T> && CCommonRange<const T>) { return *Range::RBegin(static_cast<const T&>(*this)); }
|
||||
|
||||
ENABLE_RANGE_BASED_FOR_LOOP_SUPPORT
|
||||
|
||||
private:
|
||||
|
||||
FORCEINLINE constexpr TViewInterface() = default;
|
||||
|
||||
FORCEINLINE constexpr TViewInterface(const TViewInterface&) = default;
|
||||
FORCEINLINE constexpr TViewInterface(TViewInterface&&) = default;
|
||||
FORCEINLINE constexpr TViewInterface& operator=(const TViewInterface&) = default;
|
||||
FORCEINLINE constexpr TViewInterface& operator=(TViewInterface&&) = default;
|
||||
|
||||
FORCEINLINE constexpr ~TViewInterface() = default;
|
||||
|
||||
friend T;
|
||||
};
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
template <typename R> requires (bEnableBorrowedRange<R>)
|
||||
inline constexpr bool bEnableBorrowedRange<Range::TViewInterface<R>> = true;
|
||||
|
||||
template <typename V>
|
||||
concept CView = CRange<V> && CMovable<V> && CDerivedFrom<V, Range::TViewInterface<TRemoveCVRef<V>>>;
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename T> struct TIsInitializerList : FFalse { };
|
||||
template <typename T> struct TIsInitializerList<initializer_list<T>> : FTrue { };
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <typename R>
|
||||
concept CViewableRange = CRange<R>
|
||||
&& ((CView<TRemoveCVRef<R>> && CConstructibleFrom<TRemoveCVRef<R>, R>)
|
||||
|| (!CView<TRemoveCVRef<R>> && (CLValueReference<R> || CMovable<TRemoveReference<R>>
|
||||
&& !NAMESPACE_PRIVATE::TIsInitializerList<TRemoveCVRef<R>>::Value)));
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
template <CObject T>
|
||||
class TEmptyView : public TViewInterface<TEmptyView<T>>
|
||||
{
|
||||
public:
|
||||
|
||||
using ElementType = T;
|
||||
using Reference = T&;
|
||||
using Iterator = T*;
|
||||
using Sentinel = T*;
|
||||
|
||||
using ReverseIterator = TReverseIterator<Iterator>;
|
||||
|
||||
FORCEINLINE constexpr TEmptyView() = default;
|
||||
|
||||
NODISCARD static FORCEINLINE constexpr Iterator Begin() { return nullptr; }
|
||||
NODISCARD static FORCEINLINE constexpr Sentinel End() { return nullptr; }
|
||||
NODISCARD static FORCEINLINE constexpr T* GetData() { return nullptr; }
|
||||
NODISCARD static FORCEINLINE constexpr size_t Num() { return 0; }
|
||||
NODISCARD static FORCEINLINE constexpr bool IsEmpty() { return true; }
|
||||
|
||||
};
|
||||
|
||||
static_assert(CContiguousRange<TEmptyView<int>>);
|
||||
static_assert( CCommonRange<TEmptyView<int>>);
|
||||
static_assert( CView<TEmptyView<int>>);
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
template <typename T>
|
||||
constexpr bool bEnableBorrowedRange<Range::TEmptyView<T>> = true;
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
template <CObject T> requires (CMoveConstructible<T>)
|
||||
class TSingleView : public TViewInterface<TSingleView<T>>
|
||||
{
|
||||
public:
|
||||
|
||||
using ElementType = T;
|
||||
|
||||
using Reference = T&;
|
||||
using ConstReference = const T&;
|
||||
|
||||
using Iterator = T*;
|
||||
using ConstIterator = const T*;
|
||||
|
||||
using Sentinel = T*;
|
||||
using ConstSentinel = const T*;
|
||||
|
||||
using ReverseIterator = TReverseIterator< Iterator>;
|
||||
using ConstReverseIterator = TReverseIterator<ConstIterator>;
|
||||
|
||||
FORCEINLINE constexpr TSingleView() requires (CDefaultConstructible<T>) = default;
|
||||
|
||||
FORCEINLINE constexpr explicit TSingleView(const T& InValue) requires (CCopyConstructible<T>) : Value(InValue) { }
|
||||
|
||||
FORCEINLINE constexpr explicit TSingleView(T&& InValue) : Value(MoveTemp(InValue)) { }
|
||||
|
||||
template <typename... Ts> requires (CConstructibleFrom<T, Ts...>)
|
||||
FORCEINLINE explicit TSingleView(FInPlace, Ts&&... Args) : Value(Forward<Ts>(Args)...) { }
|
||||
|
||||
FORCEINLINE constexpr Iterator Begin() { return GetData(); }
|
||||
FORCEINLINE constexpr ConstIterator Begin() const { return GetData(); }
|
||||
FORCEINLINE constexpr Sentinel End() { return GetData() + 1; }
|
||||
FORCEINLINE constexpr ConstSentinel End() const { return GetData() + 1; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr T* GetData() { return AddressOf(Value); }
|
||||
NODISCARD FORCEINLINE constexpr const T* GetData() const { return AddressOf(Value); }
|
||||
|
||||
NODISCARD static FORCEINLINE constexpr size_t Num() { return 1; }
|
||||
NODISCARD static FORCEINLINE constexpr bool IsEmpty() { return false; }
|
||||
|
||||
private:
|
||||
|
||||
NO_UNIQUE_ADDRESS T Value;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
TSingleView(T) -> TSingleView<T>;
|
||||
|
||||
static_assert(CContiguousRange<TSingleView<int>>);
|
||||
static_assert( CCommonRange<TSingleView<int>>);
|
||||
static_assert( CView<TSingleView<int>>);
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
template <CRange R, typename T> requires (CRange<TInvokeResult<T, R>>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator|(R&& Range, T&& View)
|
||||
{
|
||||
return Invoke(Forward<T>(View), Forward<R>(Range));
|
||||
}
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -6,10 +6,10 @@
|
||||
#include "String/StringView.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/Optional.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Templates/Noncopyable.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
|
@ -5,11 +5,11 @@
|
||||
#include "Memory/Allocator.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Containers/Iterator.h"
|
||||
#include "Containers/ArrayView.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Memory/MemoryOperator.h"
|
||||
#include "Miscellaneous/Iterator.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
#include "Miscellaneous/ConstantIterator.h"
|
||||
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/Container.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
template <typename T, T... Ints>
|
||||
struct TIntegerSequence
|
||||
struct TIntegerSequence
|
||||
{
|
||||
using ValueType = T;
|
||||
FORCEINLINE static constexpr size_t Num() { return sizeof...(Ints); }
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "Templates/Noncopyable.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Templates/ReferenceWrapper.h"
|
||||
|
Loading…
Reference in New Issue
Block a user