diff --git a/Redcraft.Utility/Source/Public/Range/MoveView.h b/Redcraft.Utility/Source/Public/Range/MoveView.h new file mode 100644 index 0000000..0f7a023 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Range/MoveView.h @@ -0,0 +1,112 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/TypeTraits.h" +#include "Templates/Utility.h" +#include "Iterator/Utility.h" +#include "Iterator/BasicIterator.h" +#include "Iterator/MoveIterator.h" +#include "Range/Utility.h" +#include "Range/Pipe.h" +#include "Range/View.h" +#include "Range/AllView.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +NAMESPACE_BEGIN(Range) + +/** + * A view adapter which dereferences to a rvalue reference. + * When based on an input view, the filter view satisfies at least an input view up to a random access view. + * When based on a common view, the counted iterator satisfies a common view. + */ +template requires (CView) +class TMoveView : public IBasicViewInterface> +{ +public: + + using FElementType = TRangeElement; + using FReference = TRangeRValueReference; + + FORCEINLINE constexpr TMoveView() requires (CDefaultConstructible) = default; + + FORCEINLINE constexpr explicit TMoveView(V InBase) : Base(MoveTemp(InBase)) { } + + NODISCARD FORCEINLINE constexpr auto Begin() { return MakeMoveIterator(Range::Begin(Base)); } + + NODISCARD FORCEINLINE constexpr auto End() + { + if constexpr (CCommonRange) + { + return MakeMoveIterator(Range::End(Base)); + } + else return MakeMoveSentinel(Range::End(Base)); + } + + NODISCARD FORCEINLINE constexpr auto Begin() const requires (CRange) { return MakeMoveIterator(Range::Begin(Base)); } + + NODISCARD FORCEINLINE constexpr auto End() const requires (CRange) + { + if constexpr (CCommonRange) + { + return MakeMoveIterator(Range::End(Base)); + } + else return MakeMoveSentinel(Range::End(Base)); + } + + NODISCARD FORCEINLINE constexpr size_t Num() requires (CSizedRange< V>) { return Range::Num(Base); } + NODISCARD FORCEINLINE constexpr size_t Num() const requires (CSizedRange) { return Range::Num(Base); } + + NODISCARD FORCEINLINE constexpr V GetBase() const& requires (CCopyConstructible) { return Base; } + NODISCARD FORCEINLINE constexpr V GetBase() && { return MoveTemp(Base); } + +private: + + NO_UNIQUE_ADDRESS V Base; + +}; + +template +TMoveView(R&&) -> TMoveView>; + +static_assert( CInputRange>>>>); +static_assert( CForwardRange>>>>); +static_assert(CBidirectionalRange>>>>); +static_assert( CRandomAccessRange>>>>); +static_assert( CRandomAccessRange>>>>); + +static_assert(CCommonRange>>>>); +static_assert( CView>>>>); + +NAMESPACE_END(Range) + +template +constexpr bool bEnableBorrowedRange> = bEnableBorrowedRange; + +NAMESPACE_BEGIN(Range) + +/** Creates A view adapter that dereferences to a rvalue reference. */ +template requires (requires { TMoveView(DeclVal()); }) +NODISCARD FORCEINLINE constexpr auto Move(R&& Base) +{ + return TMoveView(Forward(Base)); +} + +/** Creates A view adapter that dereferences to a rvalue reference. */ +NODISCARD FORCEINLINE constexpr auto Move() +{ + using FClosure = decltype([] requires (requires { Range::Move(DeclVal()); }) (R&& Base) + { + return Range::Move(Forward(Base)); + }); + + return TAdaptorClosure(); +} + +NAMESPACE_END(Range) + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Range/Range.h b/Redcraft.Utility/Source/Public/Range/Range.h index c15d296..8c2b29b 100644 --- a/Redcraft.Utility/Source/Public/Range/Range.h +++ b/Redcraft.Utility/Source/Public/Range/Range.h @@ -7,5 +7,6 @@ #include "Range/Factory.h" #include "Range/Pipe.h" #include "Range/AllView.h" +#include "Range/MoveView.h" #include "Range/FilterView.h" #include "Range/TransformView.h"