#pragma once #include #include #include #include #include namespace stream::ranges { template class transform_view { private: private: S stream_; Proj projection_; public: transform_view(S && stream, Proj projection) : stream_(FWD(stream)), projection_(projection) {} auto begin() const { return transform_iterator(stream_.begin(), invoke()); } auto end() const { if constexpr (detail::is_sentinal_v) { return stream_.end(); } else { return transform_iterator(stream_.end(), invoke()); } } SFINAE(detail::has_empty_v, bool) empty() const { return stream_.empty(); } SFINAE(detail::has_size_v, size_t) size() { return stream_.size(); } private: auto invoke() const { return std::function([this](detail::cref_t t) -> decltype(auto) { return std::invoke(projection_, t); }); } }; template transform_view(S &&, Proj) -> transform_view; } namespace stream::ranges::views { template class transform { public: transform(Proj const & projection) : projection_(projection) {} template friend auto operator|(Stream && stream, transform map) { // TODO: if constexpr transform_view return transform_view(FWD(stream), std::move(map.projection_)); } private: Proj projection_; }; } #include