ReactivePlusPlus
ReactiveX implementation for C++20
Toggle main menu visibility
Loading...
Searching...
No Matches
on_error_resume_next.hpp
1
// ReactivePlusPlus library
2
//
3
// Copyright Aleksey Loginov 2023 - 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/AlexInLog/ReactivePlusPlus
9
//
10
11
#pragma once
12
13
#include <rpp/operators/fwd.hpp>
14
15
#include <rpp/defs.hpp>
16
#include <rpp/operators/details/strategy.hpp>
17
18
namespace
rpp::operators::details
19
{
20
template
<rpp::constra
int
::observer TObserver>
21
struct
on_error_resume_next_disposable final :
public
rpp::composite_disposable
22
{
23
on_error_resume_next_disposable(TObserver&& observer)
24
:
rpp::composite_disposable
{}
25
, observer(std::move(observer))
26
{
27
}
28
29
RPP_NO_UNIQUE_ADDRESS TObserver observer;
30
};
31
32
template
<rpp::constra
int
::observer TObserver>
33
struct
on_error_resume_next_inner_observer_strategy
34
{
35
static
constexpr
auto
preferred_disposables_mode = rpp::details::observers::disposables_mode::None;
36
37
std::shared_ptr<TObserver> observer;
38
39
template
<
typename
T>
40
void
on_next(T&& v)
const
41
{
42
observer->on_next(std::forward<T>(v));
43
}
44
45
void
on_error(
const
std::exception_ptr& err)
const
46
{
47
observer->on_error(err);
48
}
49
50
void
on_completed()
const
51
{
52
observer->on_completed();
53
}
54
55
void
set_upstream(
const
disposable_wrapper
& d) { observer->set_upstream(d); }
56
57
bool
is_disposed()
const
{
return
observer->is_disposed(); }
58
};
59
60
61
template
<rpp::constra
int
::observer TObserver, rpp::constra
int
::decayed_type Selector>
62
struct
on_error_resume_next_observer_strategy
63
{
64
static
constexpr
auto
preferred_disposables_mode = rpp::details::observers::disposables_mode::None;
65
66
on_error_resume_next_observer_strategy(TObserver&&
observer
,
const
Selector& selector)
67
: state{init_state(std::move(
observer
))}
68
, selector{selector}
69
{
70
}
71
72
std::shared_ptr<on_error_resume_next_disposable<TObserver>> state;
73
RPP_NO_UNIQUE_ADDRESS Selector selector;
74
75
template
<
typename
T>
76
void
on_next(T&& v)
const
77
{
78
state->observer.on_next(std::forward<T>(v));
79
}
80
81
void
on_error(
const
std::exception_ptr& err)
const
82
{
83
try
84
{
85
selector(err).subscribe(
on_error_resume_next_inner_observer_strategy<TObserver>
{std::shared_ptr<TObserver>(state, &state->observer)});
86
}
87
catch
(...)
88
{
89
state->observer.on_error(std::current_exception());
90
}
91
state->dispose();
92
}
93
94
void
on_completed()
const
95
{
96
state->observer.on_completed();
97
}
98
99
void
set_upstream(
const
disposable_wrapper
& d)
const
100
{
101
state->add(d);
102
}
103
104
bool
is_disposed()
const
{
return
state->is_disposed(); }
105
106
static
std::shared_ptr<on_error_resume_next_disposable<TObserver>> init_state(TObserver&&
observer
)
107
{
108
const
auto
d =
disposable_wrapper_impl<on_error_resume_next_disposable<TObserver>
>::make(std::move(
observer
));
109
auto
ptr = d.lock();
110
ptr->observer.set_upstream(d.as_weak());
111
return
ptr;
112
}
113
};
114
115
template
<rpp::constra
int
::decayed_type Selector>
116
struct
on_error_resume_next_t
: lift_operator<on_error_resume_next_t<Selector>, Selector>
117
{
118
using
lift_operator<
on_error_resume_next_t<Selector>
, Selector>::lift_operator;
119
120
template
<rpp::constra
int
::decayed_type T>
121
struct
operator_traits
122
{
123
using
selector_observable_result_type =
124
rpp::utils::extract_observable_type_t<std::invoke_result_t<Selector, std::exception_ptr>>;
125
126
static_assert
(
127
rpp::constraint::decayed_same_as<selector_observable_result_type, T>
,
128
"Selector observable result type is not the same as T"
);
129
130
using
result_type = T;
131
132
template
<rpp::constra
int
::observer_of_type<result_type> TObserver>
133
using
observer_strategy =
on_error_resume_next_observer_strategy<TObserver, Selector>
;
134
};
135
136
template
<rpp::details::observables::constra
int
::disposables_strategy Prev>
137
using
updated_optimal_disposables_strategy = rpp::details::observables::default_disposables_strategy;
138
};
139
}
// namespace rpp::operators::details
140
141
namespace
rpp::operators
142
{
157
* @see https://reactivex.io/documentation/operators/catch.html
158
*/
159
template
<
typename
Selector>
160
requires
rpp::constraint::observable<std::invoke_result_t<Selector, std::exception_ptr>
>
161
auto
on_error_resume_next
(Selector&& selector)
162
{
163
return
details::on_error_resume_next_t<std::decay_t<Selector>
>{std::forward<Selector>(selector)};
164
}
165
}
// namespace rpp::operators
rpp::composite_disposable
Disposable which can keep some other sub-disposables. When this root disposable is disposed,...
Definition
composite_disposable.hpp:175
rpp::disposable_wrapper_impl
Main RPP wrapper over disposables.
Definition
disposable_wrapper.hpp:142
rpp::observer
Base class for any observer used in RPP. It handles core callbacks of observers. Objects of this clas...
Definition
observer.hpp:172
rpp::constraint::decayed_same_as
Definition
constraints.hpp:19
rpp::constraint::observable
Definition
fwd.hpp:80
rpp::disposable_wrapper
disposable_wrapper_impl< interface_disposable > disposable_wrapper
Wrapper to keep "simple" disposable. Specialization of rpp::disposable_wrapper_impl.
Definition
fwd.hpp:34
rpp::operators::on_error_resume_next
auto on_error_resume_next(Selector &&selector)
If an error occurs, take the result from the Selector and subscribe to that instead.
Definition
on_error_resume_next.hpp:157
rpp::operators::details::on_error_resume_next_inner_observer_strategy
Definition
on_error_resume_next.hpp:34
rpp::operators::details::on_error_resume_next_observer_strategy
Definition
on_error_resume_next.hpp:63
rpp::operators::details::on_error_resume_next_t::operator_traits
Definition
on_error_resume_next.hpp:122
rpp::operators::details::on_error_resume_next_t
Definition
on_error_resume_next.hpp:117
src
rpp
rpp
operators
on_error_resume_next.hpp
Generated by
1.17.0