feat(algorithms): add basic iterator algorithm and the corresponding testing
This commit is contained in:
4
Redcraft.Utility/Source/Public/Algorithms/Algorithms.h
Normal file
4
Redcraft.Utility/Source/Public/Algorithms/Algorithms.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Algorithms/Basic.h"
|
85
Redcraft.Utility/Source/Public/Algorithms/Basic.h
Normal file
85
Redcraft.Utility/Source/Public/Algorithms/Basic.h
Normal file
@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Iterators/Utility.h"
|
||||
#include "Iterators/BasicIterator.h"
|
||||
#include "Ranges/Utility.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
NAMESPACE_BEGIN(Algorithm)
|
||||
|
||||
/** Increments given iterator 'Iter' by 'N' elements. */
|
||||
template <CInputIterator I>
|
||||
FORCEINLINE constexpr void Advance(I& Iter, ptrdiff N)
|
||||
{
|
||||
if constexpr (CRandomAccessIterator<I>)
|
||||
{
|
||||
Iter += N;
|
||||
}
|
||||
|
||||
else if constexpr (CBidirectionalIterator<I>)
|
||||
{
|
||||
for (; N > 0; --N) ++Iter;
|
||||
for (; N < 0; ++N) --Iter;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
checkf(N >= 0, TEXT("The iterator must satisfy the CBidirectionalIterator in order to be decremented."));
|
||||
for (; N > 0; --N) ++Iter;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The number of hops from 'First' to 'Last'. */
|
||||
template <CInputIterator I, CSentinelFor<I> S>
|
||||
NODISCARD FORCEINLINE constexpr ptrdiff Distance(I First, S Last)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>)
|
||||
{
|
||||
return Last - First;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrdiff Result = 0;
|
||||
for (; First != Last; ++First) ++Result;
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The size of the range. */
|
||||
template <CRange R>
|
||||
NODISCARD FORCEINLINE constexpr ptrdiff Distance(R&& Range)
|
||||
{
|
||||
if constexpr (CSizedRange<R>)
|
||||
{
|
||||
return static_cast<ptrdiff>(Range::Num(Range));
|
||||
}
|
||||
else return Algorithm::Distance(Range::Begin(Range), Range::End(Range));
|
||||
}
|
||||
|
||||
/** @return The 'N'-th successor of iterator 'Iter'. */
|
||||
template <CInputIterator I>
|
||||
NODISCARD FORCEINLINE constexpr I Next(I Iter, ptrdiff N = 1)
|
||||
{
|
||||
Algorithm::Advance(Iter, N);
|
||||
return Iter;
|
||||
}
|
||||
|
||||
/** @return The 'N'-th predecessor of iterator 'Iter'. */
|
||||
template <CBidirectionalIterator I>
|
||||
NODISCARD FORCEINLINE constexpr I Prev(I Iter, ptrdiff N = 1)
|
||||
{
|
||||
Algorithm::Advance(Iter, -N);
|
||||
return Iter;
|
||||
}
|
||||
|
||||
NAMESPACE_END(Algorithm)
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
Reference in New Issue
Block a user