Skip to content

Commit a56de08

Browse files
feat: add cmp to iterator interface (#114)
* feat: add cmp to iterator interface * fix: compilation error with std::expected
1 parent 5bef2f7 commit a56de08

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

include/rusty_iterators/interface.hpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ using iterator::Take;
6161
using iterator::Zip;
6262
using iterator::ZipLongest;
6363

64+
enum class Ordering : uint8_t
65+
{
66+
Equal,
67+
Less,
68+
Greater,
69+
};
70+
6471
template <class T, class Derived>
6572
class IterInterface
6673
{
@@ -85,6 +92,9 @@ class IterInterface
8592
requires AllFunctor<T, Functor>
8693
[[nodiscard]] auto all(Functor&& f) -> bool;
8794

95+
template <class Other>
96+
[[nodiscard]] auto cmp(Other&& it) -> Ordering;
97+
8898
[[nodiscard]] auto collect() -> std::vector<T>;
8999
[[nodiscard]] auto count() -> size_t;
90100

@@ -229,7 +239,7 @@ template <class Functor>
229239
requires rusty_iterators::concepts::AnyFunctor<T, Functor>
230240
auto rusty_iterators::interface::IterInterface<T, Derived>::any(Functor&& f) -> bool // NOLINT
231241
{
232-
auto anyf = [f = std::forward<Functor>(f)](auto acc, auto x) {
242+
auto anyf = [f = std::forward<Functor>(f)](auto acc, auto x) -> std::expected<bool, bool> {
233243
return f(x) ? std::expected<bool, bool>{true} : std::unexpected{false};
234244
};
235245
return self().tryFold(false, std::move(anyf));
@@ -240,12 +250,31 @@ template <class Functor>
240250
requires rusty_iterators::concepts::AllFunctor<T, Functor>
241251
auto rusty_iterators::interface::IterInterface<T, Derived>::all(Functor&& f) -> bool // NOLINT
242252
{
243-
auto allf = [f = std::forward<Functor>(f)](auto acc, auto x) {
253+
auto allf = [f = std::forward<Functor>(f)](auto acc, auto x) -> std::expected<bool, bool> {
244254
return !f(x) ? std::expected<bool, bool>{false} : std::unexpected{true};
245255
};
246256
return self().tryFold(true, std::move(allf));
247257
}
248258

259+
template <class T, class Derived>
260+
template <class Other>
261+
auto rusty_iterators::interface::IterInterface<T, Derived>::cmp(Other&& it) -> Ordering
262+
{
263+
auto func = [](auto acc, auto x) -> std::expected<Ordering, Ordering> {
264+
auto left = std::get<0>(x);
265+
auto right = std::get<1>(x);
266+
267+
if (left > right)
268+
return std::expected<Ordering, Ordering>{Ordering::Greater};
269+
270+
if (left < right)
271+
return std::expected<Ordering, Ordering>{Ordering::Less};
272+
273+
return std::unexpected{Ordering::Equal};
274+
};
275+
return self().zipLongest(std::forward<Other>(it)).tryFold(Ordering::Equal, std::move(func));
276+
}
277+
249278
template <class T, class Derived>
250279
auto rusty_iterators::interface::IterInterface<T, Derived>::collect() -> std::vector<T>
251280
{

tests/iterator.test.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <rusty_iterators/iterator.hpp>
55

6+
using ::rusty_iterators::interface::Ordering;
67
using ::rusty_iterators::iterator::LazyIterator;
78
using ::testing::ElementsAreArray;
89

@@ -411,3 +412,53 @@ TEST(TestIterator, TestGetWithUbAndLb)
411412

412413
EXPECT_THAT(it.collect(), ElementsAreArray({2, 3}));
413414
}
415+
416+
TEST(TestIterator, TestCmpLongerVector)
417+
{
418+
auto v1 = std::vector{1, 2, 3};
419+
auto v2 = std::vector{1, 2};
420+
421+
auto result = LazyIterator{v1}.cmp(LazyIterator{v2});
422+
423+
ASSERT_EQ(result, Ordering::Greater);
424+
}
425+
426+
TEST(TestIterator, TestCmpShorterVector)
427+
{
428+
auto v1 = std::vector{1, 2};
429+
auto v2 = std::vector{1, 2, 3};
430+
431+
auto result = LazyIterator{v1}.cmp(LazyIterator{v2});
432+
433+
ASSERT_EQ(result, Ordering::Less);
434+
}
435+
436+
TEST(TestIterator, TestCmpEqualVectors)
437+
{
438+
auto v1 = std::vector{1, 2, 3};
439+
auto v2 = std::vector{1, 2, 3};
440+
441+
auto result = LazyIterator{v1}.cmp(LazyIterator{v2});
442+
443+
ASSERT_EQ(result, Ordering::Equal);
444+
}
445+
446+
TEST(TestIterator, TestCmpGreaterValue)
447+
{
448+
auto v1 = std::vector{1, 2, 3};
449+
auto v2 = std::vector{1, 2, 4};
450+
451+
auto result = LazyIterator{v1}.cmp(LazyIterator{v2});
452+
453+
ASSERT_EQ(result, Ordering::Less);
454+
}
455+
456+
TEST(TestIterator, TestCmpShorterValue)
457+
{
458+
auto v1 = std::vector{1, 2, 3};
459+
auto v2 = std::vector{1, 2, 2};
460+
461+
auto result = LazyIterator{v1}.cmp(LazyIterator{v2});
462+
463+
ASSERT_EQ(result, Ordering::Greater);
464+
}

0 commit comments

Comments
 (0)