fluent.hpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. //
  2. // fluent.hpp
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 1/28/17.
  6. //
  7. #pragma once
  8. #include "../streams.hpp"
  9. #include <numeric>
  10. namespace stream {
  11. template <typename T, typename R>
  12. struct map {
  13. template <typename F>
  14. explicit map(F&& f) : func(f) {}
  15. std::function<R(const T&)> func;
  16. };
  17. template <typename T, typename R>
  18. struct flatmap {
  19. template <typename F>
  20. explicit flatmap(F&& f) : func(f) {}
  21. std::function<R(const T&)> func;
  22. };
  23. template <typename T>
  24. struct filter {
  25. template <typename F>
  26. explicit filter(F&& f) : pred(f) {}
  27. std::function<bool(const T&)> pred;
  28. };
  29. template <typename L, typename R = L>
  30. struct fold_left {
  31. template <typename F>
  32. explicit fold_left(F&& f, L const & i = L()) : init(i), fold(f) {}
  33. L init;
  34. std::function<L(const L&, const R&)> fold;
  35. };
  36. }
  37. namespace stream { namespace detail {
  38. template <typename T, typename R>
  39. stream_base<R> operator|(stream_base<T> const&s, ::stream::map<typename std::decay<T>::type, R>&& f) {
  40. return s.map(f.func);
  41. }
  42. template <typename T, typename C>
  43. stream_base<typename C::value_type> operator|(stream_base<T> const&s, ::stream::flatmap<typename std::decay<T>::type, C>&& f) {
  44. return s.flatmap(f.func);
  45. }
  46. template <typename T>
  47. stream_base<T> operator|(stream_base<T> const&s, ::stream::filter<typename std::decay<T>::type>&& f) {
  48. return s.filter(f.pred);
  49. }
  50. template <typename L, typename R>
  51. L operator >(stream_base<R> const &s, ::stream::fold_left<L, typename std::decay<R>::type> && f) {
  52. return std::accumulate(s.begin(), s.end(), f.init, f.fold);
  53. }
  54. template <typename T, typename C>
  55. C & operator >(stream_base<T> const & s, C & c) {
  56. s.collect(c);
  57. return c;
  58. }
  59. } }