RxCpp
The Reactive Extensions for Native (RxCpp) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators in both C and C++.
rx-finally.hpp
Go to the documentation of this file.
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 
24 #if !defined(RXCPP_OPERATORS_RX_FINALLY_HPP)
25 #define RXCPP_OPERATORS_RX_FINALLY_HPP
26 
27 #include "../rx-includes.hpp"
28 
29 namespace rxcpp {
30 
31 namespace operators {
32 
33 namespace detail {
34 
35 template<class... AN>
36 struct finally_invalid_arguments {};
37 
38 template<class... AN>
39 struct finally_invalid : public rxo::operator_base<finally_invalid_arguments<AN...>> {
40  using type = observable<finally_invalid_arguments<AN...>, finally_invalid<AN...>>;
41 };
42 template<class... AN>
43 using finally_invalid_t = typename finally_invalid<AN...>::type;
44 
45 template<class T, class LastCall>
46 struct finally
47 {
48  typedef rxu::decay_t<T> source_value_type;
49  typedef rxu::decay_t<LastCall> last_call_type;
50  last_call_type last_call;
51 
52  finally(last_call_type lc)
53  : last_call(std::move(lc))
54  {
55  }
56 
57  template<class Subscriber>
58  struct finally_observer
59  {
60  typedef finally_observer<Subscriber> this_type;
61  typedef source_value_type value_type;
62  typedef rxu::decay_t<Subscriber> dest_type;
63  typedef observer<value_type, this_type> observer_type;
64  dest_type dest;
65 
66  finally_observer(dest_type d)
67  : dest(std::move(d))
68  {
69  }
70  void on_next(source_value_type v) const {
71  dest.on_next(v);
72  }
73  void on_error(std::exception_ptr e) const {
74  dest.on_error(e);
75  }
76  void on_completed() const {
77  dest.on_completed();
78  }
79 
80  static subscriber<value_type, observer_type> make(dest_type d, const last_call_type& lc) {
81  auto dl = d.get_subscription();
82  composite_subscription cs;
83  dl.add(cs);
84  cs.add([=](){
85  dl.unsubscribe();
86  lc();
87  });
88  return make_subscriber<value_type>(cs, this_type(d));
89  }
90  };
91 
92  template<class Subscriber>
93  auto operator()(Subscriber dest) const
94  -> decltype(finally_observer<Subscriber>::make(std::move(dest), last_call)) {
95  return finally_observer<Subscriber>::make(std::move(dest), last_call);
96  }
97 };
98 
99 }
100 
103 template<class... AN>
104 auto finally(AN&&... an)
106  return operator_factory<finally_tag, AN...>(std::make_tuple(std::forward<AN>(an)...));
107 }
108 
109 }
110 
111 template<>
113 {
114  template<class Observable, class LastCall,
115  class SourceValue = rxu::value_type_t<Observable>,
116  class Enabled = rxu::enable_if_all_true_type_t<
118  class Finally = rxo::detail::finally<SourceValue, rxu::decay_t<LastCall>>>
119  static auto member(Observable&& o, LastCall&& lc)
120  -> decltype(o.template lift<SourceValue>(Finally(std::forward<LastCall>(lc)))) {
121  return o.template lift<SourceValue>(Finally(std::forward<LastCall>(lc)));
122  }
123 
124  template<class... AN>
125  static operators::detail::finally_invalid_t<AN...> member(const AN&...) {
126  std::terminate();
127  return {};
128  static_assert(sizeof...(AN) == 10000, "finally takes (LastCall)");
129  }
130 };
131 
132 }
133 
134 #endif
Definition: rx-all.hpp:26
typename std::decay< T >::type::value_type value_type_t
Definition: rx-util.hpp:35
static auto member(Observable &&o, LastCall &&lc) -> decltype(o.template lift< SourceValue >(Finally(std::forward< LastCall >(lc))))
Definition: rx-finally.hpp:119
Definition: rx-operators.hpp:69
auto AN
Definition: rx-finally.hpp:105
Definition: rx-operators.hpp:47
typename std::enable_if< all_true_type< BN... >::value >::type enable_if_all_true_type_t
Definition: rx-util.hpp:114
Definition: rx-operators.hpp:220
static operators::detail::finally_invalid_t< AN... > member(const AN &...)
Definition: rx-finally.hpp:125
Definition: rx-predef.hpp:177
auto finally(AN &&...an) -> operator_factory< final ly_tag
Add a new action at the end of the new observable that is returned.