• 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_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)73 auto 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