| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- #pragma once
- namespace stream {
- namespace detail {
- namespace source {
- template <typename Iter> class iterator {
- public:
- using value_type = typename std::iterator_traits<Iter>::reference;
- explicit iterator(Iter it) : impl_(it) {}
- value_type operator*() { return *impl_; }
- DELEGATE_ITERATOR_IMPL(impl_)
- private:
- Iter impl_;
- };
- template <typename C>
- using reference = decltype(*std::declval<C>().begin());
- }
- template <typename C> class source_stream {
- public:
- typedef source::reference<C> reference;
- typedef decltype(std::declval<C>().begin()) _iterator;
- explicit source_stream(C && cont) : source_(std::forward<C>(cont)) {}
- iterator<reference> begin() {
- return {source::iterator<_iterator>{source_.begin()}};
- }
- iterator<reference> end() {
- return {source::iterator<_iterator>{source_.end()}};
- }
- private:
- C source_;
- };
- template <typename It, typename V = typename It::value_type>
- class range_stream {
- public:
- typedef V & reference;
- explicit range_stream(It b, It e) : begin_(b), end_(e) {}
- iterator<reference> begin() { return {source::iterator<It>{begin_}}; }
- iterator<reference> end() { return {source::iterator<It>{end_}}; }
- private:
- It begin_, end_;
- };
- }
- template <typename C>
- detail::stream_base<detail::source::reference<C>> make_stream(C && cont) {
- return std::make_shared<detail::source_stream<C>>(std::forward<C>(cont));
- }
- template <typename T> detail::stream_base<T &> make_stream(T * ptr) {
- return std::make_shared<detail::range_stream<T *, T &>>(ptr, ptr + 1);
- }
- template <typename It>
- detail::stream_base<typename It::reference> make_stream(It begin, It end) {
- return std::make_shared<detail::range_stream<It>>(begin, end);
- }
- template <typename T>
- detail::stream_base<T &> make_range_stream(T start, T const & end) {
- std::vector<T> vec;
- vec.reserve(end - start);
- while (end < start) {
- vec.emplace_back(start++);
- }
- return make_stream(std::move(vec));
- }
- template <typename T>
- detail::stream_base<T &> make_range_stream(T start, T const & end,
- T const & increment) {
- int elems{(end - start) / increment};
- if (elems < 0 || end == start) { return {}; }
- std::vector<T> vec{start};
- vec.reserve(elems + 1);
- while (elems-- > 0) {
- vec.emplace_back(start += increment);
- }
- return make_stream(std::move(vec));
- }
- }
|