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 /*! \file rx-subscribe.hpp 6 7 \brief Subscribe will cause the source observable to emit values to the provided subscriber. 8 9 \tparam ArgN types of the subscriber parameters 10 11 \param an the parameters for making a subscriber 12 13 \return A subscription with which the observer can stop receiving items before the observable has finished sending them. 14 15 The arguments of subscribe are forwarded to rxcpp::make_subscriber function. Some possible alternatives are: 16 17 - Pass an already composed rxcpp::subscriber: 18 \snippet subscribe.cpp subscribe by subscriber 19 \snippet output.txt subscribe by subscriber 20 21 - Pass an rxcpp::observer. This allows subscribing the same subscriber to several observables: 22 \snippet subscribe.cpp subscribe by observer 23 \snippet output.txt subscribe by observer 24 25 - Pass an `on_next` handler: 26 \snippet subscribe.cpp subscribe by on_next 27 \snippet output.txt subscribe by on_next 28 29 - Pass `on_next` and `on_error` handlers: 30 \snippet subscribe.cpp subscribe by on_next and on_error 31 \snippet output.txt subscribe by on_next and on_error 32 33 - Pass `on_next` and `on_completed` handlers: 34 \snippet subscribe.cpp subscribe by on_next and on_completed 35 \snippet output.txt subscribe by on_next and on_completed 36 37 - Pass `on_next`, `on_error`, and `on_completed` handlers: 38 \snippet subscribe.cpp subscribe by on_next, on_error, and on_completed 39 \snippet output.txt subscribe by on_next, on_error, and on_completed 40 . 41 42 All the alternatives above also support passing rxcpp::composite_subscription instance. For example: 43 \snippet subscribe.cpp subscribe by subscription, on_next, and on_completed 44 \snippet output.txt subscribe by subscription, on_next, and on_completed 45 46 If neither subscription nor subscriber are provided, then a new subscription is created and returned as a result: 47 \snippet subscribe.cpp subscribe unsubscribe 48 \snippet output.txt subscribe unsubscribe 49 50 For more details, see rxcpp::make_subscriber function description. 51 */ 52 53 #if !defined(RXCPP_OPERATORS_RX_SUBSCRIBE_HPP) 54 #define RXCPP_OPERATORS_RX_SUBSCRIBE_HPP 55 56 #include "../rx-includes.hpp" 57 58 namespace rxcpp { 59 60 namespace operators { 61 62 namespace detail { 63 64 template<class Subscriber> 65 class subscribe_factory; 66 67 template<class T, class I> 68 class subscribe_factory<subscriber<T, I>> 69 { 70 subscriber<T, I> scrbr; 71 public: 72 subscribe_factory(subscriber<T, I> s) 73 : scrbr(std::move(s)) 74 {} 75 template<class Observable> 76 auto operator()(Observable&& source) 77 -> decltype(std::forward<Observable>(source).subscribe(std::move(scrbr))) { 78 return std::forward<Observable>(source).subscribe(std::move(scrbr)); 79 } 80 }; 81 82 } 83 84 /*! @copydoc rx-subscribe.hpp 85 */ 86 template<class T, class... ArgN> 87 auto subscribe(ArgN&&... an) 88 -> detail::subscribe_factory<decltype (make_subscriber<T>(std::forward<ArgN>(an)...))> { 89 return detail::subscribe_factory<decltype (make_subscriber<T>(std::forward<ArgN>(an)...))> 90 (make_subscriber<T>(std::forward<ArgN>(an)...)); 91 } 92 93 namespace detail { 94 95 class dynamic_factory 96 { 97 public: 98 template<class Observable> 99 auto operator()(Observable&& source) 100 -> observable<rxu::value_type_t<rxu::decay_t<Observable>>> { 101 return observable<rxu::value_type_t<rxu::decay_t<Observable>>>(std::forward<Observable>(source)); 102 } 103 }; 104 105 } 106 107 /*! Return a new observable that performs type-forgetting conversion of this observable. 108 109 \return The source observable converted to observable<T>. 110 111 \note This operator could be useful to workaround lambda deduction bug on msvc 2013. 112 113 \sample 114 \snippet as_dynamic.cpp as_dynamic sample 115 \snippet output.txt as_dynamic sample 116 */ 117 inline auto as_dynamic() 118 -> detail::dynamic_factory { 119 return detail::dynamic_factory(); 120 } 121 122 namespace detail { 123 124 class blocking_factory 125 { 126 public: 127 template<class Observable> 128 auto operator()(Observable&& source) 129 -> decltype(std::forward<Observable>(source).as_blocking()) { 130 return std::forward<Observable>(source).as_blocking(); 131 } 132 }; 133 134 } 135 136 /*! Return a new observable that contains the blocking methods for this observable. 137 138 \return An observable that contains the blocking methods for this observable. 139 140 \sample 141 \snippet from.cpp threaded from sample 142 \snippet output.txt threaded from sample 143 */ 144 inline auto as_blocking() 145 -> detail::blocking_factory { 146 return detail::blocking_factory(); 147 } 148 149 150 } 151 152 } 153 154 #endif 155