#pragma once #include namespace stream::detail { template class map_iterator : public ::iterator::proxy, map_iterator> { public: using projection_t = std::function; using super_t = ::iterator::proxy, map_iterator>; public: map_iterator(projection_t proj, iterator && impl) : proj_(std::move(proj)), super_t(std::move(impl)) {} R dereference() const { return proj_(super_t::dereference()); } private: std::function proj_; }; 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); } }