diff --git a/include/rusty_iterators/concepts.hpp b/include/rusty_iterators/concepts.hpp index b602b45..2a369f6 100644 --- a/include/rusty_iterators/concepts.hpp +++ b/include/rusty_iterators/concepts.hpp @@ -25,6 +25,9 @@ concept EqFunctor = requires(Functor f, std::tuple t) { { f(t) } -> std::same_as; }; +template +concept NeFunctor = EqFunctor; + template concept FilterFunctor = AllFunctor; diff --git a/include/rusty_iterators/interface.hpp b/include/rusty_iterators/interface.hpp index eda11d8..6b0c4fa 100644 --- a/include/rusty_iterators/interface.hpp +++ b/include/rusty_iterators/interface.hpp @@ -27,6 +27,7 @@ using concepts::FoldFunctor; using concepts::ForEachFunctor; using concepts::Indexable; using concepts::InspectFunctor; +using concepts::NeFunctor; using concepts::PositionFunctor; using concepts::Summable; using concepts::TryFoldFunctor; @@ -123,6 +124,14 @@ class IterInterface [[nodiscard]] auto min() -> std::optional; [[nodiscard]] auto movingWindow(size_t size) -> MovingWindow; + + template + [[nodiscard]] auto ne(Other&& it) -> bool; + + template + requires NeFunctor + [[nodiscard]] auto neBy(Other&& it, Functor&& f) -> bool; + [[nodiscard]] auto nth(size_t element) -> std::optional; template @@ -355,6 +364,22 @@ auto rusty_iterators::interface::IterInterface::movingWindow(size_t return MovingWindow{std::forward(self()), size}; } +template +template +auto rusty_iterators::interface::IterInterface::ne(Other&& it) -> bool +{ + return self().neBy(std::forward(it), + [](auto x) { return std::get<0>(x) != std::get<1>(x); }); +} + +template +template + requires rusty_iterators::concepts::NeFunctor +auto rusty_iterators::interface::IterInterface::neBy(Other&& it, Functor&& f) -> bool +{ + return self().zip(std::forward(it)).any(std::forward(f)); +} + template auto rusty_iterators::interface::IterInterface::nth(size_t element) -> std::optional { diff --git a/tests/iterator.test.cpp b/tests/iterator.test.cpp index c22ff60..022259a 100644 --- a/tests/iterator.test.cpp +++ b/tests/iterator.test.cpp @@ -319,6 +319,34 @@ TEST(TestIterator, TestEqBy) ASSERT_TRUE(result); } +TEST(TestIterator, TestNeWhenSame) +{ + auto v1 = std::vector{1, 2, 3}; + auto v2 = std::vector{1, 2, 3}; + + ASSERT_FALSE(LazyIterator{v1}.ne(LazyIterator{v2})); +} + +TEST(TestIterator, TestNeWhenDifferent) +{ + auto v1 = std::vector{1, 2, 3}; + auto v2 = std::vector{1, 2, 4}; + + ASSERT_TRUE(LazyIterator{v1}.ne(LazyIterator{v2})); +} + +TEST(TestIterator, TestNeBy) +{ + auto v1 = std::vector{"a", "bc", "def"}; + auto v2 = std::vector{"d", "jk", "cgde"}; + + auto result = LazyIterator{v1}.neBy(LazyIterator{v2}, [](auto x) { + return std::get<0>(x).get().size() != std::get<1>(x).get().size(); + }); + + ASSERT_TRUE(result); +} + TEST(TestIterator, TestTryFoldEarlyExit) { auto vec = std::vector{1, 2, 3, 4, 5};