diff --git a/include/rusty_iterators/interface.hpp b/include/rusty_iterators/interface.hpp index 179a27a..c6cc415 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,7 +239,7 @@ 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) { + auto anyf = [f = std::forward(f)](auto acc, auto x) -> std::expected { return f(x) ? std::expected{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) { + auto allf = [f = std::forward(f)](auto acc, auto x) -> std::expected { return !f(x) ? std::expected{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 std::expected{Ordering::Greater}; + + if (left < right) + return std::expected{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); +}