source.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. namespace stream {
  3. namespace detail {
  4. namespace source {
  5. template <typename Iter> class iterator {
  6. public:
  7. using value_type = typename std::iterator_traits<Iter>::reference;
  8. explicit iterator(Iter it) : impl_(it) {}
  9. value_type operator*() { return *impl_; }
  10. DELEGATE_ITERATOR_IMPL(impl_)
  11. private:
  12. Iter impl_;
  13. };
  14. template <typename C>
  15. using reference = decltype(*std::declval<C>().begin());
  16. }
  17. template <typename C> class source_stream {
  18. public:
  19. typedef source::reference<C> reference;
  20. typedef decltype(std::declval<C>().begin()) _iterator;
  21. explicit source_stream(C && cont) : source_(std::forward<C>(cont)) {}
  22. iterator<reference> begin() {
  23. return {source::iterator<_iterator>{source_.begin()}};
  24. }
  25. iterator<reference> end() {
  26. return {source::iterator<_iterator>{source_.end()}};
  27. }
  28. private:
  29. C source_;
  30. };
  31. template <typename It, typename V = typename It::value_type>
  32. class range_stream {
  33. public:
  34. typedef V & reference;
  35. explicit range_stream(It b, It e) : begin_(b), end_(e) {}
  36. iterator<reference> begin() { return {source::iterator<It>{begin_}}; }
  37. iterator<reference> end() { return {source::iterator<It>{end_}}; }
  38. private:
  39. It begin_, end_;
  40. };
  41. }
  42. template <typename C>
  43. detail::stream_base<detail::source::reference<C>> make_stream(C && cont) {
  44. return std::make_shared<detail::source_stream<C>>(std::forward<C>(cont));
  45. }
  46. template <typename T> detail::stream_base<T &> make_stream(T * ptr) {
  47. return std::make_shared<detail::range_stream<T *, T &>>(ptr, ptr + 1);
  48. }
  49. template <typename It>
  50. detail::stream_base<typename It::reference> make_stream(It begin, It end) {
  51. return std::make_shared<detail::range_stream<It>>(begin, end);
  52. }
  53. template <typename T>
  54. detail::stream_base<T &> make_range_stream(T start, T const & end) {
  55. std::vector<T> vec;
  56. vec.reserve(end - start);
  57. while (end < start) {
  58. vec.emplace_back(start++);
  59. }
  60. return make_stream(std::move(vec));
  61. }
  62. template <typename T>
  63. detail::stream_base<T &> make_range_stream(T start, T const & end,
  64. T const & increment) {
  65. int elems{(end - start) / increment};
  66. if (elems < 0 || end == start) { return {}; }
  67. std::vector<T> vec{start};
  68. vec.reserve(elems + 1);
  69. while (elems-- > 0) {
  70. vec.emplace_back(start += increment);
  71. }
  72. return make_stream(std::move(vec));
  73. }
  74. }