ReactivePlusPlus
One more implementation of ReactiveX approach in C++ with care about performance and templates in mind
 
Loading...
Searching...
No Matches
lift.hpp
1// ReactivePlusPlus library
2//
3// Copyright Aleksey Loginov 2022 - present.
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
6// https://www.boost.org/LICENSE_1_0.txt)
7//
8// Project home: https://github.com/victimsnino/ReactivePlusPlus
9//
10
11#pragma once
12
13#include <rpp/observables/details/member_overload.hpp> // member_overload
14#include <rpp/subscribers/constraints.hpp> // constraint::subscriber
15#include <rpp/utils/function_traits.hpp> // extract_subscriber_type_t
16#include <rpp/utils/functors.hpp> // forwarding_on_error
17
18namespace rpp::details
19{
20struct lift_tag;
21}
22
23namespace rpp::details
24{
25template<typename T, typename NewType>
27
28template<constraint::decayed_type Type, constraint::decayed_type OnNext, constraint::decayed_type OnError, constraint::decayed_type OnCompleted>
29struct lift_action_by_callbacks;
30
31template<typename... Types>
32using decayed_lift_action_by_callbacks = lift_action_by_callbacks<std::decay_t<Types>...>;
33
34template<constraint::decayed_type NewType, lift_fn<NewType> OperatorFn, typename TObs>
35auto lift_impl(OperatorFn&& op, TObs&& _this);
36
37template<constraint::decayed_type Type, typename SpecificObservable>
38struct member_overload<Type, SpecificObservable, lift_tag>
39{
46 template<constraint::decayed_type NewType>
47 auto lift(lift_fn<NewType> auto&& op) const& requires is_header_included<lift_tag, NewType>
48 {
49 return details::lift_impl<NewType>(std::forward<decltype(op)>(op), CastThis());
50 }
51
52 template<constraint::decayed_type NewType>
53 auto lift(lift_fn<NewType> auto&& op)&& requires is_header_included<lift_tag, NewType>
54 {
55 return details::lift_impl<NewType>(std::forward<decltype(op)>(op), MoveThis());
56 }
57
58 // ********************************* LIFT OPERATOR: SUBSCRIBER -> SUBSCRIBER ******************//
66 template<typename OperatorFn,
67 constraint::decayed_type NewType = utils::extract_subscriber_type_t<utils::function_argument_t<OperatorFn>>>
68 auto lift(OperatorFn&& op) const& requires (details::lift_fn<OperatorFn, NewType> && is_header_included<lift_tag, OperatorFn, NewType>)
69 {
70 return details::lift_impl<NewType>(std::forward<decltype(op)>(op), CastThis());
71 }
72 template<typename OperatorFn,
73 constraint::decayed_type NewType = utils::extract_subscriber_type_t<utils::function_argument_t<OperatorFn>>>
74 auto lift(OperatorFn&& op) && requires (details::lift_fn<OperatorFn, NewType> && is_header_included<lift_tag, OperatorFn, NewType>)
75 {
76 return details::lift_impl<NewType>(std::forward<decltype(op)>(op), MoveThis());
77 }
78
79 // ********************************* LIFT Direct type + OnNext, Onerror, OnCompleted ******************//
80
90 template<constraint::decayed_type NewType,
91 std::invocable<Type, dynamic_subscriber<NewType>> OnNext,
92 std::invocable<std::exception_ptr, dynamic_subscriber<NewType>> OnError = utils::forwarding_on_error,
93 std::invocable<dynamic_subscriber<NewType>> OnCompleted = utils::forwarding_on_completed>
94 auto lift(OnNext&& on_next, OnError&& on_error = {}, OnCompleted&& on_completed = {}) const& requires is_header_included<lift_tag, NewType, OnNext, OnError, OnCompleted>
95 {
96 return details::lift_impl<NewType>(details::decayed_lift_action_by_callbacks<Type, OnNext, OnError, OnCompleted>{std::forward<OnNext>(on_next),
97 std::forward<OnError>(on_error),
98 std::forward<OnCompleted>(on_completed)},
99 CastThis());
100 }
101
102 template<constraint::decayed_type NewType,
103 std::invocable<Type, dynamic_subscriber<NewType>> OnNext,
104 std::invocable<std::exception_ptr, dynamic_subscriber<NewType>> OnError = utils::forwarding_on_error,
105 std::invocable<dynamic_subscriber<NewType>> OnCompleted = utils::forwarding_on_completed>
106 auto lift(OnNext&& on_next, OnError&& on_error = {}, OnCompleted&& on_completed = {})&& requires is_header_included<lift_tag, NewType, OnNext, OnError, OnCompleted>
107 {
108 return details::lift_impl<NewType>(details::decayed_lift_action_by_callbacks<Type, OnNext, OnError, OnCompleted>{std::forward<OnNext>(on_next),
109 std::forward<OnError>(on_error),
110 std::forward<OnCompleted>(on_completed)},
111 MoveThis());
112 }
113
114 // ********************************* LIFT OnNext, Onerror, OnCompleted ******************//
115
124 template<typename OnNext,
125 constraint::decayed_type NewType = utils::extract_subscriber_type_t<std::decay_t<utils::function_argument_t<OnNext, 1>>>,
126 std::invocable<std::exception_ptr, dynamic_subscriber<NewType>> OnError = utils::forwarding_on_error,
127 std::invocable<dynamic_subscriber<NewType>> OnCompleted = utils::forwarding_on_completed>
128 requires std::invocable<OnNext, Type, dynamic_subscriber<NewType>>
129 auto lift(OnNext&& on_next, OnError&& on_error = {}, OnCompleted&& on_completed = {}) const& requires is_header_included<lift_tag, NewType, OnNext, OnError, OnCompleted>
130 {
131 return details::lift_impl<NewType>(details::decayed_lift_action_by_callbacks<Type, OnNext, OnError, OnCompleted>{std::forward<OnNext>(on_next),
132 std::forward<OnError>(on_error),
133 std::forward<OnCompleted>(on_completed)},
134 CastThis());
135 }
136
137 template<typename OnNext,
138 constraint::decayed_type NewType = utils::extract_subscriber_type_t<std::decay_t<utils::function_argument_t<OnNext, 1>>>,
139 std::invocable<std::exception_ptr, dynamic_subscriber<NewType>> OnError = utils::forwarding_on_error,
140 std::invocable<dynamic_subscriber<NewType>> OnCompleted = utils::forwarding_on_completed>
141 requires std::invocable<OnNext, Type, dynamic_subscriber<NewType>>
142 auto lift(OnNext&& on_next, OnError&& on_error = {}, OnCompleted&& on_completed = {})&& requires is_header_included<lift_tag, NewType, OnNext, OnError, OnCompleted>
143 {
144 return details::lift_impl<NewType>(details::decayed_lift_action_by_callbacks<Type, OnNext, OnError, OnCompleted>{std::forward<OnNext>(on_next),
145 std::forward<OnError>(on_error),
146 std::forward<OnCompleted>(on_completed)},
147 MoveThis());
148 }
149
150private:
151 const SpecificObservable& CastThis() const
152 {
153 return *static_cast<const SpecificObservable*>(this);
154 }
155
156 SpecificObservable&& MoveThis()
157 {
158 return std::move(*static_cast<SpecificObservable*>(this));
159 }
160};
161} // namespace rpp::details
Definition: constraints.hpp:19
Definition: lift.hpp:26
auto lift(lift_fn< NewType > auto &&op) const &
The lift operator provides ability to create your own operator and apply it to observable.
Definition: lift.hpp:47
auto lift(OnNext &&on_next, OnError &&on_error={}, OnCompleted &&on_completed={}) const &is_header_included< lift_tag
The lift operator provides ability to create your own operator and apply it to observable.
auto lift(OnNext &&on_next, OnError &&on_error={}, OnCompleted &&on_completed={}) const &
The lift operator provides ability to create your own operator and apply it to observable.
Definition: lift.hpp:94
auto lift(OperatorFn &&op) const &
The lift operator provides ability to create your own operator and apply it to observable.
Definition: lift.hpp:68
Definition: member_overload.hpp:19