#pragma once namespace stream { namespace detail { template class source_iterator { public: using value_type = typename std::iterator_traits::reference; explicit source_iterator(Iter it) : impl_(it) {} value_type operator*() { return *impl_; } source_iterator & operator++() { ++impl_; return *this; } bool operator==(source_iterator const & rhs) const { return impl_ == rhs.impl_; } private: Iter impl_; }; template class source_stream { public: typedef decltype(std::declval().begin()) _iterator; typedef decltype(*std::declval<_iterator>()) reference; explicit source_stream(C && cont) : source_(std::forward(cont)) {} iterator begin() { return {source_iterator<_iterator>{source_.begin()}}; } iterator end() { return {source_iterator<_iterator>{source_.end()}}; } private: C source_; }; template class range_stream { public: typedef V & reference; explicit range_stream(It b, It e) : begin_(b), end_(e) {} iterator begin() { return {source_iterator{begin_}}; } iterator end() { return {source_iterator{end_}}; } private: It begin_, end_; }; }}