1 // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
2
3 #pragma once
4
5 #if !defined(RXCPP_RX_OPERATORS_HPP)
6 #define RXCPP_RX_OPERATORS_HPP
7
8 #include "rx-includes.hpp"
9
10 namespace rxcpp {
11
12 namespace operators {
13
14 struct tag_operator {};
15 template<class T>
16 struct operator_base
17 {
18 typedef T value_type;
19 typedef tag_operator operator_tag;
20 };
21
22 namespace detail {
23
24 template<class T, class =rxu::types_checked>
25 struct is_operator : std::false_type
26 {
27 };
28
29 template<class T>
30 struct is_operator<T, rxu::types_checked_t<typename T::operator_tag>>
31 : std::is_convertible<typename T::operator_tag*, tag_operator*>
32 {
33 };
34
35 }
36
37 template<class T, class Decayed = rxu::decay_t<T>>
38 struct is_operator : detail::is_operator<Decayed>
39 {
40 };
41
42
43 }
44 namespace rxo=operators;
45
46 template<class Tag>
47 struct member_overload
48 {
49 template<class... AN>
memberrxcpp::member_overload50 static auto member(AN&&...) ->
51 typename Tag::template include_header<std::false_type> {
52 return typename Tag::template include_header<std::false_type>();
53 }
54 };
55
56 template<class T, class... AN>
valuerxcpp::delayed_type57 struct delayed_type{using value_type = T; static T value(AN**...) {return T{};}};
58
59 template<class T, class... AN>
60 using delayed_type_t = rxu::value_type_t<delayed_type<T, AN...>>;
61
62 template<class Tag, class... AN, class Overload = member_overload<rxu::decay_t<Tag>>>
observable_member(Tag,AN &&...an)63 auto observable_member(Tag, AN&&... an) ->
64 decltype(Overload::member(std::forward<AN>(an)...)) {
65 return Overload::member(std::forward<AN>(an)...);
66 }
67
68 template<class Tag, class... AN>
69 class operator_factory
70 {
71 using this_type = operator_factory<Tag, AN...>;
72 using tag_type = rxu::decay_t<Tag>;
73 using tuple_type = std::tuple<rxu::decay_t<AN>...>;
74
75 tuple_type an;
76
77 public:
operator_factory(tuple_type an)78 operator_factory(tuple_type an)
79 : an(std::move(an))
80 {
81 }
82
83 template<class... ZN>
operator ()(tag_type t,ZN &&...zn) const84 auto operator()(tag_type t, ZN&&... zn) const
85 -> decltype(observable_member(t, std::forward<ZN>(zn)...)) {
86 return observable_member(t, std::forward<ZN>(zn)...);
87 }
88
89 template<class Observable>
operator ()(Observable source) const90 auto operator()(Observable source) const
91 -> decltype(rxu::apply(std::tuple_cat(std::make_tuple(tag_type{}, source), (*(tuple_type*)nullptr)), (*(this_type*)nullptr))) {
92 return rxu::apply(std::tuple_cat(std::make_tuple(tag_type{}, source), an), *this);
93 }
94 };
95
96 }
97
98 #include "operators/rx-lift.hpp"
99 #include "operators/rx-subscribe.hpp"
100
101 namespace rxcpp {
102
103 struct amb_tag {
104 template<class Included>
105 struct include_header{
106 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-amb.hpp>");
107 };
108 };
109
110 struct all_tag {
111 template<class Included>
112 struct include_header{
113 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-all.hpp>");
114 };
115 };
116
117 struct is_empty_tag : all_tag {};
118
119 struct any_tag {
120 template<class Included>
121 struct include_header{
122 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-any.hpp>");
123 };
124 };
125
126 struct exists_tag : any_tag {};
127 struct contains_tag : any_tag {};
128
129 struct buffer_count_tag {
130 template<class Included>
131 struct include_header{
132 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_count.hpp>");
133 };
134 };
135
136 struct buffer_with_time_tag {
137 template<class Included>
138 struct include_header{
139 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_time.hpp>");
140 };
141 };
142
143 struct buffer_with_time_or_count_tag {
144 template<class Included>
145 struct include_header{
146 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_time_count.hpp>");
147 };
148 };
149
150 struct combine_latest_tag {
151 template<class Included>
152 struct include_header{
153 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-combine_latest.hpp>");
154 };
155 };
156
157 struct concat_tag {
158 template<class Included>
159 struct include_header{
160 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-concat.hpp>");
161 };
162 };
163
164 struct concat_map_tag {
165 template<class Included>
166 struct include_header{
167 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-concat_map.hpp>");
168 };
169 };
170
171 struct connect_forever_tag {
172 template<class Included>
173 struct include_header{
174 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-connect_forever.hpp>");
175 };
176 };
177
178 struct debounce_tag {
179 template<class Included>
180 struct include_header{
181 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-debounce.hpp>");
182 };
183 };
184
185 struct delay_tag {
186 template<class Included>
187 struct include_header{
188 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-delay.hpp>");
189 };
190 };
191
192 struct distinct_tag {
193 template<class Included>
194 struct include_header{
195 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-distinct.hpp>");
196 };
197 };
198
199 struct distinct_until_changed_tag {
200 template<class Included>
201 struct include_header{
202 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-distinct_until_changed.hpp>");
203 };
204 };
205
206 struct element_at_tag {
207 template<class Included>
208 struct include_header{
209 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-element_at.hpp>");
210 };
211 };
212
213 struct filter_tag {
214 template<class Included>
215 struct include_header{
216 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-filter.hpp>");
217 };
218 };
219
220 struct finally_tag {
221 template<class Included>
222 struct include_header{
223 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-finally.hpp>");
224 };
225 };
226
227 struct flat_map_tag {
228 template<class Included>
229 struct include_header{
230 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-flat_map.hpp>");
231 };
232 };
233
234 struct group_by_tag {
235 template<class Included>
236 struct include_header{
237 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-group_by.hpp>");
238 };
239 };
240
241 struct ignore_elements_tag {
242 template<class Included>
243 struct include_header{
244 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-ignore_elements.hpp>");
245 };
246 };
247
248 struct map_tag {
249 template<class Included>
250 struct include_header{
251 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-map.hpp>");
252 };
253 };
254
255 struct merge_tag {
256 template<class Included>
257 struct include_header{
258 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-merge.hpp>");
259 };
260 };
261 struct merge_delay_error_tag {
262 template<class Included>
263 struct include_header{
264 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-merge_delay_error.hpp>");
265 };
266 };
267
268 struct multicast_tag {
269 template<class Included>
270 struct include_header{
271 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-multicast.hpp>");
272 };
273 };
274
275 struct observe_on_tag {
276 template<class Included>
277 struct include_header{
278 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-observe_on.hpp>");
279 };
280 };
281
282 struct on_error_resume_next_tag {
283 template<class Included>
284 struct include_header{
285 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-on_error_resume_next.hpp>");
286 };
287 };
288
289 class empty_error: public std::runtime_error
290 {
291 public:
empty_error(const std::string & msg)292 explicit empty_error(const std::string& msg):
293 std::runtime_error(msg)
294 {}
295 };
296 struct reduce_tag {
297 template<class Included>
298 struct include_header{
299 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-reduce.hpp>");
300 };
301 };
302 struct first_tag : reduce_tag {};
303 struct last_tag : reduce_tag {};
304 struct sum_tag : reduce_tag {};
305 struct average_tag : reduce_tag {};
306 struct min_tag : reduce_tag {};
307 struct max_tag : reduce_tag {};
308
309 struct ref_count_tag {
310 template<class Included>
311 struct include_header{
312 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-ref_count.hpp>");
313 };
314 };
315
316 struct pairwise_tag {
317 template<class Included>
318 struct include_header{
319 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-pairwise.hpp>");
320 };
321 };
322
323 struct publish_tag {
324 template<class Included>
325 struct include_header{
326 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-publish.hpp>");
327 };
328 };
329 struct publish_synchronized_tag : publish_tag {};
330
331 struct repeat_tag {
332 template<class Included>
333 struct include_header{
334 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-repeat.hpp>");
335 };
336 };
337
338 struct replay_tag {
339 template<class Included>
340 struct include_header{
341 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-replay.hpp>");
342 };
343 };
344
345 struct retry_tag {
346 template<class Included>
347 struct include_header{
348 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-retry.hpp>");
349 };
350 };
351
352 struct sample_with_time_tag {
353 template<class Included>
354 struct include_header{
355 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-sample_time.hpp>");
356 };
357 };
358
359 struct scan_tag {
360 template<class Included>
361 struct include_header{
362 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-scan.hpp>");
363 };
364 };
365
366 struct sequence_equal_tag {
367 template<class Included>
368 struct include_header{
369 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-sequence_equal.hpp>");
370 };
371 };
372
373 struct skip_tag {
374 template<class Included>
375 struct include_header{
376 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip.hpp>");
377 };
378 };
379
380 struct skip_while_tag {
381 template<class Included>
382 struct include_header{
383 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_while.hpp>");
384 };
385 };
386
387 struct skip_last_tag {
388 template<class Included>
389 struct include_header{
390 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_last.hpp>");
391 };
392 };
393
394 struct skip_until_tag {
395 template<class Included>
396 struct include_header{
397 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_until.hpp>");
398 };
399 };
400
401 struct start_with_tag {
402 template<class Included>
403 struct include_header{
404 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-start_with.hpp>");
405 };
406 };
407
408 struct subscribe_on_tag {
409 template<class Included>
410 struct include_header{
411 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-subscribe_on.hpp>");
412 };
413 };
414
415 struct switch_if_empty_tag {
416 template<class Included>
417 struct include_header{
418 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-switch_if_empty.hpp>");
419 };
420 };
421 struct default_if_empty_tag : switch_if_empty_tag {};
422
423 struct switch_on_next_tag {
424 template<class Included>
425 struct include_header{
426 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-switch_on_next.hpp>");
427 };
428 };
429
430 struct take_tag {
431 template<class Included>
432 struct include_header{
433 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take.hpp>");
434 };
435 };
436
437 struct take_last_tag {
438 template<class Included>
439 struct include_header{
440 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_last.hpp>");
441 };
442 };
443
444 struct take_while_tag {
445 template<class Included>
446 struct include_header{
447 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_while.hpp>");
448 };
449 };
450
451 struct take_until_tag {
452 template<class Included>
453 struct include_header{
454 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_until.hpp>");
455 };
456 };
457
458 struct tap_tag {
459 template<class Included>
460 struct include_header{
461 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-rap.hpp>");
462 };
463 };
464
465 struct timeout_tag {
466 template<class Included>
467 struct include_header{
468 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-timeout.hpp>");
469 };
470 };
471
472 struct time_interval_tag {
473 template<class Included>
474 struct include_header{
475 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-time_interval.hpp>");
476 };
477 };
478
479 struct timestamp_tag {
480 template<class Included>
481 struct include_header{
482 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-timestamp.hpp>");
483 };
484 };
485
486 struct window_tag {
487 template<class Included>
488 struct include_header{
489 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window.hpp>");
490 };
491 };
492
493 struct window_with_time_tag {
494 template<class Included>
495 struct include_header{
496 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_time.hpp>");
497 };
498 };
499
500 struct window_with_time_or_count_tag {
501 template<class Included>
502 struct include_header{
503 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_time_count.hpp>");
504 };
505 };
506
507 struct window_toggle_tag {
508 template<class Included>
509 struct include_header{
510 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_toggle.hpp>");
511 };
512 };
513
514 struct with_latest_from_tag {
515 template<class Included>
516 struct include_header{
517 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-with_latest_from.hpp>");
518 };
519 };
520
521 struct zip_tag {
522 template<class Included>
523 struct include_header{
524 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-zip.hpp>");
525 };
526 };
527
528 }
529
530 #include "operators/rx-multicast.hpp"
531 #include "operators/rx-publish.hpp"
532 #include "operators/rx-ref_count.hpp"
533
534 #endif
535