#pragma once namespace stream { namespace detail { template class map_iterator { public: map_iterator(std::function f, iterator && impl) : fun_(f), impl_(std::forward>(impl)) {} R operator*() { return fun_(*impl_); } map_iterator & operator++() { ++impl_; return *this; } bool operator==(map_iterator const & rhs) const { return impl_ == rhs.impl_; } private: std::function fun_; 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); } }}