From d2abcee016a7a785e76ae496f7375d58dbd90353 Mon Sep 17 00:00:00 2001 From: WiktorNowak Date: Fri, 24 Jan 2025 08:06:42 +0100 Subject: [PATCH 1/2] feat: add cmp to iterator interface --- include/rusty_iterators/interface.hpp | 37 ++++++++++++++++--- tests/iterator.test.cpp | 51 +++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/include/rusty_iterators/interface.hpp b/include/rusty_iterators/interface.hpp index 179a27a..a8a4d99 100644 --- a/include/rusty_iterators/interface.hpp +++ b/include/rusty_iterators/interface.hpp @@ -61,6 +61,13 @@ using iterator::Take; using iterator::Zip; using iterator::ZipLongest; +enum class Ordering : uint8_t +{ + Equal, + Less, + Greater, +}; + template class IterInterface { @@ -85,6 +92,9 @@ class IterInterface requires AllFunctor [[nodiscard]] auto all(Functor&& f) -> bool; + template + [[nodiscard]] auto cmp(Other&& it) -> Ordering; + [[nodiscard]] auto collect() -> std::vector; [[nodiscard]] auto count() -> size_t; @@ -229,8 +239,8 @@ template requires rusty_iterators::concepts::AnyFunctor auto rusty_iterators::interface::IterInterface::any(Functor&& f) -> bool // NOLINT { - auto anyf = [f = std::forward(f)](auto acc, auto x) { - return f(x) ? std::expected{true} : std::unexpected{false}; + auto anyf = [f = std::forward(f)](auto acc, auto x) -> std::expected { + return f(x) ? true : std::unexpected{false}; }; return self().tryFold(false, std::move(anyf)); } @@ -240,12 +250,31 @@ template requires rusty_iterators::concepts::AllFunctor auto rusty_iterators::interface::IterInterface::all(Functor&& f) -> bool // NOLINT { - auto allf = [f = std::forward(f)](auto acc, auto x) { - return !f(x) ? std::expected{false} : std::unexpected{true}; + auto allf = [f = std::forward(f)](auto acc, auto x) -> std::expected { + return !f(x) ? false : std::unexpected{true}; }; return self().tryFold(true, std::move(allf)); } +template +template +auto rusty_iterators::interface::IterInterface::cmp(Other&& it) -> Ordering +{ + auto func = [](auto acc, auto x) -> std::expected { + auto left = std::get<0>(x); + auto right = std::get<1>(x); + + if (left > right) + return Ordering::Greater; + + if (left < right) + return Ordering::Less; + + return std::unexpected{Ordering::Equal}; + }; + return self().zipLongest(std::forward(it)).tryFold(Ordering::Equal, std::move(func)); +} + template auto rusty_iterators::interface::IterInterface::collect() -> std::vector { diff --git a/tests/iterator.test.cpp b/tests/iterator.test.cpp index 2316f62..cd7dc4f 100644 --- a/tests/iterator.test.cpp +++ b/tests/iterator.test.cpp @@ -3,6 +3,7 @@ #include +using ::rusty_iterators::interface::Ordering; using ::rusty_iterators::iterator::LazyIterator; using ::testing::ElementsAreArray; @@ -411,3 +412,53 @@ TEST(TestIterator, TestGetWithUbAndLb) EXPECT_THAT(it.collect(), ElementsAreArray({2, 3})); } + +TEST(TestIterator, TestCmpLongerVector) +{ + auto v1 = std::vector{1, 2, 3}; + auto v2 = std::vector{1, 2}; + + auto result = LazyIterator{v1}.cmp(LazyIterator{v2}); + + ASSERT_EQ(result, Ordering::Greater); +} + +TEST(TestIterator, TestCmpShorterVector) +{ + auto v1 = std::vector{1, 2}; + auto v2 = std::vector{1, 2, 3}; + + auto result = LazyIterator{v1}.cmp(LazyIterator{v2}); + + ASSERT_EQ(result, Ordering::Less); +} + +TEST(TestIterator, TestCmpEqualVectors) +{ + auto v1 = std::vector{1, 2, 3}; + auto v2 = std::vector{1, 2, 3}; + + auto result = LazyIterator{v1}.cmp(LazyIterator{v2}); + + ASSERT_EQ(result, Ordering::Equal); +} + +TEST(TestIterator, TestCmpGreaterValue) +{ + auto v1 = std::vector{1, 2, 3}; + auto v2 = std::vector{1, 2, 4}; + + auto result = LazyIterator{v1}.cmp(LazyIterator{v2}); + + ASSERT_EQ(result, Ordering::Less); +} + +TEST(TestIterator, TestCmpShorterValue) +{ + auto v1 = std::vector{1, 2, 3}; + auto v2 = std::vector{1, 2, 2}; + + auto result = LazyIterator{v1}.cmp(LazyIterator{v2}); + + ASSERT_EQ(result, Ordering::Greater); +} From bba2ac24968cc7fd1e57216e1e30c5ad6668ebb5 Mon Sep 17 00:00:00 2001 From: WiktorNowak Date: Fri, 24 Jan 2025 08:10:42 +0100 Subject: [PATCH 2/2] fix: compilation error with std::expected --- include/rusty_iterators/interface.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/rusty_iterators/interface.hpp b/include/rusty_iterators/interface.hpp index a8a4d99..c6cc415 100644 --- a/include/rusty_iterators/interface.hpp +++ b/include/rusty_iterators/interface.hpp @@ -240,7 +240,7 @@ template auto rusty_iterators::interface::IterInterface::any(Functor&& f) -> bool // NOLINT { auto anyf = [f = std::forward(f)](auto acc, auto x) -> std::expected { - return f(x) ? true : std::unexpected{false}; + return f(x) ? std::expected{true} : std::unexpected{false}; }; return self().tryFold(false, std::move(anyf)); } @@ -251,7 +251,7 @@ template auto rusty_iterators::interface::IterInterface::all(Functor&& f) -> bool // NOLINT { auto allf = [f = std::forward(f)](auto acc, auto x) -> std::expected { - return !f(x) ? false : std::unexpected{true}; + return !f(x) ? std::expected{false} : std::unexpected{true}; }; return self().tryFold(true, std::move(allf)); } @@ -265,10 +265,10 @@ auto rusty_iterators::interface::IterInterface::cmp(Other&& it) -> O auto right = std::get<1>(x); if (left > right) - return Ordering::Greater; + return std::expected{Ordering::Greater}; if (left < right) - return Ordering::Less; + return std::expected{Ordering::Less}; return std::unexpected{Ordering::Equal}; };