#include "Testing/Testing.h" #include "Algorithms/Algorithms.h" #include "Containers/Array.h" #include "Containers/List.h" #include "Ranges/Factory.h" #include "Numerics/Math.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 Arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; auto Iter = Arr.Begin(); Algorithms::Advance(Iter, 5); always_check(*Iter == 5); always_check(Algorithms::Distance(Arr.Begin(), Iter) == 5); always_check(Algorithms::Distance(Arr) == 10); always_check(*Algorithms::Next(Iter) == 6); always_check(*Algorithms::Next(Iter, 2) == 7); always_check(*Algorithms::Prev(Iter) == 4); always_check(*Algorithms::Prev(Iter, 2) == 3); always_check(Algorithms::Next(Iter, Arr.End()) == Arr.End()); always_check(Algorithms::Next(Iter, 16, Arr.End()) == Arr.End()); always_check(Algorithms::Prev(Iter, 16, Arr.Begin()) == Arr.Begin()); Iter = Arr.Begin(); Algorithms::Advance(Iter, Arr.End()); always_check(Iter == Arr.End()); Iter = Arr.Begin(); always_check(Algorithms::Advance(Iter, 16, Arr.End()) == 6); always_check(Iter == Arr.End()); } { TList Arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; auto Iter = Arr.Begin(); Algorithms::Advance(Iter, 5); always_check(*Iter == 5); always_check(Algorithms::Distance(Arr.Begin(), Iter) == 5); always_check(Algorithms::Distance(Arr) == 10); always_check(*Algorithms::Next(Iter) == 6); always_check(*Algorithms::Next(Iter, 2) == 7); always_check(*Algorithms::Prev(Iter) == 4); always_check(*Algorithms::Prev(Iter, 2) == 3); always_check(Algorithms::Next(Iter, Arr.End()) == Arr.End()); always_check(Algorithms::Next(Iter, 16, Arr.End()) == Arr.End()); always_check(Algorithms::Prev(Iter, 16, Arr.Begin()) == Arr.Begin()); Iter = Arr.Begin(); Algorithms::Advance(Iter, Arr.End()); always_check(Iter == Arr.End()); Iter = Arr.Begin(); always_check(Algorithms::Advance(Iter, 16, Arr.End()) == 6); always_check(Iter == Arr.End()); } { auto Arr = Ranges::Iota(0, 10); auto Iter = Arr.Begin(); Algorithms::Advance(Iter, 5); always_check(*Iter == 5); always_check(Algorithms::Distance(Arr.Begin(), Iter) == 5); always_check(Algorithms::Distance(Arr) == 10); always_check(*Algorithms::Next(Iter) == 6); always_check(*Algorithms::Next(Iter, 2) == 7); always_check(Algorithms::Next(Iter, Arr.End()) == Arr.End()); always_check(Algorithms::Next(Iter, 16, Arr.End()) == Arr.End()); Iter = Arr.Begin(); Algorithms::Advance(Iter, Arr.End()); always_check(Iter == Arr.End()); Iter = Arr.Begin(); always_check(Algorithms::Advance(Iter, 16, Arr.End()) == 6); always_check(Iter == Arr.End()); } } void TestSearch() { { TArray Arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; TList Brr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; auto Crr = Ranges::Iota(0, 10); always_check( Algorithms::AllOf(Arr, [](int A) { return A < 10; })); always_check( Algorithms::AllOf(Brr, [](int A) { return A < 10; })); always_check( Algorithms::AllOf(Crr, [](int A) { return A < 10; })); always_check(!Algorithms::AllOf(Arr, [](int A) { return A > 5; })); always_check(!Algorithms::AllOf(Brr, [](int A) { return A > 5; })); always_check(!Algorithms::AllOf(Crr, [](int A) { return A > 5; })); always_check( Algorithms::AllOf(Arr.Begin(), Arr.End(), [](int A) { return A < 10; })); always_check( Algorithms::AllOf(Brr.Begin(), Brr.End(), [](int A) { return A < 10; })); always_check( Algorithms::AllOf(Crr.Begin(), Crr.End(), [](int A) { return A < 10; })); always_check(!Algorithms::AllOf(Arr.Begin(), Arr.End(), [](int A) { return A > 5; })); always_check(!Algorithms::AllOf(Brr.Begin(), Brr.End(), [](int A) { return A > 5; })); always_check(!Algorithms::AllOf(Crr.Begin(), Crr.End(), [](int A) { return A > 5; })); always_check(Algorithms::AnyOf(Arr, [](int A) { return A < 10; })); always_check(Algorithms::AnyOf(Brr, [](int A) { return A < 10; })); always_check(Algorithms::AnyOf(Crr, [](int A) { return A < 10; })); always_check(Algorithms::AnyOf(Arr, [](int A) { return A > 5; })); always_check(Algorithms::AnyOf(Brr, [](int A) { return A > 5; })); always_check(Algorithms::AnyOf(Crr, [](int A) { return A > 5; })); always_check(Algorithms::AnyOf(Arr.Begin(), Arr.End(), [](int A) { return A < 10; })); always_check(Algorithms::AnyOf(Brr.Begin(), Brr.End(), [](int A) { return A < 10; })); always_check(Algorithms::AnyOf(Crr.Begin(), Crr.End(), [](int A) { return A < 10; })); always_check(Algorithms::AnyOf(Arr.Begin(), Arr.End(), [](int A) { return A > 5; })); always_check(Algorithms::AnyOf(Brr.Begin(), Brr.End(), [](int A) { return A > 5; })); always_check(Algorithms::AnyOf(Crr.Begin(), Crr.End(), [](int A) { return A > 5; })); always_check(!Algorithms::NoneOf(Arr, [](int A) { return A < 10; })); always_check(!Algorithms::NoneOf(Brr, [](int A) { return A < 10; })); always_check(!Algorithms::NoneOf(Crr, [](int A) { return A < 10; })); always_check(!Algorithms::NoneOf(Arr, [](int A) { return A > 5; })); always_check(!Algorithms::NoneOf(Brr, [](int A) { return A > 5; })); always_check(!Algorithms::NoneOf(Crr, [](int A) { return A > 5; })); always_check(!Algorithms::NoneOf(Arr.Begin(), Arr.End(), [](int A) { return A < 10; })); always_check(!Algorithms::NoneOf(Brr.Begin(), Brr.End(), [](int A) { return A < 10; })); always_check(!Algorithms::NoneOf(Crr.Begin(), Crr.End(), [](int A) { return A < 10; })); always_check(!Algorithms::NoneOf(Arr.Begin(), Arr.End(), [](int A) { return A > 5; })); always_check(!Algorithms::NoneOf(Brr.Begin(), Brr.End(), [](int A) { return A > 5; })); always_check(!Algorithms::NoneOf(Crr.Begin(), Crr.End(), [](int A) { return A > 5; })); always_check( Algorithms::Contains(Arr, 5)); always_check( Algorithms::Contains(Brr, 5)); always_check( Algorithms::Contains(Crr, 5)); always_check(!Algorithms::Contains(Arr, 10)); always_check(!Algorithms::Contains(Brr, 10)); always_check(!Algorithms::Contains(Crr, 10)); always_check( Algorithms::Contains(Arr.Begin(), Arr.End(), 5)); always_check( Algorithms::Contains(Brr.Begin(), Brr.End(), 5)); always_check( Algorithms::Contains(Crr.Begin(), Crr.End(), 5)); always_check(!Algorithms::Contains(Arr.Begin(), Arr.End(), 10)); always_check(!Algorithms::Contains(Brr.Begin(), Brr.End(), 10)); always_check(!Algorithms::Contains(Crr.Begin(), Crr.End(), 10)); auto Projection = [](int A) { return A % 4; }; // Project to { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1 } always_check(Algorithms::Find(Arr, 2, { }, Projection) == Algorithms::Next(Arr.Begin(), 2)); always_check(Algorithms::Find(Brr, 2, { }, Projection) == Algorithms::Next(Brr.Begin(), 2)); always_check(Algorithms::Find(Crr, 2, { }, Projection) == Algorithms::Next(Crr.Begin(), 2)); always_check(Algorithms::Find(Arr.Begin(), Arr.End(), 2, { }, Projection) == Algorithms::Next(Arr.Begin(), 2)); always_check(Algorithms::Find(Brr.Begin(), Brr.End(), 2, { }, Projection) == Algorithms::Next(Brr.Begin(), 2)); always_check(Algorithms::Find(Crr.Begin(), Crr.End(), 2, { }, Projection) == Algorithms::Next(Crr.Begin(), 2)); always_check(Algorithms::Find(Arr, 10) == Arr.End()); always_check(Algorithms::Find(Brr, 10) == Brr.End()); always_check(Algorithms::Find(Crr, 10) == Crr.End()); always_check(Algorithms::Find(Arr, Ranges::Iota(1, 4), { }, Projection).Begin() == Algorithms::Next(Arr.Begin())); always_check(Algorithms::Find(Brr, Ranges::Iota(1, 4), { }, Projection).Begin() == Algorithms::Next(Brr.Begin())); always_check(Algorithms::Find(Crr, Ranges::Iota(1, 4), { }, Projection).Begin() == Algorithms::Next(Crr.Begin())); always_check(Algorithms::Find(Arr, Ranges::Iota(4, 16)).IsEmpty()); always_check(Algorithms::Find(Brr, Ranges::Iota(4, 16)).IsEmpty()); always_check(Algorithms::Find(Crr, Ranges::Iota(4, 16)).IsEmpty()); always_check(Algorithms::FindIf(Arr, [](int A) { return A == 2; }, Projection) == Algorithms::Next(Arr.Begin(), 2)); always_check(Algorithms::FindIf(Brr, [](int A) { return A == 2; }, Projection) == Algorithms::Next(Brr.Begin(), 2)); always_check(Algorithms::FindIf(Crr, [](int A) { return A == 2; }, Projection) == Algorithms::Next(Crr.Begin(), 2)); always_check(Algorithms::FindIf(Arr.Begin(), Arr.End(), [](int A) { return A == 2; }, Projection) == Algorithms::Next(Arr.Begin(), 2)); always_check(Algorithms::FindIf(Brr.Begin(), Brr.End(), [](int A) { return A == 2; }, Projection) == Algorithms::Next(Brr.Begin(), 2)); always_check(Algorithms::FindIf(Crr.Begin(), Crr.End(), [](int A) { return A == 2; }, Projection) == Algorithms::Next(Crr.Begin(), 2)); always_check(Algorithms::FindIf(Arr, [](int A) { return A == 10; }) == Arr.End()); always_check(Algorithms::FindIf(Brr, [](int A) { return A == 10; }) == Brr.End()); always_check(Algorithms::FindIf(Crr, [](int A) { return A == 10; }) == Crr.End()); always_check(Algorithms::FindIfNot(Arr, [](int A) { return A > 0; }, Projection) == Arr.Begin()); always_check(Algorithms::FindIfNot(Brr, [](int A) { return A > 0; }, Projection) == Brr.Begin()); always_check(Algorithms::FindIfNot(Crr, [](int A) { return A > 0; }, Projection) == Crr.Begin()); always_check(Algorithms::FindIfNot(Arr.Begin(), Arr.End(), [](int A) { return A > 0; }, Projection) == Arr.Begin()); always_check(Algorithms::FindIfNot(Brr.Begin(), Brr.End(), [](int A) { return A > 0; }, Projection) == Brr.Begin()); always_check(Algorithms::FindIfNot(Crr.Begin(), Crr.End(), [](int A) { return A > 0; }, Projection) == Crr.Begin()); always_check(Algorithms::FindIfNot(Arr, [](int A) { return A < 8; }) == Algorithms::Next(Arr.Begin(), 8)); always_check(Algorithms::FindIfNot(Brr, [](int A) { return A < 8; }) == Algorithms::Next(Brr.Begin(), 8)); always_check(Algorithms::FindIfNot(Crr, [](int A) { return A < 8; }) == Algorithms::Next(Crr.Begin(), 8)); always_check(Algorithms::FindLast(Arr, 2, { }, Projection) == Algorithms::Next(Arr.Begin(), 6)); always_check(Algorithms::FindLast(Brr, 2, { }, Projection) == Algorithms::Next(Brr.Begin(), 6)); always_check(Algorithms::FindLast(Crr, 2, { }, Projection) == Algorithms::Next(Crr.Begin(), 6)); always_check(Algorithms::FindLast(Arr.Begin(), Arr.End(), 2, { }, Projection) == Algorithms::Next(Arr.Begin(), 6)); always_check(Algorithms::FindLast(Brr.Begin(), Brr.End(), 2, { }, Projection) == Algorithms::Next(Brr.Begin(), 6)); always_check(Algorithms::FindLast(Crr.Begin(), Crr.End(), 2, { }, Projection) == Algorithms::Next(Crr.Begin(), 6)); always_check(Algorithms::FindLast(Arr, 10) == Arr.End()); always_check(Algorithms::FindLast(Brr, 10) == Brr.End()); always_check(Algorithms::FindLast(Crr, 10) == Crr.End()); always_check(Algorithms::FindLast(Arr, Ranges::Iota(1, 4), { }, Projection).Begin() == Algorithms::Next(Arr.Begin(), 5)); always_check(Algorithms::FindLast(Brr, Ranges::Iota(1, 4), { }, Projection).Begin() == Algorithms::Next(Brr.Begin(), 5)); always_check(Algorithms::FindLast(Crr, Ranges::Iota(1, 4), { }, Projection).Begin() == Algorithms::Next(Crr.Begin(), 5)); always_check(Algorithms::FindLast(Arr, Ranges::Iota(4, 16)).IsEmpty()); always_check(Algorithms::FindLast(Brr, Ranges::Iota(4, 16)).IsEmpty()); always_check(Algorithms::FindLast(Crr, Ranges::Iota(4, 16)).IsEmpty()); always_check(Algorithms::FindLastIf(Arr, [](int A) { return A == 2; }, Projection) == Algorithms::Next(Arr.Begin(), 6)); always_check(Algorithms::FindLastIf(Brr, [](int A) { return A == 2; }, Projection) == Algorithms::Next(Brr.Begin(), 6)); always_check(Algorithms::FindLastIf(Crr, [](int A) { return A == 2; }, Projection) == Algorithms::Next(Crr.Begin(), 6)); always_check(Algorithms::FindLastIf(Arr.Begin(), Arr.End(), [](int A) { return A == 2; }, Projection) == Algorithms::Next(Arr.Begin(), 6)); always_check(Algorithms::FindLastIf(Brr.Begin(), Brr.End(), [](int A) { return A == 2; }, Projection) == Algorithms::Next(Brr.Begin(), 6)); always_check(Algorithms::FindLastIf(Crr.Begin(), Crr.End(), [](int A) { return A == 2; }, Projection) == Algorithms::Next(Crr.Begin(), 6)); always_check(Algorithms::FindLastIf(Arr, [](int A) { return A == 10; }) == Arr.End()); always_check(Algorithms::FindLastIf(Brr, [](int A) { return A == 10; }) == Brr.End()); always_check(Algorithms::FindLastIf(Crr, [](int A) { return A == 10; }) == Crr.End()); always_check(Algorithms::FindLastIfNot(Arr, [](int A) { return A > 0; }, Projection) == Algorithms::Next(Arr.Begin(), 8)); always_check(Algorithms::FindLastIfNot(Brr, [](int A) { return A > 0; }, Projection) == Algorithms::Next(Brr.Begin(), 8)); always_check(Algorithms::FindLastIfNot(Crr, [](int A) { return A > 0; }, Projection) == Algorithms::Next(Crr.Begin(), 8)); always_check(Algorithms::FindLastIfNot(Arr.Begin(), Arr.End(), [](int A) { return A > 0; }, Projection) == Algorithms::Next(Arr.Begin(), 8)); always_check(Algorithms::FindLastIfNot(Brr.Begin(), Brr.End(), [](int A) { return A > 0; }, Projection) == Algorithms::Next(Brr.Begin(), 8)); always_check(Algorithms::FindLastIfNot(Crr.Begin(), Crr.End(), [](int A) { return A > 0; }, Projection) == Algorithms::Next(Crr.Begin(), 8)); always_check(Algorithms::FindLastIfNot(Arr, [](int A) { return A < 8; }) == Algorithms::Next(Arr.Begin(), 9)); always_check(Algorithms::FindLastIfNot(Brr, [](int A) { return A < 8; }) == Algorithms::Next(Brr.Begin(), 9)); always_check(Algorithms::FindLastIfNot(Crr, [](int A) { return A < 8; }) == Algorithms::Next(Crr.Begin(), 9)); always_check(Algorithms::FindAdjacent(Arr, { }, [](int A) { return Math::DivAndCeil(A, 2); }) == Algorithms::Next(Arr.Begin())); always_check(Algorithms::FindAdjacent(Brr, { }, [](int A) { return Math::DivAndCeil(A, 2); }) == Algorithms::Next(Brr.Begin())); always_check(Algorithms::FindAdjacent(Crr, { }, [](int A) { return Math::DivAndCeil(A, 2); }) == Algorithms::Next(Crr.Begin())); always_check(Algorithms::FindAdjacent(Arr.Begin(), Arr.End(), { }, [](int A) { return Math::DivAndCeil(A, 2); }) == Algorithms::Next(Arr.Begin())); always_check(Algorithms::FindAdjacent(Brr.Begin(), Brr.End(), { }, [](int A) { return Math::DivAndCeil(A, 2); }) == Algorithms::Next(Brr.Begin())); always_check(Algorithms::FindAdjacent(Crr.Begin(), Crr.End(), { }, [](int A) { return Math::DivAndCeil(A, 2); }) == Algorithms::Next(Crr.Begin())); always_check(Algorithms::FindAdjacent(Arr) == Arr.End()); always_check(Algorithms::FindAdjacent(Brr) == Brr.End()); always_check(Algorithms::FindAdjacent(Crr) == Crr.End()); always_check(Algorithms::Count(Arr, 2, { }, Projection) == 2); always_check(Algorithms::Count(Brr, 2, { }, Projection) == 2); always_check(Algorithms::Count(Crr, 2, { }, Projection) == 2); always_check(Algorithms::Count(Arr.Begin(), Arr.End(), 2, { }, Projection) == 2); always_check(Algorithms::Count(Brr.Begin(), Brr.End(), 2, { }, Projection) == 2); always_check(Algorithms::Count(Crr.Begin(), Crr.End(), 2, { }, Projection) == 2); always_check(Algorithms::Count(Arr, 10) == 0); always_check(Algorithms::Count(Brr, 10) == 0); always_check(Algorithms::Count(Crr, 10) == 0); always_check(Algorithms::CountIf(Arr, [](int A) { return A == 2; }, Projection) == 2); always_check(Algorithms::CountIf(Brr, [](int A) { return A == 2; }, Projection) == 2); always_check(Algorithms::CountIf(Crr, [](int A) { return A == 2; }, Projection) == 2); always_check(Algorithms::CountIf(Arr.Begin(), Arr.End(), [](int A) { return A == 2; }, Projection) == 2); always_check(Algorithms::CountIf(Brr.Begin(), Brr.End(), [](int A) { return A == 2; }, Projection) == 2); always_check(Algorithms::CountIf(Crr.Begin(), Crr.End(), [](int A) { return A == 2; }, Projection) == 2); always_check(Algorithms::CountIf(Arr, [](int A) { return A == 10; }) == 0); always_check(Algorithms::CountIf(Brr, [](int A) { return A == 10; }) == 0); always_check(Algorithms::CountIf(Crr, [](int A) { return A == 10; }) == 0); always_check(Algorithms::Mismatch(Arr, Arr, { }, Projection) == MakeTuple(Algorithms::Next(Arr.Begin(), 4), Algorithms::Next(Arr.Begin(), 4))); always_check(Algorithms::Mismatch(Brr, Brr, { }, Projection) == MakeTuple(Algorithms::Next(Brr.Begin(), 4), Algorithms::Next(Brr.Begin(), 4))); always_check(Algorithms::Mismatch(Crr, Crr, { }, Projection) == MakeTuple(Algorithms::Next(Crr.Begin(), 4), Algorithms::Next(Crr.Begin(), 4))); always_check(Algorithms::Mismatch(Arr.Begin(), Arr.End(), Brr.Begin(), Brr.End(), { }, Projection) == MakeTuple(Algorithms::Next(Arr.Begin(), 4), Algorithms::Next(Brr.Begin(), 4))); always_check(Algorithms::Mismatch(Brr.Begin(), Brr.End(), Crr.Begin(), Crr.End(), { }, Projection) == MakeTuple(Algorithms::Next(Brr.Begin(), 4), Algorithms::Next(Crr.Begin(), 4))); always_check(Algorithms::Mismatch(Crr.Begin(), Crr.End(), Arr.Begin(), Arr.End(), { }, Projection) == MakeTuple(Algorithms::Next(Crr.Begin(), 4), Algorithms::Next(Arr.Begin(), 4))); always_check(Algorithms::Mismatch(Arr, Brr, { }, Projection) == MakeTuple(Algorithms::Next(Arr.Begin(), 4), Algorithms::Next(Brr.Begin(), 4))); always_check(Algorithms::Mismatch(Brr, Crr, { }, Projection) == MakeTuple(Algorithms::Next(Brr.Begin(), 4), Algorithms::Next(Crr.Begin(), 4))); always_check(Algorithms::Mismatch(Crr, Arr, { }, Projection) == MakeTuple(Algorithms::Next(Crr.Begin(), 4), Algorithms::Next(Arr.Begin(), 4))); always_check(Algorithms::Equal(Arr, Arr)); always_check(Algorithms::Equal(Brr, Brr)); always_check(Algorithms::Equal(Crr, Crr)); always_check(Algorithms::Equal(Arr.Begin(), Arr.End(), Brr.Begin(), Brr.End())); always_check(Algorithms::Equal(Brr.Begin(), Brr.End(), Crr.Begin(), Crr.End())); always_check(Algorithms::Equal(Crr.Begin(), Crr.End(), Arr.Begin(), Arr.End())); always_check(Algorithms::Equal(Arr, Brr)); always_check(Algorithms::Equal(Brr, Crr)); always_check(Algorithms::Equal(Crr, Arr)); always_check(Algorithms::StartsWith(Arr, Ranges::Iota(0, 8))); always_check(Algorithms::StartsWith(Brr, Ranges::Iota(0, 8))); always_check(Algorithms::StartsWith(Crr, Ranges::Iota(0, 8))); always_check(!Algorithms::StartsWith(Arr, Ranges::Iota(0, 8), { }, Projection)); always_check(!Algorithms::StartsWith(Brr, Ranges::Iota(0, 8), { }, Projection)); always_check(!Algorithms::StartsWith(Crr, Ranges::Iota(0, 8), { }, Projection)); always_check(Algorithms::EndsWith(Arr, Ranges::Iota(8, 10))); always_check(Algorithms::EndsWith(Brr, Ranges::Iota(8, 10))); always_check(Algorithms::EndsWith(Crr, Ranges::Iota(8, 10))); always_check(Algorithms::EndsWith(Arr, Ranges::Iota(0, 2), { }, Projection)); always_check(Algorithms::EndsWith(Brr, Ranges::Iota(0, 2), { }, Projection)); always_check(Algorithms::EndsWith(Crr, Ranges::Iota(0, 2), { }, Projection)); } } NAMESPACE_PRIVATE_END void TestAlgorithms() { NAMESPACE_PRIVATE::TestBasic(); NAMESPACE_PRIVATE::TestSearch(); } NAMESPACE_END(Testing) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END