#pragma once namespace stream { namespace detail { namespace map { template class iterator { public: iterator(std::function f, ::stream::iterator&& impl) : fun_(f), impl_(std::forward<::stream::iterator>(impl)) {} R operator*() { return fun_(*impl_); } DELEGATE_ITERATOR_IMPL(impl_) private: std::function fun_; ::stream::iterator impl_; }; } template class map_stream : public stream_impl { public: template map_stream(F&& func, stream_base const& sb) : fun_(func), source_(sb) {} ~map_stream() override {} iterator begin() override { return {map::iterator{fun_, source_.begin()}}; } iterator end() override { return {map::iterator{fun_, source_.end()}}; } private: std::function fun_; stream_base source_; }; template template auto stream_base::map(F&& func) const -> stream_base> { using impl_t = map_stream>; return {std::make_shared(func, *this)}; } } }