25
25
#define RXCPP_OPERATORS_RX_REPEAT_HPP
26
26
27
27
#include " ../rx-includes.hpp"
28
+ #include " rx-retry-repeat-common.hpp"
28
29
29
30
namespace rxcpp {
30
31
@@ -44,147 +45,36 @@ using repeat_invalid_t = typename repeat_invalid<AN...>::type;
44
45
45
46
// Contain repeat variations in a namespace
46
47
namespace repeat {
47
- // Structure to perform general repeat operations on state
48
- template <class ValuesType , class Subscriber , class T >
49
- struct state_type : public std ::enable_shared_from_this<state_type<ValuesType, Subscriber, T>>,
50
- public ValuesType {
51
-
52
- typedef Subscriber output_type;
53
- state_type (const ValuesType& i, const output_type& oarg)
54
- : ValuesType(i),
55
- source_lifetime (composite_subscription::empty()),
56
- out(oarg) {
48
+ struct event_handlers {
49
+ template <typename State>
50
+ static inline void on_error (State& state, std::exception_ptr& e) {
51
+ state->out .on_error (e);
57
52
}
58
53
59
- void do_subscribe () {
60
- auto state = this ->shared_from_this ();
61
-
62
- state->out .remove (state->lifetime_token );
63
- state->source_lifetime .unsubscribe ();
64
-
65
- state->source_lifetime = composite_subscription ();
66
- state->lifetime_token = state->out .add (state->source_lifetime );
67
-
68
- state->source .subscribe (
69
- state->out ,
70
- state->source_lifetime ,
71
- // on_next
72
- [state](T t) {
73
- state->out .on_next (t);
74
- },
75
- // on_error
76
- [state](std::exception_ptr e) {
77
- state->out .on_error (e);
78
- },
79
- // on_completed
80
- [state]() {
81
- state->update ();
82
- // Use specialized predicate for finite/infinte case
83
- if (state->completed_predicate ()) {
84
- state->out .on_completed ();
85
- } else {
86
- state->do_subscribe ();
87
- }
88
- }
89
- );
90
- }
91
-
92
- composite_subscription source_lifetime;
93
- output_type out;
94
- composite_subscription::weak_subscription lifetime_token;
95
- };
96
-
97
- // Finite repeat case (explicitely limited with the number of times)
98
- template <class T , class Observable , class Count >
99
- struct finite : public operator_base <T> {
100
- typedef rxu::decay_t <Observable> source_type;
101
- typedef rxu::decay_t <Count> count_type;
102
-
103
- struct values {
104
- values (source_type s, count_type t)
105
- : source(std::move(s)),
106
- remaining_ (std::move(t)) {
107
- }
108
-
109
- inline bool completed_predicate () const {
110
- // Return true if we are completed
111
- return remaining_ <= 0 ;
112
- }
113
-
114
- inline void update () {
115
- // Decrement counter
116
- --remaining_;
117
- }
118
-
119
- source_type source;
120
-
121
- private:
122
- // Counter to hold number of times remaining to complete
123
- count_type remaining_;
124
- };
125
-
126
- finite (source_type s, count_type t)
127
- : initial_(std::move(s), std::move(t)) {
128
- }
129
-
130
- template <class Subscriber >
131
- void on_subscribe (const Subscriber& s) const {
132
- typedef state_type<values, Subscriber, T> state_t ;
133
- // take a copy of the values for each subscription
134
- auto state = std::make_shared<state_t >(initial_, s);
135
- if (initial_.completed_predicate ()) {
136
- // return completed
54
+ template <typename State>
55
+ static inline void on_completed (State& state) {
56
+ // Functions update() and completed_predicate() vary between finite and infinte versions
57
+ state->update ();
58
+ if (state->completed_predicate ()) {
137
59
state->out .on_completed ();
138
60
} else {
139
- // start the first iteration
140
61
state->do_subscribe ();
141
62
}
142
63
}
143
-
144
- private:
145
- values initial_;
146
64
};
147
65
66
+ // Finite repeat case (explicitely limited with the number of times)
67
+ template <class T , class Observable , class Count >
68
+ using finite = ::rxcpp::operators::detail::retry_repeat_common::finite
69
+ <event_handlers, T, Observable, Count>;
70
+
148
71
// Infinite repeat case
149
72
template <class T , class Observable >
150
- struct infinite : public operator_base <T> {
151
- typedef rxu::decay_t <Observable> source_type;
152
-
153
- struct values {
154
- values (source_type s)
155
- : source(std::move(s)) {
156
- }
157
-
158
- static inline bool completed_predicate () {
159
- // Infinite repeat never completes
160
- return false ;
161
- }
162
-
163
- static inline void update () {
164
- // Infinite repeat does not need to update state
165
- }
166
-
167
- source_type source;
168
- };
169
-
170
- infinite (source_type s) : initial_(std::move(s)) {
171
- }
172
-
173
- template <class Subscriber >
174
- void on_subscribe (const Subscriber& s) const {
175
- typedef state_type<values, Subscriber, T> state_t ;
176
- // take a copy of the values for each subscription
177
- auto state = std::make_shared<state_t >(initial_, s);
178
- // start the first iteration
179
- state->do_subscribe ();
180
- }
181
-
182
- private:
183
- values initial_;
184
- };
185
- }
73
+ using infinite = ::rxcpp::operators::detail::retry_repeat_common::infinite
74
+ <event_handlers, T, Observable>;
186
75
187
76
}
77
+ } // detail
188
78
189
79
/* ! @copydoc rx-repeat.hpp
190
80
*/
0 commit comments