| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- #pragma once
- #include <memory>
- #include "source.hpp"
- namespace stream {
- /**
- * Construct a stream out of the given container. If C && is an rvalue
- * reference, the returned object will take ownership of cont. Otherwise, we
- * capture cont by reference to maximise performance.
- */
- template <typename C>
- auto make_stream(C && cont) -> detail::stream_base<decltype(*cont.begin())> {
- return std::make_shared<detail::source_stream<C>>(std::forward<C>(cont));
- }
- template <typename T> detail::stream_base<T &> make_empty_stream() {
- return std::make_shared<detail::range_stream<T *, T &>>(nullptr, nullptr);
- }
- /**
- * Construct a single element stream containing the pointer given
- */
- template <typename T> detail::stream_base<T &> make_stream(T * ptr) {
- return std::make_shared<detail::range_stream<T *, T &>>(ptr, ptr + 1);
- }
- /**
- * Construct a stream from input iterators representing the start and end
- * Requirements: It must be an iterator type that provides the trait
- * 'reference'
- */
- 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);
- }
- /**
- * Construct a stream given certain start and end bounds.
- * e.g. stream::make_range_stream(0, 10)
- */
- template <typename T>
- detail::stream_base<T &> make_range_stream(T start, T const & end) {
- std::vector<T> vec;
- vec.reserve(end - start);
- while (start < end) {
- vec.emplace_back(start++);
- }
- return make_stream(std::move(vec));
- }
- /**
- * Construct a stream given certain start and end bounds, as well as an
- * increment amount. e.g. stream::make_range_stream(0, 10, 2)
- */
- 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));
- }
- }
|