diff --git a/include/rusty_iterators/concepts.hpp b/include/rusty_iterators/concepts.hpp index 2a369f6..07dc908 100644 --- a/include/rusty_iterators/concepts.hpp +++ b/include/rusty_iterators/concepts.hpp @@ -60,6 +60,9 @@ concept InspectFunctor = requires(Functor f, T& t) { template concept PositionFunctor = AllFunctor; +template +concept ReduceFunctor = FoldFunctor; + template concept Summable = requires(T first, T second) { { first + second } -> std::same_as; diff --git a/include/rusty_iterators/interface.hpp b/include/rusty_iterators/interface.hpp index 51e5733..f75b1a0 100644 --- a/include/rusty_iterators/interface.hpp +++ b/include/rusty_iterators/interface.hpp @@ -30,6 +30,7 @@ using concepts::Indexable; using concepts::InspectFunctor; using concepts::NeFunctor; using concepts::PositionFunctor; +using concepts::ReduceFunctor; using concepts::Summable; using concepts::TryFoldFunctor; using concepts::TupleLike; @@ -115,6 +116,8 @@ class IterInterface requires InspectFunctor auto inspect(Functor&& f) -> Inspect; + [[nodiscard]] auto last() -> std::optional; + template requires std::invocable [[nodiscard]] auto map(Functor&& f) -> Map; @@ -143,7 +146,7 @@ class IterInterface [[nodiscard]] auto position(Functor&& f) -> std::optional; template - requires FoldFunctor + requires ReduceFunctor [[nodiscard]] auto reduce(Functor&& f) -> std::optional; template @@ -342,6 +345,12 @@ auto rusty_iterators::interface::IterInterface::inspect(Functor&& f) return Inspect{std::forward(self()), std::forward(f)}; } +template +auto rusty_iterators::interface::IterInterface::last() -> std::optional +{ + return self().reduce([](auto _, auto x) { return x; }); +} + template template requires std::invocable @@ -422,7 +431,7 @@ auto rusty_iterators::interface::IterInterface::position(Functor&& f template template - requires rusty_iterators::concepts::FoldFunctor + requires rusty_iterators::concepts::ReduceFunctor auto rusty_iterators::interface::IterInterface::reduce(Functor&& f) -> std::optional { auto first = self().next(); diff --git a/tests/iterator.test.cpp b/tests/iterator.test.cpp index f669ad2..4cc3be9 100644 --- a/tests/iterator.test.cpp +++ b/tests/iterator.test.cpp @@ -359,3 +359,19 @@ TEST(TestIterator, TestTryFoldEarlyExit) ASSERT_EQ(result, 6); } + +TEST(TestIterator, TestLastOnEmptyIterator) +{ + auto vec = std::vector{}; + auto it = LazyIterator{vec}; + + ASSERT_EQ(it.last(), std::nullopt); +} + +TEST(TestIterator, TestLast) +{ + auto vec = std::vector{1, 2, 3}; + auto it = LazyIterator{vec}; + + ASSERT_EQ(it.last(), 3); +}