• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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