make_stream.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #pragma once
  2. #include "source.hpp"
  3. namespace stream {
  4. /**
  5. * Construct a stream out of the given container. If C && is an rvalue
  6. * reference, the returned object will take ownership of cont. Otherwise, we
  7. * capture cont by reference to maximise performance.
  8. */
  9. template <typename C>
  10. auto make_stream(C && cont) -> detail::stream_base<decltype(*cont.begin())> {
  11. return std::make_shared<detail::source_stream<C>>(std::forward<C>(cont));
  12. }
  13. /**
  14. * Construct a single element stream containing the pointer given
  15. */
  16. template <typename T> detail::stream_base<T &> make_stream(T * ptr) {
  17. return std::make_shared<detail::range_stream<T *, T &>>(ptr, ptr + 1);
  18. }
  19. /**
  20. * Construct a stream from input iterators representing the start and end
  21. * Requirements: It must be an iterator type that provides the trait
  22. * 'reference'
  23. */
  24. template <typename It>
  25. detail::stream_base<typename It::reference> make_stream(It begin, It end) {
  26. return std::make_shared<detail::range_stream<It>>(begin, end);
  27. }
  28. /**
  29. * Construct a stream given certain start and end bounds.
  30. * e.g. stream::make_range_stream(0, 10)
  31. */
  32. template <typename T>
  33. detail::stream_base<T &> make_range_stream(T start, T const & end) {
  34. std::vector<T> vec;
  35. vec.reserve(end - start);
  36. while (end < start) {
  37. vec.emplace_back(start++);
  38. }
  39. return make_stream(std::move(vec));
  40. }
  41. /**
  42. * Construct a stream given certain start and end bounds, as well as an
  43. * increment amount. e.g. stream::make_range_stream(0, 10, 2)
  44. */
  45. template <typename T>
  46. detail::stream_base<T &> make_range_stream(T start, T const & end,
  47. T const & increment) {
  48. int elems{(end - start) / increment};
  49. if (elems < 0 || end == start) { return {}; }
  50. std::vector<T> vec{start};
  51. vec.reserve(elems + 1);
  52. while (elems-- > 0) {
  53. vec.emplace_back(start += increment);
  54. }
  55. return make_stream(std::move(vec));
  56. }
  57. }