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_OPERATORS_HPP) 6 #define RXCPP_RX_OPERATORS_HPP 7 8 #include "rx-includes.hpp" 9 10 namespace rxcpp { 11 12 namespace operators { 13 14 struct tag_operator {}; 15 template<class T> 16 struct operator_base 17 { 18 typedef T value_type; 19 typedef tag_operator operator_tag; 20 }; 21 22 namespace detail { 23 24 template<class T, class =rxu::types_checked> 25 struct is_operator : std::false_type 26 { 27 }; 28 29 template<class T> 30 struct is_operator<T, rxu::types_checked_t<typename T::operator_tag>> 31 : std::is_convertible<typename T::operator_tag*, tag_operator*> 32 { 33 }; 34 35 } 36 37 template<class T, class Decayed = rxu::decay_t<T>> 38 struct is_operator : detail::is_operator<Decayed> 39 { 40 }; 41 42 43 } 44 namespace rxo=operators; 45 46 template<class Tag> 47 struct member_overload 48 { 49 template<class... AN> 50 static auto member(AN&&...) -> 51 typename Tag::template include_header<std::false_type> { 52 return typename Tag::template include_header<std::false_type>(); 53 } 54 }; 55 56 template<class T, class... AN> 57 struct delayed_type{using value_type = T; static T value(AN**...) {return T{};}}; 58 59 template<class T, class... AN> 60 using delayed_type_t = rxu::value_type_t<delayed_type<T, AN...>>; 61 62 template<class Tag, class... AN, class Overload = member_overload<rxu::decay_t<Tag>>> 63 auto observable_member(Tag, AN&&... an) -> 64 decltype(Overload::member(std::forward<AN>(an)...)) { 65 return Overload::member(std::forward<AN>(an)...); 66 } 67 68 template<class Tag, class... AN> 69 class operator_factory 70 { 71 using this_type = operator_factory<Tag, AN...>; 72 using tag_type = rxu::decay_t<Tag>; 73 using tuple_type = std::tuple<rxu::decay_t<AN>...>; 74 75 tuple_type an; 76 77 public: 78 operator_factory(tuple_type an) 79 : an(std::move(an)) 80 { 81 } 82 83 template<class... ZN> 84 auto operator()(tag_type t, ZN&&... zn) const 85 -> decltype(observable_member(t, std::forward<ZN>(zn)...)) { 86 return observable_member(t, std::forward<ZN>(zn)...); 87 } 88 89 template<class Observable> 90 auto operator()(Observable source) const 91 -> decltype(rxu::apply(std::tuple_cat(std::make_tuple(tag_type{}, source), (*(tuple_type*)nullptr)), (*(this_type*)nullptr))) { 92 return rxu::apply(std::tuple_cat(std::make_tuple(tag_type{}, source), an), *this); 93 } 94 }; 95 96 } 97 98 #include "operators/rx-lift.hpp" 99 #include "operators/rx-subscribe.hpp" 100 101 namespace rxcpp { 102 103 struct amb_tag { 104 template<class Included> 105 struct include_header{ 106 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-amb.hpp>"); 107 }; 108 }; 109 110 struct all_tag { 111 template<class Included> 112 struct include_header{ 113 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-all.hpp>"); 114 }; 115 }; 116 117 struct is_empty_tag : all_tag {}; 118 119 struct any_tag { 120 template<class Included> 121 struct include_header{ 122 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-any.hpp>"); 123 }; 124 }; 125 126 struct exists_tag : any_tag {}; 127 struct contains_tag : any_tag {}; 128 129 struct buffer_count_tag { 130 template<class Included> 131 struct include_header{ 132 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_count.hpp>"); 133 }; 134 }; 135 136 struct buffer_with_time_tag { 137 template<class Included> 138 struct include_header{ 139 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_time.hpp>"); 140 }; 141 }; 142 143 struct buffer_with_time_or_count_tag { 144 template<class Included> 145 struct include_header{ 146 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-buffer_time_count.hpp>"); 147 }; 148 }; 149 150 struct combine_latest_tag { 151 template<class Included> 152 struct include_header{ 153 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-combine_latest.hpp>"); 154 }; 155 }; 156 157 struct concat_tag { 158 template<class Included> 159 struct include_header{ 160 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-concat.hpp>"); 161 }; 162 }; 163 164 struct concat_map_tag { 165 template<class Included> 166 struct include_header{ 167 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-concat_map.hpp>"); 168 }; 169 }; 170 171 struct connect_forever_tag { 172 template<class Included> 173 struct include_header{ 174 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-connect_forever.hpp>"); 175 }; 176 }; 177 178 struct debounce_tag { 179 template<class Included> 180 struct include_header{ 181 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-debounce.hpp>"); 182 }; 183 }; 184 185 struct delay_tag { 186 template<class Included> 187 struct include_header{ 188 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-delay.hpp>"); 189 }; 190 }; 191 192 struct distinct_tag { 193 template<class Included> 194 struct include_header{ 195 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-distinct.hpp>"); 196 }; 197 }; 198 199 struct distinct_until_changed_tag { 200 template<class Included> 201 struct include_header{ 202 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-distinct_until_changed.hpp>"); 203 }; 204 }; 205 206 struct element_at_tag { 207 template<class Included> 208 struct include_header{ 209 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-element_at.hpp>"); 210 }; 211 }; 212 213 struct filter_tag { 214 template<class Included> 215 struct include_header{ 216 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-filter.hpp>"); 217 }; 218 }; 219 220 struct finally_tag { 221 template<class Included> 222 struct include_header{ 223 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-finally.hpp>"); 224 }; 225 }; 226 227 struct flat_map_tag { 228 template<class Included> 229 struct include_header{ 230 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-flat_map.hpp>"); 231 }; 232 }; 233 234 struct group_by_tag { 235 template<class Included> 236 struct include_header{ 237 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-group_by.hpp>"); 238 }; 239 }; 240 241 struct ignore_elements_tag { 242 template<class Included> 243 struct include_header{ 244 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-ignore_elements.hpp>"); 245 }; 246 }; 247 248 struct map_tag { 249 template<class Included> 250 struct include_header{ 251 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-map.hpp>"); 252 }; 253 }; 254 255 struct merge_tag { 256 template<class Included> 257 struct include_header{ 258 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-merge.hpp>"); 259 }; 260 }; 261 struct merge_delay_error_tag { 262 template<class Included> 263 struct include_header{ 264 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-merge_delay_error.hpp>"); 265 }; 266 }; 267 268 struct multicast_tag { 269 template<class Included> 270 struct include_header{ 271 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-multicast.hpp>"); 272 }; 273 }; 274 275 struct observe_on_tag { 276 template<class Included> 277 struct include_header{ 278 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-observe_on.hpp>"); 279 }; 280 }; 281 282 struct on_error_resume_next_tag { 283 template<class Included> 284 struct include_header{ 285 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-on_error_resume_next.hpp>"); 286 }; 287 }; 288 289 class empty_error: public std::runtime_error 290 { 291 public: 292 explicit empty_error(const std::string& msg): 293 std::runtime_error(msg) 294 {} 295 }; 296 struct reduce_tag { 297 template<class Included> 298 struct include_header{ 299 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-reduce.hpp>"); 300 }; 301 }; 302 struct first_tag : reduce_tag {}; 303 struct last_tag : reduce_tag {}; 304 struct sum_tag : reduce_tag {}; 305 struct average_tag : reduce_tag {}; 306 struct min_tag : reduce_tag {}; 307 struct max_tag : reduce_tag {}; 308 309 struct ref_count_tag { 310 template<class Included> 311 struct include_header{ 312 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-ref_count.hpp>"); 313 }; 314 }; 315 316 struct pairwise_tag { 317 template<class Included> 318 struct include_header{ 319 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-pairwise.hpp>"); 320 }; 321 }; 322 323 struct publish_tag { 324 template<class Included> 325 struct include_header{ 326 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-publish.hpp>"); 327 }; 328 }; 329 struct publish_synchronized_tag : publish_tag {}; 330 331 struct repeat_tag { 332 template<class Included> 333 struct include_header{ 334 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-repeat.hpp>"); 335 }; 336 }; 337 338 struct replay_tag { 339 template<class Included> 340 struct include_header{ 341 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-replay.hpp>"); 342 }; 343 }; 344 345 struct retry_tag { 346 template<class Included> 347 struct include_header{ 348 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-retry.hpp>"); 349 }; 350 }; 351 352 struct sample_with_time_tag { 353 template<class Included> 354 struct include_header{ 355 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-sample_time.hpp>"); 356 }; 357 }; 358 359 struct scan_tag { 360 template<class Included> 361 struct include_header{ 362 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-scan.hpp>"); 363 }; 364 }; 365 366 struct sequence_equal_tag { 367 template<class Included> 368 struct include_header{ 369 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-sequence_equal.hpp>"); 370 }; 371 }; 372 373 struct skip_tag { 374 template<class Included> 375 struct include_header{ 376 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip.hpp>"); 377 }; 378 }; 379 380 struct skip_while_tag { 381 template<class Included> 382 struct include_header{ 383 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_while.hpp>"); 384 }; 385 }; 386 387 struct skip_last_tag { 388 template<class Included> 389 struct include_header{ 390 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_last.hpp>"); 391 }; 392 }; 393 394 struct skip_until_tag { 395 template<class Included> 396 struct include_header{ 397 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-skip_until.hpp>"); 398 }; 399 }; 400 401 struct start_with_tag { 402 template<class Included> 403 struct include_header{ 404 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-start_with.hpp>"); 405 }; 406 }; 407 408 struct subscribe_on_tag { 409 template<class Included> 410 struct include_header{ 411 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-subscribe_on.hpp>"); 412 }; 413 }; 414 415 struct switch_if_empty_tag { 416 template<class Included> 417 struct include_header{ 418 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-switch_if_empty.hpp>"); 419 }; 420 }; 421 struct default_if_empty_tag : switch_if_empty_tag {}; 422 423 struct switch_on_next_tag { 424 template<class Included> 425 struct include_header{ 426 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-switch_on_next.hpp>"); 427 }; 428 }; 429 430 struct take_tag { 431 template<class Included> 432 struct include_header{ 433 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take.hpp>"); 434 }; 435 }; 436 437 struct take_last_tag { 438 template<class Included> 439 struct include_header{ 440 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_last.hpp>"); 441 }; 442 }; 443 444 struct take_while_tag { 445 template<class Included> 446 struct include_header{ 447 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_while.hpp>"); 448 }; 449 }; 450 451 struct take_until_tag { 452 template<class Included> 453 struct include_header{ 454 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_until.hpp>"); 455 }; 456 }; 457 458 struct tap_tag { 459 template<class Included> 460 struct include_header{ 461 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-rap.hpp>"); 462 }; 463 }; 464 465 struct timeout_tag { 466 template<class Included> 467 struct include_header{ 468 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-timeout.hpp>"); 469 }; 470 }; 471 472 struct time_interval_tag { 473 template<class Included> 474 struct include_header{ 475 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-time_interval.hpp>"); 476 }; 477 }; 478 479 struct timestamp_tag { 480 template<class Included> 481 struct include_header{ 482 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-timestamp.hpp>"); 483 }; 484 }; 485 486 struct window_tag { 487 template<class Included> 488 struct include_header{ 489 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window.hpp>"); 490 }; 491 }; 492 493 struct window_with_time_tag { 494 template<class Included> 495 struct include_header{ 496 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_time.hpp>"); 497 }; 498 }; 499 500 struct window_with_time_or_count_tag { 501 template<class Included> 502 struct include_header{ 503 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_time_count.hpp>"); 504 }; 505 }; 506 507 struct window_toggle_tag { 508 template<class Included> 509 struct include_header{ 510 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_toggle.hpp>"); 511 }; 512 }; 513 514 struct with_latest_from_tag { 515 template<class Included> 516 struct include_header{ 517 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-with_latest_from.hpp>"); 518 }; 519 }; 520 521 struct zip_tag { 522 template<class Included> 523 struct include_header{ 524 static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-zip.hpp>"); 525 }; 526 }; 527 528 } 529 530 #include "operators/rx-multicast.hpp" 531 #include "operators/rx-publish.hpp" 532 #include "operators/rx-ref_count.hpp" 533 534 #endif 535