source.hpp 2.6 KB

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