158 lines
8.0 KiB
C++
158 lines
8.0 KiB
C++
#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() requires (CDefaultConstructible<I>) = 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 (CEqualityComparable<I, J>)
|
|
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 (CSizedSentinelFor<I, 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
|