then.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include <rpl/producer.h>
  9. namespace rpl {
  10. namespace details {
  11. template <typename Value, typename Error, typename Generator>
  12. class then_helper {
  13. public:
  14. then_helper(producer<Value, Error, Generator> &&following)
  15. : _following(std::move(following)) {
  16. }
  17. template <
  18. typename OtherValue,
  19. typename OtherError,
  20. typename OtherGenerator,
  21. typename NewValue = superset_type_t<Value, OtherValue>,
  22. typename NewError = superset_type_t<Error, OtherError>>
  23. auto operator()(
  24. producer<OtherValue, OtherError, OtherGenerator> &&initial
  25. ) {
  26. return make_producer<NewValue, NewError>([
  27. initial = std::move(initial),
  28. following = std::move(_following)
  29. ](const auto &consumer) mutable {
  30. return std::move(initial).start(
  31. [consumer](auto &&value) {
  32. consumer.put_next_forward(
  33. std::forward<decltype(value)>(value));
  34. }, [consumer](auto &&error) {
  35. consumer.put_error_forward(
  36. std::forward<decltype(error)>(error));
  37. }, [
  38. consumer,
  39. following = std::move(following)
  40. ]() mutable {
  41. consumer.add_lifetime(std::move(following).start(
  42. [consumer](auto &&value) {
  43. consumer.put_next_forward(
  44. std::forward<decltype(value)>(value));
  45. }, [consumer](auto &&error) {
  46. consumer.put_error_forward(
  47. std::forward<decltype(error)>(error));
  48. }, [consumer] {
  49. consumer.put_done();
  50. }));
  51. });
  52. });
  53. }
  54. private:
  55. producer<Value, Error, Generator> _following;
  56. };
  57. } // namespace details
  58. template <typename Value, typename Error, typename Generator>
  59. inline auto then(producer<Value, Error, Generator> &&following)
  60. -> details::then_helper<Value, Error, Generator> {
  61. return { std::move(following) };
  62. }
  63. } // namespace rpl