feat(algorithms): add basic iterator algorithm and the corresponding testing

This commit is contained in:
Redstone1024 2024-12-20 17:35:31 +08:00
parent 8c228fbf52
commit 343007ffd6
4 changed files with 135 additions and 0 deletions

View File

@ -0,0 +1,45 @@
#include "Testing/Testing.h"
#include "Algorithms/Algorithms.h"
#include "Containers/Array.h"
#include "Containers/List.h"
#include "Miscellaneous/AssertionMacros.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(Testing)
NAMESPACE_PRIVATE_BEGIN
void TestBasic()
{
TArray<int> Arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto Iter = Arr.Begin();
Algorithm::Advance(Iter, 5);
always_check(*Iter == 5);
always_check(Algorithm::Distance(Arr.Begin(), Iter) == 5);
always_check(Algorithm::Distance(Arr) == 10);
always_check(*Algorithm::Next(Iter, 2) == 7);
always_check(*Algorithm::Prev(Iter, 2) == 3);
}
NAMESPACE_PRIVATE_END
void TestAlgorithms()
{
NAMESPACE_PRIVATE::TestBasic();
}
NAMESPACE_END(Testing)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,4 @@
#pragma once
#include "CoreTypes.h"
#include "Algorithms/Basic.h"

View 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

View File

@ -13,6 +13,7 @@ REDCRAFTUTILITY_API void TestTemplates();
REDCRAFTUTILITY_API void TestNumeric();
REDCRAFTUTILITY_API void TestIterator();
REDCRAFTUTILITY_API void TestRange();
REDCRAFTUTILITY_API void TestAlgorithms();
REDCRAFTUTILITY_API void TestMemory();
REDCRAFTUTILITY_API void TestContainers();
REDCRAFTUTILITY_API void TestString();