make_stream.hpp 1.9 KB

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