feat(containers): add TFunctionalInputIterator and operations support
This commit is contained in:
parent
f521c2b5d5
commit
5909d20605
@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Templates/Invoke.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
|
#include "Templates/Noncopyable.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
#include "Miscellaneous/Compare.h"
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
@ -35,17 +37,17 @@ template <typename T>
|
|||||||
concept CDereferenceable = requires(T& A) { { *A } -> CReferenceable; };
|
concept CDereferenceable = requires(T& A) { { *A } -> CReferenceable; };
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
using TIteratorElementType = typename NAMESPACE_PRIVATE::TIteratorElementType<I>::Type;
|
using TIteratorElementType = typename NAMESPACE_PRIVATE::TIteratorElementType<TRemoveCVRef<I>>::Type;
|
||||||
|
|
||||||
template <CReferenceable I>
|
template <CReferenceable I>
|
||||||
using TIteratorReferenceType = decltype(*DeclVal<I&>());
|
using TIteratorReferenceType = decltype(*DeclVal<I&>());
|
||||||
|
|
||||||
template <CReferenceable T> requires (requires(T& Iter) { { MoveTemp(*Iter) } -> CReferenceable; })
|
template <CReferenceable I> requires (requires(I& Iter) { { MoveTemp(*Iter) } -> CReferenceable; })
|
||||||
using TIteratorRValueReferenceType = decltype(MoveTemp(*DeclVal<T&>()));
|
using TIteratorRValueReferenceType = decltype(MoveTemp(*DeclVal<I&>()));
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
concept CIndirectlyReadable =
|
concept CIndirectlyReadable =
|
||||||
requires(const I Iter)
|
requires(const TRemoveCVRef<I> Iter)
|
||||||
{
|
{
|
||||||
typename TIteratorElementType<I>;
|
typename TIteratorElementType<I>;
|
||||||
typename TIteratorReferenceType<I>;
|
typename TIteratorReferenceType<I>;
|
||||||
@ -59,7 +61,7 @@ concept CIndirectlyReadable =
|
|||||||
|
|
||||||
template <typename I, typename T>
|
template <typename I, typename T>
|
||||||
concept CIndirectlyWritable =
|
concept CIndirectlyWritable =
|
||||||
requires(I && Iter, T && A)
|
requires(I&& Iter, T&& A)
|
||||||
{
|
{
|
||||||
*Iter = Forward<T>(A);
|
*Iter = Forward<T>(A);
|
||||||
*Forward<I>(Iter) = Forward<T>(A);
|
*Forward<I>(Iter) = Forward<T>(A);
|
||||||
@ -68,7 +70,7 @@ concept CIndirectlyWritable =
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
concept CWeaklyIncrementable = CDefaultConstructible<I> && CMovable<I>
|
concept CWeaklyIncrementable = CMovable<I>
|
||||||
&& requires(I Iter) { { ++Iter } -> CSameAs<I&>; Iter++; };
|
&& requires(I Iter) { { ++Iter } -> CSameAs<I&>; Iter++; };
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
@ -180,7 +182,8 @@ public:
|
|||||||
|
|
||||||
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.GetBase() - LHS.GetBase(); }
|
||||||
|
|
||||||
NODISCARD FORCEINLINE constexpr IteratorType GetBase() const { return Current; }
|
NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; }
|
||||||
|
NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return Current; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -249,7 +252,8 @@ public:
|
|||||||
|
|
||||||
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.GetBase() - RHS.GetBase(); }
|
||||||
|
|
||||||
NODISCARD FORCEINLINE constexpr IteratorType GetBase() const { return Current; }
|
NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; }
|
||||||
|
NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return Current; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -297,7 +301,8 @@ public:
|
|||||||
template <CInputIterator I> requires (CSizedSentinelFor<SentinelType, I>)
|
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.GetBase() - Sentinel.GetBase(); }
|
||||||
|
|
||||||
NODISCARD FORCEINLINE constexpr SentinelType GetBase() const { return Last; }
|
NODISCARD FORCEINLINE constexpr const SentinelType& GetBase() const& { return Last; }
|
||||||
|
NODISCARD FORCEINLINE constexpr SentinelType GetBase() && { return Last; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -391,7 +396,8 @@ public:
|
|||||||
NODISCARD FORCEINLINE constexpr explicit operator ElementType*() requires (CContiguousIterator<IteratorType> && !CConst<ElementType>) { CheckThis(); return Current; }
|
NODISCARD FORCEINLINE constexpr explicit operator ElementType*() requires (CContiguousIterator<IteratorType> && !CConst<ElementType>) { CheckThis(); return Current; }
|
||||||
NODISCARD FORCEINLINE constexpr explicit operator const ElementType*() const requires (CContiguousIterator<IteratorType>) { CheckThis(); return Current; }
|
NODISCARD FORCEINLINE constexpr explicit operator const ElementType*() const requires (CContiguousIterator<IteratorType>) { CheckThis(); return Current; }
|
||||||
|
|
||||||
NODISCARD FORCEINLINE constexpr IteratorType GetBase() const { CheckThis(); return Current; }
|
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 ptrdiff Num() const { CheckThis(); return Length; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -417,6 +423,57 @@ private:
|
|||||||
static_assert(CContiguousIterator<TCountedIterator<int32*>>);
|
static_assert(CContiguousIterator<TCountedIterator<int32*>>);
|
||||||
static_assert(CSizedSentinelFor<FDefaultSentinel, TCountedIterator<int32*>>);
|
static_assert(CSizedSentinelFor<FDefaultSentinel, TCountedIterator<int32*>>);
|
||||||
|
|
||||||
|
template <typename I>
|
||||||
|
TCountedIterator(I, ptrdiff) -> TCountedIterator<I>;
|
||||||
|
|
||||||
|
template <CInvocable F, CInvocable G> requires (CReferenceable<TInvokeResult<F>> && CBooleanTestable<TInvokeResult<G>> && CMovable<F> && CMovable<G>)
|
||||||
|
class TFunctionalInputIterator final : private FNoncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using Inputer = F;
|
||||||
|
using Sentinel = G;
|
||||||
|
|
||||||
|
using ElementType = TRemoveReference<TInvokeResult<Inputer>>;
|
||||||
|
|
||||||
|
FORCEINLINE constexpr TFunctionalInputIterator() = default;
|
||||||
|
|
||||||
|
FORCEINLINE constexpr TFunctionalInputIterator(TFunctionalInputIterator&&) = default;
|
||||||
|
FORCEINLINE constexpr TFunctionalInputIterator& operator=(TFunctionalInputIterator&&) = default;
|
||||||
|
|
||||||
|
template <typename T, typename U> requires (CConvertibleTo<T, Inputer> && CConvertibleTo<U, Sentinel>)
|
||||||
|
FORCEINLINE constexpr TFunctionalInputIterator(T&& InInputer, U&& InSentinel) : InputerStorage(Forward<T>(InInputer)), SentinelStorage(Forward<U>(InSentinel)), bIsConsumed(false) { }
|
||||||
|
|
||||||
|
NODISCARD FORCEINLINE constexpr bool operator==(FDefaultSentinel) const& { return Invoke(SentinelStorage); }
|
||||||
|
|
||||||
|
NODISCARD FORCEINLINE constexpr decltype(auto) operator*() const { checkf(!bIsConsumed, TEXT("The element are consumed. Please check IsConsumed().")); bIsConsumed = true; return Invoke(InputerStorage); }
|
||||||
|
NODISCARD FORCEINLINE constexpr void operator->() const = delete;
|
||||||
|
|
||||||
|
FORCEINLINE constexpr TFunctionalInputIterator& operator++() { if (!bIsConsumed) Invoke(InputerStorage); bIsConsumed = false; return *this; }
|
||||||
|
|
||||||
|
FORCEINLINE constexpr void operator++(int) { if (!bIsConsumed) Invoke(InputerStorage); bIsConsumed = false; }
|
||||||
|
|
||||||
|
NODISCARD FORCEINLINE constexpr const Inputer& GetInputer() const& { return InputerStorage; }
|
||||||
|
NODISCARD FORCEINLINE constexpr Inputer GetInputer() && { return InputerStorage; }
|
||||||
|
|
||||||
|
NODISCARD FORCEINLINE constexpr const Sentinel& GetSentinel() const& { return SentinelStorage; }
|
||||||
|
NODISCARD FORCEINLINE constexpr Sentinel GetSentinel() && { return SentinelStorage; }
|
||||||
|
|
||||||
|
NODISCARD FORCEINLINE constexpr bool IsConsumed() const { return bIsConsumed; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Inputer InputerStorage;
|
||||||
|
Sentinel SentinelStorage;
|
||||||
|
mutable bool bIsConsumed;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(CInputIterator<TFunctionalInputIterator<int32(*)(), bool(*)()>>);
|
||||||
|
|
||||||
|
template <typename F, typename G>
|
||||||
|
TFunctionalInputIterator(F, G) -> TFunctionalInputIterator<F, G>;
|
||||||
|
|
||||||
NAMESPACE_BEGIN(Iteration)
|
NAMESPACE_BEGIN(Iteration)
|
||||||
|
|
||||||
/** Increments given iterator 'Iter' by 'N' elements. */
|
/** Increments given iterator 'Iter' by 'N' elements. */
|
||||||
|
Loading…
Reference in New Issue
Block a user