fluent.hpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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 <
  27. typename T, typename F,
  28. typename = typename std::enable_if<!traits::is_filter<T, F>::value>::type>
  29. auto operator|(stream_base<T> const & s, F && f) -> decltype(s.map(f)) {
  30. return s.map(f);
  31. }
  32. template <
  33. typename T, typename P,
  34. typename = typename std::enable_if<traits::is_filter<T, P>::value>::type>
  35. stream_base<T> operator|(stream_base<T> const & s, P && f) {
  36. return s.filter(f);
  37. }
  38. template <typename R> R operator>(stream_base<R> const & s, R const & val) {
  39. return s.accumulate(val);
  40. }
  41. template <typename L, typename R, typename F>
  42. L operator>(stream_base<R> const & s, std::pair<L, F> const & pair) {
  43. return s.accumulate(pair.second, pair.first);
  44. }
  45. template <typename T, typename F,
  46. typename = typename std::enable_if<
  47. !traits::is_collection<F, T>::value>::type>
  48. typename std::decay<T>::type operator>(stream_base<T> const & s, F && f) {
  49. return s.accumulate(f, typename std::decay<T>::type());
  50. }
  51. template <typename T, typename C,
  52. typename = typename std::enable_if<
  53. traits::is_collection<C, T>::value>::type>
  54. C & operator>(stream_base<T> const & s, C & c) {
  55. s.collect(c);
  56. return c;
  57. }
  58. }}