fluent.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. namespace stream { namespace traits {
  10. template <typename T, typename P>
  11. using is_filter =
  12. std::is_same<bool, decltype(std::declval<P>()(std::declval<T>()))>;
  13. template <typename C, typename T, typename = void>
  14. struct is_collection : public std::false_type {};
  15. template <typename C, typename T>
  16. struct is_collection<C, T,
  17. typename std::enable_if<std::is_constructible<
  18. typename C::value_type, T>::value>::type>
  19. : public std::true_type {};
  20. }}
  21. namespace stream { namespace detail {
  22. template <typename T, typename F>
  23. auto operator||(stream_base<T> const & s, F && f) -> decltype(s.flatmap(f)) {
  24. return s.flatmap(f);
  25. }
  26. template <typename T, typename F>
  27. auto operator|(stream_base<T> const & s, F && f) -> decltype(s.map(f)) {
  28. return s.map(f);
  29. }
  30. template <
  31. typename T, typename P,
  32. typename = typename std::enable_if<traits::is_filter<T, P>::value>::type>
  33. stream_base<T> operator%(stream_base<T> const & s, P && f) {
  34. return s.filter(f);
  35. }
  36. template <typename R> R operator>(stream_base<R> const & s, R const & val) {
  37. return s.accumulate(val);
  38. }
  39. template <typename L, typename R, typename F>
  40. L operator>(stream_base<R> const & s, std::pair<L, F> const & pair) {
  41. return s.accumulate(pair.second, pair.first);
  42. }
  43. template <typename T, typename F,
  44. typename = typename std::enable_if<
  45. !traits::is_collection<F, T>::value>::type>
  46. typename std::decay<T>::type operator>(stream_base<T> const & s, F && f) {
  47. return s.accumulate(f, typename std::decay<T>::type());
  48. }
  49. template <typename T, typename C,
  50. typename = typename std::enable_if<
  51. traits::is_collection<C, T>::value>::type>
  52. C & operator>(stream_base<T> const & s, C & c) {
  53. s.collect(c);
  54. return c;
  55. }
  56. }}