#pragma once namespace stream { namespace detail { namespace source { template class iterator : public iterator_impl::reference> { public: using value_type = typename std::iterator_traits::reference; typedef iterator_impl super; explicit iterator(Iter it) : impl_(it) {} ~iterator() {} value_type operator*() override { return *impl_; } DELEGATE_ITERATOR_IMPL(impl_) private: Iter impl_; }; template using reference = decltype(*std::declval().begin()); } template class source_stream : public stream_impl> { public: typedef source::reference reference; typedef decltype(std::declval().begin()) _iterator; explicit source_stream(C && cont) : source_(std::forward(cont)) {} ~source_stream() override {} iterator begin() override { return {new source::iterator<_iterator>{source_.begin()}}; } iterator end() override { return {new source::iterator<_iterator>{source_.end()}}; } private: C source_; }; template class range_stream : public stream_impl { public: typedef V & reference; explicit range_stream(It b, It e) : begin_(b), end_(e) {} ~range_stream() override {} iterator begin() override { return {new source::iterator{begin_}}; } iterator end() override { return {new source::iterator{end_}}; } private: It begin_, end_; }; } template detail::stream_base> make_stream(C && cont) { return {std::make_shared>(cont)}; } template detail::stream_base make_stream(T * ptr) { return {std::make_shared>(ptr, ptr+1)}; } template detail::stream_base make_stream(It begin, It end) { return {std::make_shared>(begin, end)}; } }