source.hpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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 : public stream_impl<source::reference<C>> {
  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. ~source_stream() override {}
  25. iterator<reference> begin() override { return {source::iterator<_iterator>{source_.begin()}}; }
  26. iterator<reference> end() override { return {source::iterator<_iterator>{source_.end()}}; }
  27. private:
  28. C source_;
  29. };
  30. template <typename It, typename V = typename It::value_type>
  31. class range_stream : public stream_impl<V &> {
  32. public:
  33. typedef V & reference;
  34. explicit range_stream(It b, It e) : begin_(b), end_(e) {}
  35. ~range_stream() override {}
  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>>(cont)};
  45. }
  46. template <typename T>
  47. detail::stream_base<T&> make_stream(T * ptr) {
  48. return {std::make_shared<detail::range_stream<T*, T>>(ptr, ptr+1)};
  49. }
  50. template <typename It>
  51. detail::stream_base<typename It::reference> make_stream(It begin, It end) {
  52. return {std::make_shared<detail::range_stream<It>>(begin, end)};
  53. }
  54. }