#include "Testing/Testing.h" #include "Ranges/Ranges.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 TestConversion() { { const TArray Arr = { 1, 2, 3, 4, 5 }; const TList List = { 1, 2, 3, 4, 5 }; const TArray Brr = Ranges::View(List.Begin(), List.End()) | Ranges::To>(); const TList Mist = Ranges::View(Arr.Begin(), Arr.End()) | Ranges::To>(); always_check(Arr == Brr); always_check(List == Mist); } { const TArray Arr = { 1, 2, 3, 4, 5 }; const TList List = { 1, 2, 3, 4, 5 }; const TArray Brr = Ranges::View(List.Begin(), List.End()) | Ranges::To(); const TList Mist = Ranges::View(Arr.Begin(), Arr.End()) | Ranges::To(); always_check(Arr == Brr); always_check(List == Mist); } } void TestFactory() { { const TArray Arr = { }; const TArray Brr = Ranges::Empty | Ranges::To>(); always_check(Arr == Brr); } { const TArray Arr = { 1 }; const TArray Brr = Ranges::Single(1) | Ranges::To>(); always_check(Arr == Brr); } { const TArray Arr = { 0, 1, 2, 3, 4 }; const TArray Brr = Ranges::Iota(0, 5) | Ranges::To>(); always_check(Arr == Brr); } { auto View = Ranges::Iota(0, 5); always_check(View.Num() == 5); always_check(!View.IsEmpty()); always_check(!!View); always_check(View.Front() == 0); auto First = View.Begin(); auto Last = View.End(); auto ConstFirst = AsConst(View).Begin(); auto ConstLast = AsConst(View).End(); always_check(First == ConstFirst); always_check(Last == ConstLast ); ConstFirst = First; ConstLast = Last; auto Iter = ConstFirst; auto Jter = ConstLast; ++Iter; always_check(*Iter++ == 1); } { auto View = Ranges::Iota(0); always_check(!View.IsEmpty()); always_check(!!View); always_check(View.Front() == 0); auto First = View.Begin(); auto Last = View.End(); auto ConstFirst = AsConst(View).Begin(); auto ConstLast = AsConst(View).End(); always_check(First == ConstFirst); ConstFirst = First; ConstLast = Last; auto Iter = ConstFirst; auto Jter = ConstLast; ++Iter; always_check(*Iter++ == 1); } { const TArray Arr = { 0, 0, 0, 0, 0 }; const TArray Brr = Ranges::Repeat(0, 5) | Ranges::To>(); always_check(Arr == Brr); } { auto View = Ranges::Repeat(0, 8); always_check(View.Num() == 8); always_check(!View.IsEmpty()); always_check(!!View); always_check(View.Front() == 0); always_check(View.Back() == 0); auto First = View.Begin(); auto Last = View.End(); auto ConstFirst = AsConst(View).Begin(); auto ConstLast = AsConst(View).End(); always_check(First == ConstFirst); always_check(Last == ConstLast ); always_check(ConstLast - First == 8); ConstFirst = First; ConstLast = Last; auto Iter = ConstFirst; auto Jter = ConstLast; ++Iter; --Jter; always_check(*Iter++ == 0); always_check(*Jter-- == 0); Iter += 2; Jter -= 2; always_check(Iter[-1] == 0); always_check(Jter[ 1] == 0); Iter = Iter - 2; Jter = Jter + 2; always_check(*Iter == 0); always_check(*Jter == 0); Iter = 2 + Iter; Jter = Jter - 2; always_check(Iter - Jter == 0); } { auto View = Ranges::Repeat(0); always_check(!View.IsEmpty()); always_check(!!View); always_check(View.Front() == 0); auto First = View.Begin(); auto Last = View.End(); auto ConstFirst = AsConst(View).Begin(); auto ConstLast = AsConst(View).End(); always_check(First == ConstFirst); ConstFirst = First; ConstLast = Last; auto Iter = ConstFirst; auto Jter = ConstFirst + 8; ++Iter; --Jter; always_check(*Iter++ == 0); always_check(*Jter-- == 0); Iter += 2; Jter -= 2; always_check(Iter[-1] == 0); always_check(Jter[ 1] == 0); Iter = Iter - 2; Jter = Jter + 2; always_check(*Iter == 0); always_check(*Jter == 0); Iter = 2 + Iter; Jter = Jter - 2; always_check(Iter - Jter == 0); } } void TestAllView() { TArray Arr = { 0, 1, 2, 3, 4 }; TArray Brr = Ranges::All(Arr) | Ranges::To>(); always_check(Arr == Brr); auto View = Ranges::All(MoveTemp(Arr)); Arr.Reset(); TArray Crr = View | Ranges::To>(); always_check(Brr == Crr); } void TestMoveView() { { 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 View = Arr | Ranges::Move(); auto First = View.Begin(); auto Last = View.End(); FTracker Temp(*First++); Temp = *First++; always_check(First == Last); } { TArray Arr = { 0, 1, 2, 3, 4, 5, 6, 7 }; auto View = Arr | Ranges::Move(); always_check(View.Num() == 8); always_check(!View.IsEmpty()); always_check(!!View); always_check(View.Front() == 0); always_check(View.Back() == 7); auto First = View.Begin(); auto Last = View.End(); auto ConstFirst = AsConst(View).Begin(); auto ConstLast = AsConst(View).End(); always_check(First == ConstFirst); always_check(Last == ConstLast ); always_check(ConstLast - First == 8); ConstFirst = First; ConstLast = Last; 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); } { auto View = Ranges::Iota(0) | Ranges::Move(); always_check(!View.IsEmpty()); always_check(!!View); always_check(View.Front() == 0); auto First = View.Begin(); auto Last = View.End(); auto ConstFirst = AsConst(View).Begin(); auto ConstLast = AsConst(View).End(); always_check(First == ConstFirst); ConstFirst = First; ConstLast = Last; auto Iter = ConstFirst; auto Jter = ConstLast; ++Iter; always_check(*Iter++ == 1); } } void TestMiscView() { { TArray Arr = { 0, 1, 2, 3, 4, 5, 6, 7 }; TArray Brr = { 0, 2, 4, 6 }; TArray Crr = Arr | Ranges::Filter([](int Value) { return Value % 2 == 0; }) | Ranges::To>(); always_check(Brr == Crr); } { TArray Arr = { 0, 1, 2, 2, 1, 0 }; TArray Brr = { 0, 2, 4, 4, 2, 0 }; TArray Crr = Arr | Ranges::Transform([](int Value) { return Value * 2; }) | Ranges::To>(); always_check(Brr == Crr); } { TArray Arr = { 0, 1, 2, 3, 3, 2, 1, 0 }; TArray Brr = { 0, 2, 4, 4, 2, 0 }; TArray Crr = Arr | Ranges::Filter ([](int Value) { return Value < 3; }) | Ranges::Transform([](int Value) { return Value * 2; }) | Ranges::To>(); TArray Drr = Arr | Ranges::Transform([](int Value) { return Value * 2; }) | Ranges::Filter ([](int Value) { return Value < 6; }) | Ranges::To>(); always_check(Brr == Crr); always_check(Brr == Drr); } { TArray Arr = { 0, 1, 2, 3, 4, 5, 6, 7 }; TArray Brr = Ranges::Iota(0) | Ranges::Take(8) | Ranges::To>(); TArray Crr = Ranges::Iota(0) | Ranges::TakeWhile([](int Value) { return Value < 8; }) | Ranges::To>(); always_check(Arr == Brr); always_check(Arr == Crr); } { TArray Arr = { 0, 4, 7, 8, 3, 1, 10 }; TArray Brr = { 0, 2, 4 }; TArray Crr = Arr | Ranges::Filter ([](int Value) { return Value % 2 == 0; }) | Ranges::Take(3) | Ranges::Transform([](int Value) { return Value / 2; }) | Ranges::To>(); TArray Drr = Arr | Ranges::Filter ([](int Value) { return Value % 2 == 0; }) | Ranges::TakeWhile([](int Value) { return Value < 10; }) | Ranges::Transform([](int Value) { return Value / 2; }) | Ranges::To>(); TArray Err = Arr | Ranges::Filter ([](int Value) { return Value % 2 == 0; }) | Ranges::Transform([](int Value) { return Value / 2; }) | Ranges::Take(3) | Ranges::To>(); TArray Frr = Arr | Ranges::Filter ([](int Value) { return Value % 2 == 0; }) | Ranges::Transform([](int Value) { return Value / 2; }) | Ranges::TakeWhile([](int Value) { return Value < 5; }) | Ranges::To>(); TArray Grr = Arr | Ranges::Take(6) | Ranges::Filter ([](int Value) { return Value % 2 == 0; }) | Ranges::Transform([](int Value) { return Value / 2; }) | Ranges::To>(); TArray Hrr = Arr | Ranges::TakeWhile([](int Value) { return Value < 10; }) | Ranges::Filter ([](int Value) { return Value % 2 == 0; }) | Ranges::Transform([](int Value) { return Value / 2; }) | Ranges::To>(); always_check(Brr == Crr); always_check(Brr == Drr); always_check(Brr == Err); always_check(Brr == Frr); always_check(Brr == Grr); always_check(Brr == Hrr); } } NAMESPACE_PRIVATE_END void TestRange() { NAMESPACE_PRIVATE::TestConversion(); NAMESPACE_PRIVATE::TestFactory(); NAMESPACE_PRIVATE::TestAllView(); NAMESPACE_PRIVATE::TestMoveView(); NAMESPACE_PRIVATE::TestMiscView(); } NAMESPACE_END(Testing) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END