#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: template map_stream(F && func, stream_base const & sb) : fun_(func), source_(sb) {} iterator begin() { return {map::iterator{fun_, source_.begin()}}; } iterator end() { return {map::iterator{fun_, source_.end()}}; } private: std::function fun_; stream_base source_; }; template template stream_base> stream_base::map(F && func) && { return std::make_shared>>( func, std::move(*this)); } template template stream_base> stream_base::map(F && func) const & { return std::make_shared>>(func, *this); } }}