fluent.hpp 1.9 KB

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