accumulate.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. //
  2. // accumulate.h
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 3/29/23.
  6. //
  7. #pragma once
  8. #include <optional>
  9. #include <stream/detail/identity.h>
  10. #include <stream/detail/traits.h>
  11. #define FWD(x) std::forward<decltype(x)>(x)
  12. namespace stream::ranges {
  13. template <typename It, typename S, typename T, typename F>
  14. auto fold_left(It it, S end, T init, F reduce) {
  15. for (; it != end; ++it) {
  16. init = reduce(init, *it);
  17. }
  18. return init;
  19. }
  20. template <typename Stream, typename T, typename F>
  21. auto fold_left(Stream && stream, T init, F reduce) {
  22. for (auto && elem : FWD(stream)) {
  23. init = reduce(init, FWD(elem));
  24. }
  25. return init;
  26. }
  27. template <typename Stream, typename F>
  28. auto fold_left_with_first(Stream && stream, F reduce)
  29. -> std::optional<traits::value_type<Stream>> {
  30. if (stream.empty()) { return std::nullopt; }
  31. return fold_left(++stream.begin(), stream.end(), *stream.begin(), reduce);
  32. }
  33. template <typename Stream>
  34. auto first(Stream && stream) -> std::optional<traits::value_type<Stream>> {
  35. return stream.empty() ? std::nullopt : std::optional(*stream.begin());
  36. }
  37. template <typename It, typename S, typename Pred,
  38. typename Proj = detail::identity>
  39. bool any_of(It it, S end, Pred pred, Proj proj = {}) {
  40. for (; it != end; ++it) {
  41. if (pred(proj(*it))) { return true; }
  42. }
  43. return false;
  44. }
  45. template <typename Stream, typename Pred, typename Proj = detail::identity>
  46. bool any_of(Stream const & stream, Pred pred, Proj proj = {}) {
  47. return any_of(stream.begin(), stream.end(), pred, proj);
  48. }
  49. template <typename It, typename S, typename Pred,
  50. typename Proj = detail::identity>
  51. bool none_of(It it, S end, Pred pred, Proj proj = {}) {
  52. return !any_of(it, end, pred, proj);
  53. }
  54. template <typename Stream, typename Pred, typename Proj = detail::identity>
  55. bool none_of(Stream const & stream, Pred pred, Proj proj = {}) {
  56. return none_of(stream.begin(), stream.end(), pred, proj);
  57. }
  58. template <typename It, typename S, typename Pred,
  59. typename Proj = detail::identity>
  60. bool all_of(It it, S end, Pred pred, Proj proj = {}) {
  61. for (; it != end; ++it) {
  62. if (!pred(proj(*it))) { return false; }
  63. }
  64. return true;
  65. }
  66. template <typename Stream, typename Pred, typename Proj = detail::identity>
  67. bool all_of(Stream const & stream, Pred pred, Proj proj = {}) {
  68. return all_of(stream.begin(), stream.end(), pred, proj);
  69. }
  70. }
  71. #undef FWD