ReactivePlusPlus
ReactiveX implementation for C++20
Loading...
Searching...
No Matches
fwd.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/disposables/fwd.hpp>
14#include <rpp/observers/details/fwd.hpp>
15
16#include <rpp/utils/constraints.hpp>
17#include <rpp/utils/function_traits.hpp>
18#include <rpp/utils/functors.hpp>
19#include <rpp/utils/utils.hpp>
20
21#include <exception>
22
23namespace rpp::constraint
24{
25 template<typename S>
26 concept observer_strategy_base = requires(const S& const_strategy, S& strategy, const rpp::disposable_wrapper& disposable) {
27 // const_strategy.on_next(v);
28 // const_strategy.on_next(std::move(mv));
29 const_strategy.on_error(std::exception_ptr{});
30 const_strategy.on_completed();
31
32 strategy.set_upstream(disposable);
33 {
34 strategy.is_disposed()
35 } -> std::same_as<bool>;
36 };
37
55 template<typename S, typename Type>
56 concept observer_strategy = observer_strategy_base<S> && requires(const S& const_strategy, const Type& v, Type& mv) {
57 const_strategy.on_next(v);
58 const_strategy.on_next(std::move(mv));
59
60 // strategy has to provide it's preferred disposable mode: minimal level of disposable logic it could work with.
61 // if observer_strategy fully controls disposable logic or just forwards disposable to downstream observer: rpp::details::observers::disposables_mode::None
62 // if you not sure about this field - just use rpp::details::observers::disposables_mode::Auto
63 { std::decay_t<S>::preferred_disposables_mode } -> rpp::constraint::decayed_same_as<rpp::details::observers::disposables_mode>; /* = rpp::details::observers::disposables_mode::Auto */
64 };
65} // namespace rpp::constraint
66
67namespace rpp::details::observers
68{
69 template<rpp::constraint::decayed_type Type>
71
73 std::invocable<Type> OnNext,
74 std::invocable<const std::exception_ptr&> OnError,
75 std::invocable<> OnCompleted>
76 struct lambda_strategy;
77
78 template<rpp::constraint::observer_strategy_base S, rpp::details::observers::constraint::disposables_strategy DisposableStrategy>
80 {
81 static constexpr auto preferred_disposables_mode = rpp::details::observers::disposables_mode::Auto;
82
84
85 consteval static void on_next(const auto&) noexcept {}
86 consteval static void on_error(const std::exception_ptr&) noexcept {}
87 consteval static void on_completed() noexcept {}
88
89 consteval static void set_upstream(const disposable_wrapper&) noexcept {}
90 consteval static bool is_disposed() noexcept { return false; }
91 };
92} // namespace rpp::details::observers
93namespace rpp
94{
95 template<constraint::decayed_type Type, constraint::observer_strategy<Type> Strategy>
96 class observer;
97
98 /*
99 * @brief Same as rpp::observer, but with passed rpp::composite_disposable_wrapper to constructor instead (as a result, it's possible to dispose observer early outside)
100 * @ingroup observers
101 */
102 template<constraint::decayed_type Type, constraint::observer_strategy<Type> Strategy>
104
105 template<constraint::decayed_type Type>
107
118 template<constraint::decayed_type Type, std::invocable<Type> OnNext, std::invocable<const std::exception_ptr&> OnError, std::invocable<> OnCompleted>
120
121 /*
122 * @brief Same as rpp::lambda_observer, but with passed rpp::composite_disposable_wrapper to constructor instead (as a result, it's possible to dispose observer early outside)
123 * @ingroup observers
124 */
125 template<constraint::decayed_type Type, std::invocable<Type> OnNext, std::invocable<const std::exception_ptr&> OnError, std::invocable<> OnCompleted>
127
138 template<constraint::decayed_type Type,
139 std::invocable<Type> OnNext,
140 std::invocable<const std::exception_ptr&> OnError = rpp::utils::rethrow_error_t,
141 std::invocable<> OnCompleted = rpp::utils::empty_function_t<>>
142 auto make_lambda_observer(OnNext&& on_next,
143 OnError&& on_error = {},
144 OnCompleted&& on_completed = {}) -> lambda_observer<Type,
145 std::decay_t<OnNext>,
146 std::decay_t<OnError>,
147 std::decay_t<OnCompleted>>;
148
160 template<constraint::decayed_type Type,
161 std::invocable<Type> OnNext,
162 std::invocable<const std::exception_ptr&> OnError = rpp::utils::rethrow_error_t,
163 std::invocable<> OnCompleted = rpp::utils::empty_function_t<>>
165 OnNext&& on_next,
166 OnError&& on_error = {},
167 OnCompleted&& on_completed = {}) -> lambda_observer_with_external_disposable<Type,
168 std::decay_t<OnNext>,
169 std::decay_t<OnError>,
170 std::decay_t<OnCompleted>>;
171
182 template<typename OnNext,
183 std::invocable<const std::exception_ptr&> OnError = rpp::utils::rethrow_error_t,
184 std::invocable<> OnCompleted = rpp::utils::empty_function_t<>,
185 constraint::decayed_type Type = rpp::utils::decayed_function_argument_t<OnNext>>
186 requires std::invocable<OnNext, Type>
187 auto make_lambda_observer(OnNext&& on_next,
188 OnError&& on_error = {},
189 OnCompleted&& on_completed = {})
190 {
191 return make_lambda_observer<Type>(std::forward<OnNext>(on_next), std::forward<OnError>(on_error), std::forward<OnCompleted>(on_completed));
192 }
193
206 template<typename OnNext,
207 std::invocable<const std::exception_ptr&> OnError = rpp::utils::rethrow_error_t,
208 std::invocable<> OnCompleted = rpp::utils::empty_function_t<>,
209 constraint::decayed_type Type = rpp::utils::decayed_function_argument_t<OnNext>>
210 requires std::invocable<OnNext, Type>
212 OnNext&& on_next,
213 OnError&& on_error = {},
214 OnCompleted&& on_completed = {})
215 {
216 return make_lambda_observer<Type>(d, std::forward<OnNext>(on_next), std::forward<OnError>(on_error), std::forward<OnCompleted>(on_completed));
217 }
218} // namespace rpp
219
220namespace rpp::details::observers
221{
223 {
224 static constexpr auto preferred_disposables_mode = rpp::details::observers::disposables_mode::None;
225
226 static void on_next(const auto&) noexcept {}
227
228 static void on_error(const std::exception_ptr&) noexcept {}
229
230 static void on_completed() noexcept {}
231
232 static void set_upstream(const disposable_wrapper&) noexcept {}
233
234 static bool is_disposed() noexcept { return true; }
235 };
236
237 template<typename T>
239} // namespace rpp::details::observers
240
241namespace rpp::utils
242{
243 template<typename T>
244 using extract_observer_type_t = typename rpp::utils::extract_base_type_params_t<T, rpp::observer>::template type_at_index_t<0>;
245} // namespace rpp::utils
246
247namespace rpp::constraint
248{
249 template<typename T>
251
252 template<typename T, typename Type>
253 concept observer_of_type = observer<std::decay_t<T>> && std::same_as<rpp::utils::extract_observer_type_t<std::decay_t<T>>, Type>;
254} // namespace rpp::constraint
Type-erased version of the rpp::observer. Any observer can be converted to dynamic_observer via rpp::...
Definition fwd.hpp:106
Base class for any observer used in RPP. It handles core callbacks of observers. Objects of this clas...
Definition observer.hpp:172
Definition constraints.hpp:19
Definition constraints.hpp:22
Definition fwd.hpp:253
Concept defines requirements for an user-defined observer strategy.
Definition fwd.hpp:56
Definition fwd.hpp:250
Definition utils.hpp:48
observer< Type, details::observers::lambda_strategy< Type, OnNext, OnError, OnCompleted > > lambda_observer
Observer specialized with passed callbacks. Most easiesest way to construct observer "on the fly" via...
Definition fwd.hpp:119
auto make_lambda_observer(OnNext &&on_next, OnError &&on_error={}, OnCompleted &&on_completed={}) -> lambda_observer< Type, std::decay_t< OnNext >, std::decay_t< OnError >, std::decay_t< OnCompleted > >
Constructs observer specialized with passed callbacks. Most easiesest way to construct observer "on t...
Definition lambda_observer.hpp:51
Definition lambda_observer.hpp:24
Definition functors.hpp:28
Definition functors.hpp:54