#pragma once #include "CoreTypes.h" #include "TypeTraits/TypeTraits.h" #include "Templates/Utility.h" #include "Iterators/Utility.h" #include "Iterators/BasicIterator.h" #include "Iterators/MoveIterator.h" #include "Ranges/Utility.h" #include "Ranges/Pipe.h" #include "Ranges/View.h" #include "Ranges/AllView.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_BEGIN(Ranges) /** * A view adapter which dereferences to a rvalue reference. * When based on an input view, the move view satisfies at least an input view up to a random access view. * When based on a common view, the move view satisfies a common view. */ template <CInputRange V> requires (CView<V>) class TMoveView : public IBasicViewInterface<TMoveView<V>> { public: using FElementType = TRangeElement<V>; using FReference = TRangeRValueReference<V>; FORCEINLINE constexpr TMoveView() requires (CDefaultConstructible<V>) = default; FORCEINLINE constexpr explicit TMoveView(V InBase) : Base(MoveTemp(InBase)) { } NODISCARD FORCEINLINE constexpr auto Begin() requires (!CSimpleView<V>) { return MakeMoveIterator(Ranges::Begin(Base)); } NODISCARD FORCEINLINE constexpr auto Begin() const requires (CRange<const V>) { return MakeMoveIterator(Ranges::Begin(Base)); } NODISCARD FORCEINLINE constexpr auto End() requires (!CSimpleView<V>) { if constexpr (CCommonRange<V>) { return MakeMoveIterator(Ranges::End(Base)); } else return MakeMoveSentinel(Ranges::End(Base)); } NODISCARD FORCEINLINE constexpr auto End() const requires (CRange<const V>) { if constexpr (CCommonRange<V>) { return MakeMoveIterator(Ranges::End(Base)); } else return MakeMoveSentinel(Ranges::End(Base)); } NODISCARD FORCEINLINE constexpr size_t Num() requires (CSizedRange< V>) { return Ranges::Num(Base); } NODISCARD FORCEINLINE constexpr size_t Num() const requires (CSizedRange<const V>) { return Ranges::Num(Base); } NODISCARD FORCEINLINE constexpr V GetBase() const& requires (CCopyConstructible<V>) { return Base; } NODISCARD FORCEINLINE constexpr V GetBase() && { return MoveTemp(Base); } private: NO_UNIQUE_ADDRESS V Base; }; template <typename R> TMoveView(R&&) -> TMoveView<TAllView<R>>; static_assert( CInputRange<TMoveView<TAllView<IRange< IInputIterator<int&>>>>>); static_assert( CForwardRange<TMoveView<TAllView<IRange< IForwardIterator<int&>>>>>); static_assert(CBidirectionalRange<TMoveView<TAllView<IRange<IBidirectionalIterator<int&>>>>>); static_assert( CRandomAccessRange<TMoveView<TAllView<IRange< IRandomAccessIterator<int&>>>>>); static_assert( CRandomAccessRange<TMoveView<TAllView<IRange< IContiguousIterator<int&>>>>>); static_assert(CCommonRange<TMoveView<TAllView<ICommonRange<IForwardIterator<int>>>>>); static_assert( CView<TMoveView<TAllView< IRange< IInputIterator<int>>>>>); NAMESPACE_END(Ranges) template <typename T> constexpr bool bEnableBorrowedRange<Ranges::TMoveView<T>> = bEnableBorrowedRange<T>; NAMESPACE_BEGIN(Ranges) /** Creates A view adapter that dereferences to a rvalue reference. */ template <CViewableRange R> requires (requires { TMoveView(DeclVal<R>()); }) NODISCARD FORCEINLINE constexpr auto Move(R&& Base) { return TMoveView(Forward<R>(Base)); } /** Creates A view adapter that dereferences to a rvalue reference. */ NODISCARD FORCEINLINE constexpr auto Move() { using FClosure = decltype([]<CViewableRange R> requires (requires { Ranges::Move(DeclVal<R>()); }) (R&& Base) { return Ranges::Move(Forward<R>(Base)); }); return TAdaptorClosure<FClosure>(); } NAMESPACE_END(Ranges) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END