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-predef.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 
5 #if !defined(RXCPP_RX_PREDEF_HPP)
6 #define RXCPP_RX_PREDEF_HPP
7 
8 #include "rx-includes.hpp"
9 
10 namespace rxcpp {
11 
12 //
13 // create a typedef for rxcpp_trace_type to override the default
14 //
15 inline auto trace_activity() -> decltype(rxcpp_trace_activity(trace_tag()))& {
16  static decltype(rxcpp_trace_activity(trace_tag())) trace;
17  return trace;
18 }
19 
20 
21 struct tag_action {};
22 template<class T, class C = rxu::types_checked>
23 struct is_action : public std::false_type {};
24 
25 template<class T>
26 struct is_action<T, typename rxu::types_checked_from<typename T::action_tag>::type>
27  : public std::is_convertible<typename T::action_tag*, tag_action*> {};
28 
29 
30 struct tag_worker {};
31 template<class T>
32 class is_worker
33 {
34  struct not_void {};
35  template<class C>
36  static typename C::worker_tag* check(int);
37  template<class C>
38  static not_void check(...);
39 public:
40  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_worker*>::value;
41 };
42 
43 struct tag_scheduler {};
44 template<class T>
46 {
47  struct not_void {};
48  template<class C>
49  static typename C::scheduler_tag* check(int);
50  template<class C>
51  static not_void check(...);
52 public:
53  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_scheduler*>::value;
54 };
55 
56 struct tag_schedulable {};
57 template<class T>
59 {
60  struct not_void {};
61  template<class C>
62  static typename C::schedulable_tag* check(int);
63  template<class C>
64  static not_void check(...);
65 public:
66  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_schedulable*>::value;
67 };
68 
69 namespace detail
70 {
71 
72 struct stateless_observer_tag {};
73 
74 }
75 
76 // state with optional overrides
77 template<class T, class State = void, class OnNext = void, class OnError = void, class OnCompleted = void>
78 class observer;
79 
80 // no state with optional overrides
81 template<class T, class OnNext, class OnError, class OnCompleted>
82 class observer<T, detail::stateless_observer_tag, OnNext, OnError, OnCompleted>;
83 
84 // virtual functions forward to dynamically allocated shared observer instance.
85 template<class T>
86 class observer<T, void, void, void, void>;
87 
88 struct tag_observer {};
89 template<class T>
91 {
92  template<class C>
93  static typename C::observer_tag* check(int);
94  template<class C>
95  static void check(...);
96 public:
97  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_observer*>::value;
98 };
99 
101 template<class T>
103 {
104  struct not_void {};
105  template<class C>
106  static typename C::dynamic_observer_tag* check(int);
107  template<class C>
108  static not_void check(...);
109 public:
110  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_dynamic_observer*>::value;
111 };
112 
113 struct tag_subscriber {};
114 template<class T>
116 {
117  struct not_void {};
118  template<class C>
119  static typename C::subscriber_tag* check(int);
120  template<class C>
121  static not_void check(...);
122 public:
123  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_subscriber*>::value;
124 };
125 
127 template<class T>
129 {
130  struct not_void {};
131  template<class C>
132  static typename C::dynamic_observable_tag* check(int);
133  template<class C>
134  static not_void check(...);
135 public:
136  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_dynamic_observable*>::value;
137 };
138 
139 template<class T>
140 class dynamic_observable;
141 
142 template<
143  class T = void,
144  class SourceObservable = typename std::conditional<std::is_same<T, void>::value,
145  void, dynamic_observable<T>>::type>
146 class observable;
147 
148 template<class T, class Source>
150 
151 template<class Selector, class Default, template<class... TN> class SO, class... AN>
152 struct defer_observable;
153 
154 struct tag_observable {};
155 template<class T>
158  typedef T value_type;
159 };
160 
161 namespace detail {
162 
163 template<class T, class =rxu::types_checked>
164 struct is_observable : std::false_type
165 {
166 };
167 
168 template<class T>
169 struct is_observable<T, rxu::types_checked_t<typename T::observable_tag>>
170  : std::is_convertible<typename T::observable_tag*, tag_observable*>
171 {
172 };
173 
174 }
175 
176 template<class T, class Decayed = rxu::decay_t<T>>
177 struct is_observable : detail::is_observable<Decayed>
178 {
179 };
180 
181 template<class Observable, class DecayedObservable = rxu::decay_t<Observable>>
182 using observable_tag_t = typename DecayedObservable::observable_tag;
183 
184 // extra indirection for vs2013 support
185 template<class Types, class =rxu::types_checked>
186 struct expand_observable_tags { struct type; };
187 template<class... ObservableN>
188 struct expand_observable_tags<rxu::types<ObservableN...>, rxu::types_checked_t<typename ObservableN::observable_tag...>>
189 {
190  using type = rxu::types<typename ObservableN::observable_tag...>;
191 };
192 template<class... ObservableN>
193 using observable_tags_t = typename expand_observable_tags<rxu::types<ObservableN...>>::type;
194 
195 template<class... ObservableN>
197 
199 
200 template<class T>
202 {
203  struct not_void {};
204  template<class C>
205  static typename C::dynamic_observable_tag* check(int);
206  template<class C>
207  static not_void check(...);
208 public:
209  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_dynamic_connectable_observable*>::value;
210 };
211 
212 template<class T>
214 
215 template<class T,
216  class SourceObservable = typename std::conditional<std::is_same<T, void>::value,
219 
221 template<class T>
223 {
224  template<class C>
225  static typename C::observable_tag check(int);
226  template<class C>
227  static void check(...);
228 public:
229  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_connectable_observable>::value;
230 };
231 
233 
234 template<class T>
236 {
237  struct not_void {};
238  template<class C>
239  static typename C::dynamic_observable_tag* check(int);
240  template<class C>
241  static not_void check(...);
242 public:
243  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_dynamic_grouped_observable*>::value;
244 };
245 
246 template<class K, class T>
248 
249 template<class K, class T,
250  class SourceObservable = typename std::conditional<std::is_same<T, void>::value,
252 class grouped_observable;
253 
254 template<class K, class T, class Source>
256 
258 template<class T>
260 {
261  template<class C>
262  static typename C::observable_tag check(int);
263  template<class C>
264  static void check(...);
265 public:
266  static const bool value = std::is_convertible<decltype(check<rxu::decay_t<T>>(0)), tag_grouped_observable>::value;
267 };
268 
269 template<class Source, class Function>
273 
274 // check methods instead of void_t for vs2013 support
275 
276  struct tag_not_valid;
277  template<class CS, class CO>
278  static auto check(int) -> decltype((*(CS*)nullptr)((*(CO*)nullptr)));
279  template<class CS, class CO>
280  static tag_not_valid check(...);
281 
282  using type = decltype(check<function_type, source_type>(0));
283 
284  static const bool value = !std::is_same<type, tag_not_valid>::value && is_observable<source_type>::value;
285 };
286 
287 //
288 // this type is the default used by operators that subscribe to
289 // multiple sources. It assumes that the sources are already synchronized
290 //
292 {
293  template<class Observable>
294  auto operator()(Observable o)
295  -> Observable {
296  return std::move(o);
297  static_assert(is_observable<Observable>::value, "only support observables");
298  }
299 };
300 
301 template<class T>
303 {
304  T operator()(T t) {
305  return std::move(t);
306  }
307 };
308 
309 template<class T, class Seed, class Accumulator>
311 
314  typedef T source_value_type;
315 
316  struct tag_not_valid {};
317  template<class CS, class CV, class CRS>
318  static auto check(int) -> decltype((*(CRS*)nullptr)(*(CS*)nullptr, *(CV*)nullptr));
319  template<class CS, class CV, class CRS>
320  static tag_not_valid check(...);
321 
322  typedef decltype(check<seed_type, source_value_type, accumulator_type>(0)) type;
323  static const bool value = std::is_same<type, seed_type>::value;
324 };
325 
326 }
327 
328 #endif
Definition: rx-predef.hpp:220
Definition: rx-grouped_observable.hpp:30
Definition: rx-predef.hpp:88
Definition: rx-util.hpp:100
a source of values that is shared across all subscribers and does not start until connectable_observa...
Definition: rx-connectable_observable.hpp:105
a source of observables which each emit values from one category specified by the key selector...
Definition: rx-grouped_observable.hpp:121
Definition: rx-observable.hpp:157
Definition: rx-all.hpp:26
Definition: rx-predef.hpp:302
Definition: rx-predef.hpp:23
typename expand_observable_tags< rxu::types< ObservableN... >>::type observable_tags_t
Definition: rx-predef.hpp:193
Definition: rx-predef.hpp:113
auto AN
Definition: rx-finally.hpp:105
Definition: rx-predef.hpp:222
Definition: rx-predef.hpp:156
Definition: rx-predef.hpp:201
tag_observable observable_tag
Definition: rx-predef.hpp:157
Definition: rx-predef.hpp:291
typename std::decay< T >::type decay_t
Definition: rx-util.hpp:36
Definition: rx-predef.hpp:100
auto operator()(Observable o) -> Observable
Definition: rx-predef.hpp:294
auto rxcpp_trace_activity(...) -> rxcpp::trace_noop
Definition: rx-predef.hpp:232
rxu::decay_t< Source > source_type
Definition: rx-predef.hpp:272
Definition: rx-predef.hpp:21
rxu::decay_t< Function > function_type
Definition: rx-predef.hpp:271
Definition: rx-predef.hpp:30
Definition: rx-observable.hpp:36
Definition: rx-predef.hpp:235
T value_type
Definition: rx-predef.hpp:158
grouped_observable< K, T > make_dynamic_grouped_observable(Source &&s)
Definition: rx-grouped_observable.hpp:108
observable< T > make_observable_dynamic(Source &&s)
Definition: rx-observable.hpp:102
Definition: rx-predef.hpp:58
typename DecayedObservable::observable_tag observable_tag_t
Definition: rx-predef.hpp:182
a source of values. subscribe or use one of the operator methods that return a new observable...
Definition: rx-observable.hpp:510
Definition: rx-util.hpp:147
Definition: rx-predef.hpp:32
auto trace_activity() -> decltype(rxcpp_trace_activity(trace_tag()))&
Definition: rx-predef.hpp:15
Definition: rx-predef.hpp:198
rxu::decay_t< Accumulator > accumulator_type
Definition: rx-predef.hpp:312
Definition: rx-connectable_observable.hpp:30
Definition: rx-predef.hpp:154
Definition: rx-predef.hpp:257
Definition: rx-predef.hpp:270
Definition: rx-predef.hpp:310
typename types_checked_from< TN... >::type types_checked_t
Definition: rx-util.hpp:164
Definition: rx-trace.hpp:107
consumes values from an observable using State that may implement on_next, on_error and on_completed ...
Definition: rx-observer.hpp:179
T source_value_type
Definition: rx-predef.hpp:314
Definition: rx-predef.hpp:56
Definition: rx-predef.hpp:186
decltype(check< function_type, source_type >(0)) type
Definition: rx-predef.hpp:282
Definition: rx-predef.hpp:128
Definition: rx-predef.hpp:90
rxu::decay_t< Seed > seed_type
Definition: rx-predef.hpp:313
Definition: rx-predef.hpp:102
Definition: rx-predef.hpp:115
Definition: rx-predef.hpp:43
Definition: rx-predef.hpp:259
Definition: rx-predef.hpp:126
Definition: rx-predef.hpp:45
T operator()(T t)
Definition: rx-predef.hpp:304
Definition: rx-predef.hpp:177