summaryrefslogtreecommitdiff
path: root/Rx/v2/src/rxcpp/operators/rx-subscribe.hpp
blob: 7488bdeb8f174a6b0967ff8d760ecd4e27676d97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

#pragma once

/*! \file rx-subscribe.hpp

    \brief Subscribe will cause the source observable to emit values to the provided subscriber.

    \tparam ArgN  types of the subscriber parameters

    \param an  the parameters for making a subscriber

    \return  A subscription with which the observer can stop receiving items before the observable has finished sending them.

    The arguments of subscribe are forwarded to rxcpp::make_subscriber function. Some possible alternatives are:

    - Pass an already composed rxcpp::subscriber:
    \snippet subscribe.cpp subscribe by subscriber
    \snippet output.txt subscribe by subscriber

    - Pass an rxcpp::observer. This allows subscribing the same subscriber to several observables:
    \snippet subscribe.cpp subscribe by observer
    \snippet output.txt subscribe by observer

    - Pass an `on_next` handler:
    \snippet subscribe.cpp subscribe by on_next
    \snippet output.txt subscribe by on_next

    - Pass `on_next` and `on_error` handlers:
    \snippet subscribe.cpp subscribe by on_next and on_error
    \snippet output.txt subscribe by on_next and on_error

    - Pass `on_next` and `on_completed` handlers:
    \snippet subscribe.cpp subscribe by on_next and on_completed
    \snippet output.txt subscribe by on_next and on_completed

    - Pass `on_next`, `on_error`, and `on_completed` handlers:
    \snippet subscribe.cpp subscribe by on_next, on_error, and on_completed
    \snippet output.txt subscribe by on_next, on_error, and on_completed
    .

    All the alternatives above also support passing rxcpp::composite_subscription instance. For example:
    \snippet subscribe.cpp subscribe by subscription, on_next, and on_completed
    \snippet output.txt subscribe by subscription, on_next, and on_completed

    If neither subscription nor subscriber are provided, then a new subscription is created and returned as a result:
    \snippet subscribe.cpp subscribe unsubscribe
    \snippet output.txt subscribe unsubscribe

    For more details, see rxcpp::make_subscriber function description.
*/

#if !defined(RXCPP_OPERATORS_RX_SUBSCRIBE_HPP)
#define RXCPP_OPERATORS_RX_SUBSCRIBE_HPP

#include "../rx-includes.hpp"

namespace rxcpp {

namespace operators {

namespace detail {

template<class Subscriber>
class subscribe_factory;

template<class T, class I>
class subscribe_factory<subscriber<T, I>>
{
    subscriber<T, I> scrbr;
public:
    subscribe_factory(subscriber<T, I> s)
        : scrbr(std::move(s))
    {}
    template<class Observable>
    auto operator()(Observable&& source)
        -> decltype(std::forward<Observable>(source).subscribe(std::move(scrbr))) {
        return      std::forward<Observable>(source).subscribe(std::move(scrbr));
    }
};

}

template<class T, class Arg0>
auto subscribe(Arg0&& a0)
    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0)))> {
    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0)))>
                                        (make_subscriber<T>(std::forward<Arg0>(a0)));
}
template<class T, class Arg0, class Arg1>
auto subscribe(Arg0&& a0, Arg1&& a1)
    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1)))> {
    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1)))>
                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1)));
}
template<class T, class Arg0, class Arg1, class Arg2>
auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2)
    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))> {
    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))>
                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)));
}
template<class T, class Arg0, class Arg1, class Arg2, class Arg3>
auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3)
    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))> {
    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))>
                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)));
}
template<class T, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4>
auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4)
    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)))> {
    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)))>
                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)));
}
template<class T, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4, Arg5&& a5)
    ->      detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)))> {
    return  detail::subscribe_factory<decltype  (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)))>
                                        (make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)));
}

namespace detail {

class dynamic_factory
{
public:
    template<class Observable>
    auto operator()(Observable&& source)
        ->      observable<rxu::value_type_t<rxu::decay_t<Observable>>> {
        return  observable<rxu::value_type_t<rxu::decay_t<Observable>>>(std::forward<Observable>(source));
    }
};

}

inline auto as_dynamic()
    ->      detail::dynamic_factory {
    return  detail::dynamic_factory();
}

}

}

#endif