Compare commits
5 Commits
85199119b3
...
566052c8c2
Author | SHA1 | Date | |
---|---|---|---|
566052c8c2 | |||
a0250ebaf8 | |||
f88cf7ef3e | |||
e6d525f2c3 | |||
dd3a366c14 |
226
Redcraft.Utility/Source/Private/Testing/IteratorTesting.cpp
Normal file
226
Redcraft.Utility/Source/Private/Testing/IteratorTesting.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
#include "Testing/IteratorTesting.h"
|
||||
|
||||
#include "Iterator/Iterator.h"
|
||||
#include "Containers/List.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
NAMESPACE_BEGIN(Testing)
|
||||
|
||||
void TestIterator()
|
||||
{
|
||||
TestMoveIterator();
|
||||
TestReverseIterator();
|
||||
TestCountedIterator();
|
||||
TestInsertIterator();
|
||||
}
|
||||
|
||||
void TestMoveIterator()
|
||||
{
|
||||
{
|
||||
struct FTracker
|
||||
{
|
||||
FTracker() = default;
|
||||
FTracker(const FTracker&) { always_check_no_entry(); }
|
||||
FTracker(FTracker&&) = default;
|
||||
~FTracker() = default;
|
||||
FTracker& operator=(const FTracker&) { always_check_no_entry(); }
|
||||
FTracker& operator=(FTracker&&) = default;
|
||||
};
|
||||
|
||||
FTracker Arr[2];
|
||||
|
||||
auto First = MakeMoveIterator(&Arr[0]);
|
||||
auto Last = MakeMoveIterator(&Arr[2]);
|
||||
|
||||
FTracker Temp(*First++);
|
||||
|
||||
Temp = *First++;
|
||||
|
||||
always_check(First == Last);
|
||||
}
|
||||
|
||||
{
|
||||
int Arr[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
auto First = MakeMoveIterator(&Arr[0]);
|
||||
auto Last = MakeMoveIterator(&Arr[8]);
|
||||
|
||||
auto ConstFirst = MakeMoveIterator(&AsConst(Arr)[0]);
|
||||
auto ConstLast = MakeMoveIterator(&AsConst(Arr)[8]);
|
||||
|
||||
always_check(First == ConstFirst);
|
||||
always_check(Last == ConstLast );
|
||||
|
||||
always_check(ConstLast - First == 8);
|
||||
|
||||
auto Iter = ConstFirst;
|
||||
auto Jter = ConstLast;
|
||||
|
||||
++Iter;
|
||||
--Jter;
|
||||
|
||||
always_check(*Iter++ == 1);
|
||||
always_check(*Jter-- == 7);
|
||||
|
||||
Iter += 2;
|
||||
Jter -= 2;
|
||||
|
||||
always_check(Iter[-1] == 3);
|
||||
always_check(Jter[ 1] == 5);
|
||||
|
||||
Iter = Iter - 2;
|
||||
Jter = Jter + 2;
|
||||
|
||||
always_check(*Iter == 2);
|
||||
always_check(*Jter == 6);
|
||||
|
||||
Iter = 2 + Iter;
|
||||
Jter = Jter - 2;
|
||||
|
||||
always_check(Iter - Jter == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void TestReverseIterator()
|
||||
{
|
||||
int Arr[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
|
||||
auto First = MakeReverseIterator(&Arr[8]);
|
||||
auto Last = MakeReverseIterator(&Arr[0]);
|
||||
|
||||
auto ConstFirst = MakeReverseIterator(&AsConst(Arr)[8]);
|
||||
auto ConstLast = MakeReverseIterator(&AsConst(Arr)[0]);
|
||||
|
||||
always_check(First == ConstFirst);
|
||||
always_check(Last == ConstLast );
|
||||
|
||||
always_check(ConstLast - First == 8);
|
||||
|
||||
auto Iter = ConstFirst;
|
||||
auto Jter = ConstLast;
|
||||
|
||||
++Iter;
|
||||
--Jter;
|
||||
|
||||
always_check(*Iter++ == 1);
|
||||
always_check(*Jter-- == 7);
|
||||
|
||||
Iter += 2;
|
||||
Jter -= 2;
|
||||
|
||||
always_check(Iter[-1] == 3);
|
||||
always_check(Jter[ 1] == 5);
|
||||
|
||||
Iter = Iter - 2;
|
||||
Jter = Jter + 2;
|
||||
|
||||
always_check(*Iter == 2);
|
||||
always_check(*Jter == 6);
|
||||
|
||||
Iter = 2 + Iter;
|
||||
Jter = Jter - 2;
|
||||
|
||||
always_check(Iter - Jter == 0);
|
||||
}
|
||||
|
||||
void TestCountedIterator()
|
||||
{
|
||||
int Arr[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
|
||||
auto First = MakeCountedIterator(&Arr[0], 8);
|
||||
auto Last = First + 8;
|
||||
|
||||
auto ConstFirst = MakeCountedIterator(&AsConst(Arr)[0], 8);
|
||||
auto ConstLast = ConstFirst + 8;
|
||||
|
||||
always_check(First == ConstFirst);
|
||||
always_check(Last == ConstLast );
|
||||
|
||||
always_check(ConstLast - First == 8);
|
||||
|
||||
always_check(Last == DefaultSentinel);
|
||||
always_check(DefaultSentinel == Last);
|
||||
|
||||
always_check(DefaultSentinel - First == 8);
|
||||
always_check(First - DefaultSentinel == -8);
|
||||
|
||||
always_check(First == ConstFirst);
|
||||
always_check(Last == ConstLast );
|
||||
|
||||
always_check(Last - First == 8);
|
||||
|
||||
auto Iter = ConstFirst;
|
||||
auto Jter = ConstLast;
|
||||
|
||||
++Iter;
|
||||
--Jter;
|
||||
|
||||
always_check(*Iter++ == 1);
|
||||
always_check(*Jter-- == 7);
|
||||
|
||||
Iter += 2;
|
||||
Jter -= 2;
|
||||
|
||||
always_check(Iter[-1] == 3);
|
||||
always_check(Jter[ 1] == 5);
|
||||
|
||||
Iter = Iter - 2;
|
||||
Jter = Jter + 2;
|
||||
|
||||
always_check(*Iter == 2);
|
||||
always_check(*Jter == 6);
|
||||
|
||||
Iter = 2 + Iter;
|
||||
Jter = Jter - 2;
|
||||
|
||||
always_check(Iter - Jter == 0);
|
||||
}
|
||||
|
||||
void TestInsertIterator()
|
||||
{
|
||||
{
|
||||
TList<int> List = { 1, 2, 3 };
|
||||
|
||||
auto Iter = MakeFrontInserter(List);
|
||||
|
||||
*Iter++ = 1;
|
||||
*Iter++ = 2;
|
||||
*Iter++ = 3;
|
||||
|
||||
always_check(List == TList<int>({ 3, 2, 1, 1, 2, 3 }));
|
||||
}
|
||||
|
||||
{
|
||||
TList<int> List = { 1, 2, 3 };
|
||||
|
||||
auto Iter = MakeBackInserter(List);
|
||||
|
||||
*Iter++ = 1;
|
||||
*Iter++ = 2;
|
||||
*Iter++ = 3;
|
||||
|
||||
always_check(List == TList<int>({ 1, 2, 3, 1, 2, 3 }));
|
||||
}
|
||||
|
||||
{
|
||||
TList<int> List = { 1, 2, 3 };
|
||||
|
||||
auto Iter = MakeInserter(List, ++++List.Begin());
|
||||
|
||||
*Iter++ = 1;
|
||||
*Iter++ = 2;
|
||||
*Iter++ = 3;
|
||||
|
||||
always_check(List == TList<int>({ 1, 2, 1, 2, 3, 3 }));
|
||||
}
|
||||
}
|
||||
|
||||
NAMESPACE_END(Testing)
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -67,14 +67,12 @@ public:
|
||||
}
|
||||
|
||||
template <CInputOrOutputIterator J> requires (CCommonType<I, J>)
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Length == RHS.Length; }
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Num() == RHS.Num(); }
|
||||
|
||||
template <CInputOrOutputIterator J> requires (CCommonType<I, J>)
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Length <=> RHS.Length; }
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Num() <=> RHS.Num(); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(FDefaultSentinel) const& { return Length == static_cast<ptrdiff>(0); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(FDefaultSentinel) const& { return static_cast<ptrdiff>(0) <=> Length; }
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(FDefaultSentinel) const& { return Num() == static_cast<ptrdiff>(0); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr TIteratorReference<I> operator*() { CheckThis(true); return *GetBase(); }
|
||||
NODISCARD FORCEINLINE constexpr TIteratorReference<I> operator*() const requires (CDereferenceable<const I>) { CheckThis(true); return *GetBase(); }
|
||||
@ -99,7 +97,7 @@ public:
|
||||
NODISCARD friend FORCEINLINE constexpr TCountedIterator operator+(ptrdiff Offset, TCountedIterator Iter) requires (CRandomAccessIterator<I>) { return Iter + Offset; }
|
||||
|
||||
template <CInputOrOutputIterator J> requires (CCommonType<I, J>)
|
||||
NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { LHS.CheckThis(); RHS.CheckThis(); return LHS.Length - RHS.Length; }
|
||||
NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return RHS.Num() - LHS.Num(); }
|
||||
|
||||
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(); }
|
||||
@ -123,9 +121,6 @@ private:
|
||||
checkf(!(bExceptEnd && Length == static_cast<ptrdiff>(0)), TEXT("Read access violation. Please check Num()."));
|
||||
}
|
||||
|
||||
template <CInputOrOutputIterator J>
|
||||
friend class TCountedIterator;
|
||||
|
||||
};
|
||||
|
||||
static_assert( CInputIterator<TCountedIterator< IInputIterator<int&>>>);
|
||||
|
@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Iterator/Utility.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Templates/Noncopyable.h"
|
||||
#include "Iterator/Utility.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/Noncopyable.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
@ -142,7 +144,7 @@ NODISCARD FORCEINLINE constexpr auto MakeBackInserter(C& Container)
|
||||
template <typename C>
|
||||
NODISCARD FORCEINLINE constexpr auto MakeInserter(C& Container, const typename C::FConstIterator& InIter)
|
||||
{
|
||||
return NAMESPACE_PRIVATE::TInsertIterator([&Container, Iter = InIter]<typename T>(T&& A) mutable { Iter = Container.Insert(Iter, Forward<T>(A)); });
|
||||
return NAMESPACE_PRIVATE::TInsertIterator([&Container, Iter = InIter]<typename T>(T&& A) mutable { Iter = Container.Insert(Iter, Forward<T>(A)); ++Iter; });
|
||||
}
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
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 friend FORCEINLINE constexpr TCompareThreeWayResult<I, J> operator<=>(const TMoveIterator& LHS, const TMoveIterator<J>& RHS) { return LHS.GetBase() <=> RHS.GetBase(); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr TIteratorRValueReference<I> operator*() const { return MoveTemp(*GetBase()); }
|
||||
|
||||
|
@ -63,8 +63,8 @@ public:
|
||||
FORCEINLINE constexpr TReverseIterator& operator+=(ptrdiff Offset) requires (CRandomAccessIterator<I>) { Current -= Offset; return *this; }
|
||||
FORCEINLINE constexpr TReverseIterator& operator-=(ptrdiff Offset) requires (CRandomAccessIterator<I>) { Current += Offset; return *this; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TReverseIterator Temp = *this; Temp -= Offset; return Temp; }
|
||||
NODISCARD FORCEINLINE constexpr TReverseIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TReverseIterator Temp = *this; Temp += Offset; return Temp; }
|
||||
NODISCARD FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TReverseIterator Temp = *this; Temp += Offset; return Temp; }
|
||||
NODISCARD FORCEINLINE constexpr TReverseIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator<I>) { TReverseIterator Temp = *this; Temp -= Offset; return Temp; }
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr TReverseIterator operator+(ptrdiff Offset, const TReverseIterator& Iter) requires (CRandomAccessIterator<I>) { return Iter + Offset; }
|
||||
|
||||
|
@ -34,9 +34,17 @@ public:
|
||||
|
||||
FORCEINLINE constexpr explicit TMoveView(V InBase) : Base(MoveTemp(InBase)) { }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() { return MakeMoveIterator(Range::Begin(Base)); }
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() requires (!CSimpleView<V>)
|
||||
{
|
||||
return MakeMoveIterator(Range::Begin(Base));
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto End()
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() const requires (CRange<const V>)
|
||||
{
|
||||
return MakeMoveIterator(Range::Begin(Base));
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto End() requires (!CSimpleView<V>)
|
||||
{
|
||||
if constexpr (CCommonRange<V>)
|
||||
{
|
||||
@ -45,9 +53,7 @@ public:
|
||||
else return MakeMoveSentinel(Range::End(Base));
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() const requires (CRange<const V>) { return MakeMoveIterator(Range::Begin(Base)); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto End() const requires (CRange<const V>)
|
||||
NODISCARD FORCEINLINE constexpr auto End() const requires (CRange<const V>)
|
||||
{
|
||||
if constexpr (CCommonRange<V>)
|
||||
{
|
||||
|
@ -11,3 +11,4 @@
|
||||
#include "Range/FilterView.h"
|
||||
#include "Range/TransformView.h"
|
||||
#include "Range/TakeView.h"
|
||||
#include "Range/TakeWhileView.h"
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
|
||||
FORCEINLINE constexpr TTakeView(V InBase, size_t InCount) : Base(MoveTemp(InBase)), Count(InCount) { }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto Begin()
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() requires (!CSimpleView<V>)
|
||||
{
|
||||
if constexpr (CSizedRange<V>)
|
||||
{
|
||||
@ -62,7 +62,7 @@ public:
|
||||
else return MakeCountedIterator(Range::Begin(Base), Count);
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto End()
|
||||
NODISCARD FORCEINLINE constexpr auto End() requires (!CSimpleView<V>)
|
||||
{
|
||||
if constexpr (CSizedRange<V>)
|
||||
{
|
||||
|
149
Redcraft.Utility/Source/Public/Range/TakeWhileView.h
Normal file
149
Redcraft.Utility/Source/Public/Range/TakeWhileView.h
Normal file
@ -0,0 +1,149 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Iterator/Utility.h"
|
||||
#include "Iterator/BasicIterator.h"
|
||||
#include "Iterator/CountedIterator.h"
|
||||
#include "Numeric/Math.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 that includes elements that satisfy the predicate from the beginning of the range.
|
||||
* When based on an input view, the take while view satisfies at least an input view up to a contiguous view.
|
||||
* When based on a forward and output view, the take while view satisfies an output view.
|
||||
*/
|
||||
template <CInputRange V, CPredicate<TRangeReference<V>> Pred> requires (CView<V> && CObject<Pred> && CMoveConstructible<Pred>)
|
||||
class TTakeWhileView : public IBasicViewInterface<TTakeWhileView<V, Pred>>
|
||||
{
|
||||
private:
|
||||
|
||||
template <bool bConst> class FSentinelImpl;
|
||||
|
||||
public:
|
||||
|
||||
using FElementType = TRangeElement<V>;
|
||||
using FReference = TRangeReference<V>;
|
||||
|
||||
FORCEINLINE constexpr TTakeWhileView() requires (CDefaultConstructible<V>&& CDefaultConstructible<Pred>) = default;
|
||||
|
||||
FORCEINLINE constexpr explicit TTakeWhileView(V InBase, Pred InPredicate) : Base(MoveTemp(InBase)), Predicate(MoveTemp(InPredicate)) { }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() requires (!CSimpleView<V>)
|
||||
{
|
||||
return Range::Begin(Base);
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto Begin() const requires (CRange<const V> && CPredicate<const Pred&, TRangeReference<const V>>)
|
||||
{
|
||||
return Range::Begin(Base);
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto End() requires (!CSimpleView<V>)
|
||||
{
|
||||
return FSentinelImpl<false>(Range::End(Base), AddressOf(Predicate));
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto End() const requires (CRange<const V> && CPredicate<const Pred&, TRangeReference<const V>>)
|
||||
{
|
||||
return FSentinelImpl<true>(Range::End(Base), AddressOf(Predicate));
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr V GetBase() const& requires (CCopyConstructible<V>) { return Base; }
|
||||
NODISCARD FORCEINLINE constexpr V GetBase() && { return MoveTemp(Base); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr const Pred& GetPredicate() const { return Predicate; }
|
||||
|
||||
private:
|
||||
|
||||
NO_UNIQUE_ADDRESS V Base;
|
||||
|
||||
NO_UNIQUE_ADDRESS Pred Predicate;
|
||||
|
||||
template <bool bConst>
|
||||
class FSentinelImpl final
|
||||
{
|
||||
private:
|
||||
|
||||
using FBase = TConditional<bConst, const V, V>;
|
||||
using FPred = TConditional<bConst, const Pred, Pred>;
|
||||
|
||||
public:
|
||||
|
||||
FORCEINLINE constexpr FSentinelImpl() = default;
|
||||
|
||||
FORCEINLINE constexpr FSentinelImpl(FSentinelImpl<!bConst> Sentinel) requires (bConst && CConvertibleTo<TRangeSentinel<V>, TRangeSentinel<FBase>>)
|
||||
: Current(Sentinel.Current), Predicate(Sentinel.Predicate)
|
||||
{ }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(const TRangeIterator<FBase>& InValue) const&
|
||||
{
|
||||
return InValue == Current || !InvokeResult<bool>(*Predicate, *InValue);
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr TRangeSentinel<FBase> GetBase() const { return Current; }
|
||||
|
||||
private:
|
||||
|
||||
NO_UNIQUE_ADDRESS TRangeSentinel<FBase> Current;
|
||||
|
||||
FPred* Predicate;
|
||||
|
||||
FORCEINLINE constexpr FSentinelImpl(TRangeSentinel<FBase> InCurrent, FPred* InPredicate) : Current(InCurrent), Predicate(InPredicate) { }
|
||||
|
||||
friend TTakeWhileView;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <typename R, typename Pred>
|
||||
TTakeWhileView(R&&, Pred) -> TTakeWhileView<TAllView<R>, Pred>;
|
||||
|
||||
static_assert( CInputRange<TTakeWhileView<TAllView<IRange< IInputIterator<int&>>>, bool(*)(int)>>);
|
||||
static_assert( CForwardRange<TTakeWhileView<TAllView<IRange< IForwardIterator<int&>>>, bool(*)(int)>>);
|
||||
static_assert(CBidirectionalRange<TTakeWhileView<TAllView<IRange<IBidirectionalIterator<int&>>>, bool(*)(int)>>);
|
||||
static_assert( CRandomAccessRange<TTakeWhileView<TAllView<IRange< IRandomAccessIterator<int&>>>, bool(*)(int)>>);
|
||||
static_assert( CContiguousRange<TTakeWhileView<TAllView<IRange< IContiguousIterator<int&>>>, bool(*)(int)>>);
|
||||
|
||||
static_assert(CView<TTakeWhileView<TAllView<IRange<IInputIterator<int>>>, bool(*)(int)>>);
|
||||
|
||||
static_assert(COutputRange<TTakeWhileView<TAllView<IRange<IForwardIterator<int&>>>, bool(*)(int)>, int>);
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
/** Creates A view adapter that includes elements that satisfy the predicate from the beginning of the range. */
|
||||
template <CViewableRange R, typename Pred> requires (requires { TTakeWhileView(DeclVal<R>(), DeclVal<Pred>()); })
|
||||
NODISCARD FORCEINLINE constexpr auto TakeWhile(R&& Base, Pred&& Predicate)
|
||||
{
|
||||
return TTakeWhileView(Forward<R>(Base), Forward<Pred>(Predicate));
|
||||
}
|
||||
|
||||
/** Creates A view adapter that includes elements that satisfy the predicate from the beginning of the range. */
|
||||
template <typename Pred>
|
||||
NODISCARD FORCEINLINE constexpr auto TakeWhile(Pred&& Predicate)
|
||||
{
|
||||
using FClosure = decltype([]<CViewableRange R, typename T> requires (requires { Range::TakeWhile(DeclVal<R>(), DeclVal<T>()); }) (R&& Base, T&& Predicate)
|
||||
{
|
||||
return Range::TakeWhile(Forward<R>(Base), Forward<T>(Predicate));
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<Pred>>(Forward<Pred>(Predicate));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -175,7 +175,7 @@ private:
|
||||
NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const FSentinelImpl& LHS, const FIteratorImpl<bConst>& RHS)
|
||||
requires CSizedSentinelFor<TRangeSentinel<FBase>, TRangeIterator<FBase>>
|
||||
{
|
||||
return RHS.GetBase() - LHS.GetBase();
|
||||
return LHS.GetBase() - RHS.GetBase();
|
||||
}
|
||||
|
||||
NODISCARD FORCEINLINE constexpr TRangeSentinel<FBase> GetBase() const { return Current; }
|
||||
|
@ -98,6 +98,12 @@ concept CViewableRange = CRange<R>
|
||||
|| (!CView<TRemoveCVRef<R>> && (CLValueReference<R> || (CMovable<TRemoveReference<R>>
|
||||
&& !NAMESPACE_PRIVATE::TIsInitializerList<TRemoveCVRef<R>>::Value))));
|
||||
|
||||
/** A concept specifies that a view uses the same iterator and sentinel type for both const and non-const views. */
|
||||
template <typename V>
|
||||
concept CSimpleView = CView<V> && CRange<const V>
|
||||
&& CSameAs<TRangeIterator<V>, TRangeIterator<const V>>
|
||||
&& CSameAs<TRangeSentinel<V>, TRangeSentinel<const V>>;
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
/** A simple view that combines an iterator-sentinel pair into a view. */
|
||||
|
21
Redcraft.Utility/Source/Public/Testing/IteratorTesting.h
Normal file
21
Redcraft.Utility/Source/Public/Testing/IteratorTesting.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
NAMESPACE_BEGIN(Testing)
|
||||
|
||||
REDCRAFTUTILITY_API void TestIterator();
|
||||
REDCRAFTUTILITY_API void TestMoveIterator();
|
||||
REDCRAFTUTILITY_API void TestReverseIterator();
|
||||
REDCRAFTUTILITY_API void TestCountedIterator();
|
||||
REDCRAFTUTILITY_API void TestInsertIterator();
|
||||
|
||||
NAMESPACE_END(Testing)
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
Loading…
Reference in New Issue
Block a user