Home | History | Annotate | Download | only in rxcpp
      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>
     50     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>
     57 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>>>
     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:
     78     operator_factory(tuple_type an)
     79         : an(std::move(an))
     80     {
     81     }
     82 
     83     template<class... ZN>
     84     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>
     90     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:
    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