diff --git a/ostd/range.hh b/ostd/range.hh index 2f08fac..014a090 100644 --- a/ostd/range.hh +++ b/ostd/range.hh @@ -606,16 +606,48 @@ inline auto chunks(T n) { return [n](auto &&obj) { return obj.chunks(n); }; } +namespace detail { + template + inline auto join_proxy(T &&obj, Tuple &tup, TupleIndices) { + return obj.join(forward(get(tup))...); + } + + template + inline auto zip_proxy(T &&obj, Tuple &tup, TupleIndices) { + return obj.zip(forward(get(tup))...); + } +} + +template +inline auto join(R &&range) { + return [range = forward(range)](auto &&obj) mutable { + return obj.join(forward(range)); + }; +} + template inline auto join(R1 &&r1, R &&...rr) { - /* TODO find a way to avoid a copy here with varargs */ - return [=](auto &&obj) { return obj.join(move(r1), move(rr)...); }; + return [ranges = forward_as_tuple(forward(r1), forward(rr)...)] + (auto &&obj) mutable { + using Index = detail::MakeTupleIndices; + return detail::join_proxy(forward(obj), ranges, Index()); + }; +} + +template +inline auto zip(R &&range) { + return [range = forward(range)](auto &&obj) mutable { + return obj.zip(forward(range)); + }; } template inline auto zip(R1 &&r1, R &&...rr) { - /* TODO find a way to avoid a copy here with varargs */ - return [=](auto &&obj) { return obj.zip(move(r1), move(rr)...); }; + return [ranges = forward_as_tuple(forward(r1), forward(rr)...)] + (auto &&obj) mutable { + using Index = detail::MakeTupleIndices; + return detail::zip_proxy(forward(obj), ranges, Index()); + }; } template