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. ~iterator() {}
  11. value_type operator*() { return *impl_; }
  12. DELEGATE_ITERATOR_IMPL(impl_)
  13. private:
  14. Iter impl_;
  15. };
  16. template <typename C>
  17. using reference = decltype(*std::declval<C>().begin());
  18. }
  19. template <typename C>
  20. class source_stream : public stream_impl<source::reference<C>> {
  21. public:
  22. typedef source::reference<C> reference;
  23. typedef decltype(std::declval<C>().begin()) _iterator;
  24. explicit source_stream(C && cont) : source_(std::forward<C>(cont)) {}
  25. ~source_stream() override {}
  26. iterator<reference> begin() override { return {source::iterator<_iterator>{source_.begin()}}; }
  27. iterator<reference> end() override { return {source::iterator<_iterator>{source_.end()}}; }
  28. private:
  29. C source_;
  30. };
  31. template <typename It, typename V = typename It::value_type>
  32. class range_stream : public stream_impl<V &> {
  33. public:
  34. typedef V & reference;
  35. explicit range_stream(It b, It e) : begin_(b), end_(e) {}
  36. ~range_stream() override {}
  37. iterator<reference> begin() override { return {new source::iterator<It>{begin_}}; }
  38. iterator<reference> end() override { return {new source::iterator<It>{end_}}; }
  39. private:
  40. It begin_, end_;
  41. };
  42. }
  43. template <typename C>
  44. detail::stream_base<detail::source::reference<C>> make_stream(C && cont) {
  45. return {std::make_shared<detail::source_stream<C>>(cont)};
  46. }
  47. template <typename T>
  48. detail::stream_base<T&> make_stream(T * ptr) {
  49. return {std::make_shared<detail::range_stream<T*, T>>(ptr, ptr+1)};
  50. }
  51. template <typename It>
  52. detail::stream_base<typename It::reference> make_stream(It begin, It end) {
  53. return {std::make_shared<detail::range_stream<It>>(begin, end)};
  54. }
  55. }