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_SOURCES_RX_DEFER_HPP) 6 #define RXCPP_SOURCES_RX_DEFER_HPP 7 8 #include "../rx-includes.hpp" 9 10 /*! \file rx-defer.hpp 11 12 \brief Returns an observable that calls the specified observable factory to create an observable for each new observer that subscribes. 13 14 \tparam ObservableFactory the type of the observable factory 15 16 \param of the observable factory function to invoke for each observer that subscribes to the resulting observable 17 18 \return observable whose observers' subscriptions trigger an invocation of the given observable factory function 19 20 \sample 21 \snippet defer.cpp defer sample 22 \snippet output.txt defer sample 23 */ 24 25 namespace rxcpp { 26 27 namespace sources { 28 29 namespace detail { 30 31 template<class ObservableFactory> 32 struct defer_traits 33 { 34 typedef rxu::decay_t<ObservableFactory> observable_factory_type; 35 typedef decltype((*(observable_factory_type*)nullptr)()) collection_type; 36 typedef typename collection_type::value_type value_type; 37 }; 38 39 template<class ObservableFactory> 40 struct defer : public source_base<rxu::value_type_t<defer_traits<ObservableFactory>>> 41 { 42 typedef defer<ObservableFactory> this_type; 43 typedef defer_traits<ObservableFactory> traits; 44 45 typedef typename traits::observable_factory_type observable_factory_type; 46 typedef typename traits::collection_type collection_type; 47 48 observable_factory_type observable_factory; 49 deferrxcpp::sources::detail::defer50 defer(observable_factory_type of) 51 : observable_factory(std::move(of)) 52 { 53 } 54 template<class Subscriber> on_subscriberxcpp::sources::detail::defer55 void on_subscribe(Subscriber o) const { 56 57 auto selectedCollection = on_exception( 58 [this](){return this->observable_factory();}, 59 o); 60 if (selectedCollection.empty()) { 61 return; 62 } 63 64 selectedCollection->subscribe(o); 65 } 66 }; 67 68 } 69 70 /*! @copydoc rx-defer.hpp 71 */ 72 template<class ObservableFactory> defer(ObservableFactory of)73auto defer(ObservableFactory of) 74 -> observable<rxu::value_type_t<detail::defer_traits<ObservableFactory>>, detail::defer<ObservableFactory>> { 75 return observable<rxu::value_type_t<detail::defer_traits<ObservableFactory>>, detail::defer<ObservableFactory>>( 76 detail::defer<ObservableFactory>(std::move(of))); 77 } 78 79 } 80 81 } 82 83 #endif 84