diff options
author | Kirk Shoop (MS Open Tech) <kirk.shoop@microsoft.com> | 2014-03-26 23:03:21 -0700 |
---|---|---|
committer | Kirk Shoop (MS Open Tech) <kirk.shoop@microsoft.com> | 2014-03-26 23:03:21 -0700 |
commit | 5fb44100464a3aaefe8bd4d8dc4a42afd5e2de19 (patch) | |
tree | b364f3eb17205632e938794f96d0ca6a1b494a40 /Rx/v2 | |
parent | 3c54077a4f8f1eaa6203fdb8f942235b8cdfcb2c (diff) | |
download | RxCpp-5fb44100464a3aaefe8bd4d8dc4a42afd5e2de19.tar.gz |
windows compiles!
gave up on compilers that do not have variadic support - at least for
now
Diffstat (limited to 'Rx/v2')
-rw-r--r-- | Rx/v2/src/rxcpp/rx-observable.hpp | 98 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-observer.hpp | 64 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-scheduler.hpp | 64 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-subscriber.hpp | 55 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-util.hpp | 417 | ||||
-rw-r--r-- | Rx/v2/test/subjects/subject.cpp | 22 |
6 files changed, 91 insertions, 629 deletions
diff --git a/Rx/v2/src/rxcpp/rx-observable.hpp b/Rx/v2/src/rxcpp/rx-observable.hpp index c062ae2..2b59544 100644 --- a/Rx/v2/src/rxcpp/rx-observable.hpp +++ b/Rx/v2/src/rxcpp/rx-observable.hpp @@ -223,7 +223,6 @@ public: return *this; } -#if RXCPP_USE_VARIADIC_TEMPLATES /// /// subscribe will cause this observable to emit values to the provided subscriber. /// callers must provide enough arguments to make a subscriber. @@ -239,103 +238,6 @@ public: -> decltype(detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<ArgN>(an)...))) { return detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); } -#else - /// - /// subscribe will cause this observable to emit values to the provided subscriber. - /// callers must provide enough arguments to make a subscriber. - /// overrides are supported. thus - /// subscribe(thesubscriber, composite_subscription()) - /// will take thesubscriber.get_observer() and the provided - /// subscription and subscribe to the new subscriber. - /// the on_next, on_error, on_completed methods can be supplied instead of an observer - /// if a subscription or subscriber is not provided then a new subscription will be created. - /// - template<class Arg0> - auto subscribe(Arg0&& a0) const - -> decltype(detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0)))) { - return detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0))); - } - - /// - /// subscribe will cause this observable to emit values to the provided subscriber. - /// callers must provide enough arguments to make a subscriber. - /// overrides are supported. thus - /// subscribe(thesubscriber, composite_subscription()) - /// will take thesubscriber.get_observer() and the provided - /// subscription and subscribe to the new subscriber. - /// the on_next, on_error, on_completed methods can be supplied instead of an observer - /// if a subscription or subscriber is not provided then a new subscription will be created. - /// - template<class Arg0, class Arg1> - auto subscribe(Arg0&& a0, Arg1&& a1) const - -> decltype(detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1)))) { - return detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1))); - } - - /// - /// subscribe will cause this observable to emit values to the provided subscriber. - /// callers must provide enough arguments to make a subscriber. - /// overrides are supported. thus - /// subscribe(thesubscriber, composite_subscription()) - /// will take thesubscriber.get_observer() and the provided - /// subscription and subscribe to the new subscriber. - /// the on_next, on_error, on_completed methods can be supplied instead of an observer - /// if a subscription or subscriber is not provided then a new subscription will be created. - /// - template<class Arg0, class Arg1, class Arg2> - auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2) const - -> decltype(detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))) { - return detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))); - } - - /// - /// subscribe will cause this observable to emit values to the provided subscriber. - /// callers must provide enough arguments to make a subscriber. - /// overrides are supported. thus - /// subscribe(thesubscriber, composite_subscription()) - /// will take thesubscriber.get_observer() and the provided - /// subscription and subscribe to the new subscriber. - /// the on_next, on_error, on_completed methods can be supplied instead of an observer - /// if a subscription or subscriber is not provided then a new subscription will be created. - /// - template<class Arg0, class Arg1, class Arg2, class Arg3> - auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) const - -> decltype(detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))) { - return detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))); - } - - /// - /// subscribe will cause this observable to emit values to the provided subscriber. - /// callers must provide enough arguments to make a subscriber. - /// overrides are supported. thus - /// subscribe(thesubscriber, composite_subscription()) - /// will take thesubscriber.get_observer() and the provided - /// subscription and subscribe to the new subscriber. - /// the on_next, on_error, on_completed methods can be supplied instead of an observer - /// if a subscription or subscriber is not provided then a new subscription will be created. - /// - template<class Arg0, class Arg1, class Arg2, class Arg3, class Arg4> - auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4) const - -> decltype(detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)))) { - return detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4))); - } - - /// - /// subscribe will cause this observable to emit values to the provided subscriber. - /// callers must provide enough arguments to make a subscriber. - /// overrides are supported. thus - /// subscribe(thesubscriber, composite_subscription()) - /// will take thesubscriber.get_observer() and the provided - /// subscription and subscribe to the new subscriber. - /// the on_next, on_error, on_completed methods can be supplied instead of an observer - /// if a subscription or subscriber is not provided then a new subscription will be created. - /// - template<class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> - auto subscribe(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4, Arg5&& a5) const - -> decltype(detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)))) { - return detail_subscribe(make_subscriber<T>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5))); - } -#endif /// filter (AKA Where) -> /// for each item from this observable use Predicate to select which items to emit from the new observable that is returned. diff --git a/Rx/v2/src/rxcpp/rx-observer.hpp b/Rx/v2/src/rxcpp/rx-observer.hpp index 26d998f..ec40195 100644 --- a/Rx/v2/src/rxcpp/rx-observer.hpp +++ b/Rx/v2/src/rxcpp/rx-observer.hpp @@ -267,6 +267,9 @@ template<class ResolvedArgSet> struct resolved_observer_traits { typedef typename std::decay<ResolvedArgSet>::type resolved_set; + + static_assert(std::tuple_size<resolved_set>::value >= 3, "must have at least three resolved arguments"); + typedef typename std::tuple_element<0, resolved_set>::type resolved_on_next; typedef typename std::tuple_element<1, resolved_set>::type resolved_on_error; typedef typename std::tuple_element<2, resolved_set>::type resolved_on_completed; @@ -323,78 +326,29 @@ struct tag_oncompleted_resolution }; // types to disambiguate -// on_next and optional on_error, on_completed + -// optional subscription +// on_next and optional on_error, on_completed // template<class T> struct tag_observer_set - : public rxu::detail::tag_set<tag_onnext_resolution<T>, - rxu::detail::tag_set<tag_onerror_resolution, - rxu::detail::tag_set<tag_oncompleted_resolution>>> { + typedef rxu::detail::tag_set<tag_onnext_resolution<T>, tag_onerror_resolution, tag_oncompleted_resolution> type; }; } -#if RXCPP_USE_VARIADIC_TEMPLATES template<class T, class Arg0, class... ArgN> auto make_observer(Arg0&& a0, ArgN&&... an) - -> decltype(detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...))) { - return detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); -} -#else -template<class T, class Arg0> -auto make_observer(Arg0&& a0) - -> decltype(detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0)))) { - return detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0))); -} -template<class T, class Arg0, class Arg1> -auto make_observer(Arg0&& a0, Arg1&& a1) - -> decltype(detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1)))) { - return detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1))); -} -template<class T, class Arg0, class Arg1, class Arg2> -auto make_observer(Arg0&& a0, Arg1&& a1, Arg2&& a2) - -> decltype(detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))) { - return detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))); -} -template<class T, class Arg0, class Arg1, class Arg2, class Arg3> -auto make_observer(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) - -> decltype(detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))) { - return detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))); + -> decltype(detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(typename detail::tag_observer_set<T>::type(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...))) { + return detail::make_observer_resolved<T>(rxu::detail::resolve_arg_set(typename detail::tag_observer_set<T>::type(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); } -#endif -#if RXCPP_USE_VARIADIC_TEMPLATES template<class T, class Arg0, class... ArgN> auto make_observer_dynamic(Arg0&& a0, ArgN&&... an) - -> decltype(detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...))) { - return detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); -} -#else -template<class T, class Arg0> -auto make_observer_dynamic(Arg0&& a0) - -> decltype(detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0)))) { - return detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0))); -} -template<class T, class Arg0, class Arg1> -auto make_observer_dynamic(Arg0&& a0, Arg1&& a1) - -> decltype(detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1)))) { - return detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1))); + -> decltype(detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(typename detail::tag_observer_set<T>::type(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...))) { + return detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(typename detail::tag_observer_set<T>::type(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); } -template<class T, class Arg0, class Arg1, class Arg2> -auto make_observer_dynamic(Arg0&& a0, Arg1&& a1, Arg2&& a2) - -> decltype(detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))) { - return detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))); -} -template<class T, class Arg0, class Arg1, class Arg2, class Arg3> -auto make_observer_dynamic(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) - -> decltype(detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))) { - return detail::make_observer_dynamic_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_observer_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))); -} -#endif } diff --git a/Rx/v2/src/rxcpp/rx-scheduler.hpp b/Rx/v2/src/rxcpp/rx-scheduler.hpp index cadc173..f92a981 100644 --- a/Rx/v2/src/rxcpp/rx-scheduler.hpp +++ b/Rx/v2/src/rxcpp/rx-scheduler.hpp @@ -552,17 +552,13 @@ struct tag_scheduler_resolution }; -struct tag_schedulable_set - // the first four must be the same as tag_observer_set or the indexing will fail - : public rxu::detail::tag_set<tag_when_resolution, - rxu::detail::tag_set<tag_schedulable_resolution, - rxu::detail::tag_set<rxcpp::detail::tag_subscription_resolution, - rxu::detail::tag_set<tag_scheduler_resolution, - rxu::detail::tag_set<tag_action_resolution, - rxu::detail::tag_set<tag_action_function_resolution, - rxu::detail::tag_set<tag_action_duration_resolution>>>>>>> -{ -}; +typedef rxu::detail::tag_set<tag_when_resolution, + tag_schedulable_resolution, + rxcpp::detail::tag_subscription_resolution, + tag_scheduler_resolution, + tag_action_resolution, + tag_action_function_resolution, + tag_action_duration_resolution> tag_schedulable_set; template<bool schedulable_is_arg, bool action_is_arg, bool action_function_is_arg> struct action_selector; @@ -639,61 +635,15 @@ schedulable schedule_resolved(ResolvedArgSet&& rsArg) { } -#if RXCPP_USE_VARIADIC_TEMPLATES template<class Arg0, class... ArgN> schedulable make_schedulable(Arg0&& a0, ArgN&&... an) { return detail::make_schedulable_resolved<true>(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); } -#else -template<class Arg0> -schedulable make_schedulable(Arg0&& a0) { - return detail::make_schedulable_resolved<true>(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0))); -} -template<class Arg0, class Arg1> -schedulable make_schedulable(Arg0&& a0, Arg1&& a1) { - return detail::make_schedulable_resolved<true>(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<Arg1>(a1))); -} -template<class Arg0, class Arg1, class Arg2> -schedulable make_schedulable(Arg0&& a0, Arg1&& a1, Arg2&& a2) { - return detail::make_schedulable_resolved<true>(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))); -} -template<class Arg0, class Arg1, class Arg2, class Arg3> -schedulable make_schedulable(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) { - return detail::make_schedulable_resolved<true>(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))); -} -template<class Arg0, class Arg1, class Arg2, class Arg3, class Arg4> -schedulable make_schedulable(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4) { - return detail::make_schedulable_resolved<true>(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4))); -} -#endif -#if RXCPP_USE_VARIADIC_TEMPLATES template<class Arg0, class... ArgN> schedulable schedule(Arg0&& a0, ArgN&&... an) { return detail::schedule_resolved(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); } -#else -template<class Arg0> -schedulable schedule(Arg0&& a0) { - return detail::schedule_resolved(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0))); -} -template<class Arg0, class Arg1> -schedulable schedule(Arg0&& a0, Arg1&& a1) { - return detail::schedule_resolved(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<Arg1>(a1))); -} -template<class Arg0, class Arg1, class Arg2> -schedulable schedule(Arg0&& a0, Arg1&& a1, Arg2&& a2) { - return detail::schedule_resolved(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))); -} -template<class Arg0, class Arg1, class Arg2, class Arg3> -schedulable schedule(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) { - return detail::schedule_resolved(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))); -} -template<class Arg0, class Arg1, class Arg2, class Arg3, class Arg4> -schedulable schedule(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4) { - return detail::schedule_resolved(rxu::detail::resolve_arg_set(detail::tag_schedulable_set(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4))); -} -#endif namespace detail { diff --git a/Rx/v2/src/rxcpp/rx-subscriber.hpp b/Rx/v2/src/rxcpp/rx-subscriber.hpp index 91086d8..d6a4deb 100644 --- a/Rx/v2/src/rxcpp/rx-subscriber.hpp +++ b/Rx/v2/src/rxcpp/rx-subscriber.hpp @@ -192,6 +192,7 @@ auto make_subscriber_resolved(ResolvedArgSet&& rsArg) return subscriber<T, decltype( select_observer<T>(*(typename std::decay<ResolvedArgSet>::type*)nullptr))>( s, r, select_observer<T>(rs)); + static_assert(std::tuple_size<decltype(rs)>::value == 7, "must have 7 resolved args"); // at least for now do not enforce resolver #if 0 typedef typename std::decay<decltype(rr)>::type rr_t; @@ -243,57 +244,25 @@ struct tag_resumption_resolution template<class T> struct tag_subscriber_set - // the first four must be the same as tag_observer_set or the indexing will fail - : public rxu::detail::tag_set<tag_onnext_resolution<T>, - rxu::detail::tag_set<tag_onerror_resolution, - rxu::detail::tag_set<tag_oncompleted_resolution, - rxu::detail::tag_set<tag_subscription_resolution, - rxu::detail::tag_set<tag_resumption_resolution, - rxu::detail::tag_set<tag_observer_resolution<T>, - rxu::detail::tag_set<tag_subscriber_resolution<T>>>>>>>> { + // the first four must be the same as tag_observer_set or the indexing will fail + typedef rxu::detail::tag_set< + tag_onnext_resolution<T>, + tag_onerror_resolution, + tag_oncompleted_resolution, + tag_subscription_resolution, + tag_resumption_resolution, + tag_observer_resolution<T>, + tag_subscriber_resolution<T>> type; }; } -#if RXCPP_USE_VARIADIC_TEMPLATES template<class T, class Arg0, class... ArgN> auto make_subscriber(Arg0&& a0, ArgN&&... an) - -> decltype(detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...))) { - return detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); + -> decltype(detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(typename detail::tag_subscriber_set<T>::type(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...))) { + return detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(typename detail::tag_subscriber_set<T>::type(), std::forward<Arg0>(a0), std::forward<ArgN>(an)...)); } -#else -template<class T, class Arg0> -auto make_subscriber(Arg0&& a0) - -> decltype(detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0)))) { - return detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0))); -} -template<class T, class Arg0, class Arg1> -auto make_subscriber(Arg0&& a0, Arg1&& a1) - -> decltype(detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1)))) { - return detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1))); -} -template<class T, class Arg0, class Arg1, class Arg2> -auto make_subscriber(Arg0&& a0, Arg1&& a1, Arg2&& a2) - -> decltype(detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))) { - return detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))); -} -template<class T, class Arg0, class Arg1, class Arg2, class Arg3> -auto make_subscriber(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) - -> decltype(detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))) { - return detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))); -} -template<class T, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4> -auto make_subscriber(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4) - -> decltype(detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)))) { - return detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4))); -} -template<class T, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -auto make_subscriber(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4, Arg5&& a5) - -> decltype(detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)))) { - return detail::make_subscriber_resolved<T>(rxu::detail::resolve_arg_set(detail::tag_subscriber_set<T>(), std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5))); -} -#endif } diff --git a/Rx/v2/src/rxcpp/rx-util.hpp b/Rx/v2/src/rxcpp/rx-util.hpp index 9132aaf..6c7efa2 100644 --- a/Rx/v2/src/rxcpp/rx-util.hpp +++ b/Rx/v2/src/rxcpp/rx-util.hpp @@ -198,8 +198,6 @@ private: Function* function; }; -#if RXCPP_USE_VARIADIC_TEMPLATES - template<int N, int Index> struct select_arg { @@ -253,164 +251,7 @@ struct resolved_arg<-1, T> } }; -#else - -template<int N, class T> -struct resolved_arg -{ - typedef resolved_arg<N, T> this_type; - static const int n = N; - static const bool is_arg = true; - typedef T result_type; - result_type value; - struct tag_value {}; - template<class Value> - resolved_arg(Value&& v, tag_value&&) - : value(std::forward<Value>(v)) - { - } - template<class Arg0> - static this_type make(Arg0&& a0) { - return this_type(std::forward<Arg0>(a0), tag_value()); - } -}; - -template<class T> -struct resolved_arg<-1, T> -{ - typedef resolved_arg<-1, T> this_type; - static const int n = -1; - static const bool is_arg = false; - typedef T result_type; - result_type value; - static this_type make() { - return this_type(); - } -}; - -template<int N, template<class Arg> class Predicate, class Default, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct arg_resolver_n; -template<template<class Arg> class Predicate, class Default, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct arg_resolver_n<5, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> -{ - static const int n = 5; - static const bool is_arg = true; - typedef Arg5 result_type; - typedef resolved_arg<n, result_type> resolved_type; - typedef arg_resolver_n<n, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> this_type; - typedef arg_resolver_n<n - 1, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> prev_type; - typedef typename std::conditional<Predicate<result_type>::value, this_type, typename prev_type::type>::type type; - template<class R> - static resolved_arg<n, result_type> make(const Arg0&, const Arg1&, const Arg2&, const Arg3&, const Arg4&, R&& a) - { - return resolved_arg<n, result_type>::make(std::forward<R>(a)); - } -}; - -template<template<class Arg> class Predicate, class Default, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct arg_resolver_n<4, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> -{ - static const int n = 4; - static const bool is_arg = true; - typedef Arg4 result_type; - typedef resolved_arg<n, result_type> resolved_type; - typedef arg_resolver_n<n, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> this_type; - typedef arg_resolver_n<n - 1, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> prev_type; - typedef typename std::conditional<Predicate<result_type>::value, this_type, typename prev_type::type>::type type; - template<class R> - static resolved_arg<n, result_type> make(const Arg0&, const Arg1&, const Arg2&, const Arg3&, R&& a, const Arg5&) - { - return resolved_arg<n, result_type>::make(std::forward<R>(a)); - } -}; - -template<template<class Arg> class Predicate, class Default, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct arg_resolver_n<3, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> -{ - static const int n = 3; - static const bool is_arg = true; - typedef Arg3 result_type; - typedef resolved_arg<n, result_type> resolved_type; - typedef arg_resolver_n<n, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> this_type; - typedef arg_resolver_n<n - 1, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> prev_type; - typedef typename std::conditional<Predicate<result_type>::value, this_type, typename prev_type::type>::type type; - template<class R> - static resolved_arg<n, result_type> make(const Arg0&, const Arg1&, const Arg2&, R&& a, const Arg4&, const Arg5&) - { - return resolved_arg<n, result_type>::make(std::forward<R>(a)); - } -}; - -template<template<class Arg> class Predicate, class Default, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct arg_resolver_n<2, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> -{ - static const int n = 2; - static const bool is_arg = true; - typedef Arg2 result_type; - typedef resolved_arg<n, result_type> resolved_type; - typedef arg_resolver_n<n, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> this_type; - typedef arg_resolver_n<n - 1, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> prev_type; - typedef typename std::conditional<Predicate<result_type>::value, this_type, typename prev_type::type>::type type; - template<class R> - static resolved_arg<n, result_type> make(const Arg0&, const Arg1&, R&& a, const Arg3&, const Arg4&, const Arg5&) - { - return resolved_arg<n, result_type>::make(std::forward<R>(a)); - } -}; - -template<template<class Arg> class Predicate, class Default, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct arg_resolver_n<1, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> -{ - static const int n = 1; - static const bool is_arg = true; - typedef Arg1 result_type; - typedef resolved_arg<n, result_type> resolved_type; - typedef arg_resolver_n<n, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> this_type; - typedef arg_resolver_n<n - 1, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> prev_type; - typedef typename std::conditional<Predicate<result_type>::value, this_type, typename prev_type::type>::type type; - template<class R> - static resolved_arg<n, result_type> make(const Arg0&, R&& a, const Arg2&, const Arg3&, const Arg4&, const Arg5&) - { - return resolved_arg<n, result_type>::make(std::forward<R>(a)); - } -}; - -template<template<class Arg> class Predicate, class Default, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct arg_resolver_n<0, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> -{ - static const int n = 0; - static const bool is_arg = true; - typedef Arg0 result_type; - typedef resolved_arg<n, result_type> resolved_type; - typedef arg_resolver_n<n, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> this_type; - typedef arg_resolver_n<n - 1, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> prev_type; - typedef typename std::conditional<Predicate<result_type>::value, this_type, typename prev_type::type>::type type; - template<class R> - static resolved_arg<n, result_type> make(R&& a, const Arg1&, const Arg2&, const Arg3&, const Arg4&, const Arg5&) - { - return resolved_arg<n, result_type>::make(std::forward<R>(a)); - } -}; - -template<template<class Arg> class Predicate, class Default, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -struct arg_resolver_n<-1, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> -{ - static const int n = -1; - static const bool is_arg = false; - typedef Default result_type; - typedef resolved_arg<n, result_type> resolved_type; - typedef arg_resolver_n<n, Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5> this_type; - typedef this_type type; - static resolved_arg<n, result_type> make(const Arg0&, const Arg1&, const Arg2&, const Arg3&, const Arg4&, const Arg5&) - { - return resolved_arg<n, result_type>(); - } -}; -#endif - - -#if RXCPP_USE_VARIADIC_TEMPLATES template<int N, bool... PredicateN> struct select_first; @@ -452,243 +293,67 @@ struct arg_resolver Default>::type result_type; typedef resolved_arg<match::value, result_type> resolved_type; }; -#else -struct tag_unresolvable {}; -template<template<class Arg> class Predicate, class Default, class Arg0 = tag_unresolvable, class Arg1 = tag_unresolvable, class Arg2 = tag_unresolvable, class Arg3 = tag_unresolvable, class Arg4 = tag_unresolvable, class Arg5 = tag_unresolvable> -struct arg_resolver -{ - typedef typename arg_resolver_n<5, Predicate, Default, typename std::decay<Arg0>::type, typename std::decay<Arg1>::type, typename std::decay<Arg2>::type, typename std::decay<Arg3>::type, typename std::decay<Arg4>::type, typename std::decay<Arg5>::type>::type type; -}; -#endif -#if RXCPP_USE_VARIADIC_TEMPLATES -template<template<class Arg> class Predicate, class Default, - class... ArgN> +template<template<class Arg> class Predicate, class Default, class... ArgN> auto resolve_arg(ArgN&&... an) -> typename arg_resolver<Predicate, Default, ArgN...>::resolved_type { return arg_resolver<Predicate, Default, ArgN...>::resolved_type::make(std::forward<ArgN>(an)...); } -#else -template<template<class Arg> class Predicate, class Default> -auto resolve_arg() --> decltype(typename arg_resolver<Predicate, Default>::type::make(tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable())) { - return typename arg_resolver<Predicate, Default>::type::make(tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable()); -} - -template<template<class Arg> class Predicate, class Default, - class Arg0> -auto resolve_arg(Arg0&& a0) --> decltype(typename arg_resolver<Predicate, Default, Arg0>::type::make(std::forward<Arg0>(a0), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable())) { - return typename arg_resolver<Predicate, Default, Arg0>::type::make(std::forward<Arg0>(a0), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable()); -} - -template<template<class Arg> class Predicate, class Default, - class Arg0, class Arg1> -auto resolve_arg(Arg0&& a0, Arg1&& a1) --> decltype(typename arg_resolver<Predicate, Default, Arg0, Arg1>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable())) { - return typename arg_resolver<Predicate, Default, Arg0, Arg1>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), tag_unresolvable(), tag_unresolvable(), tag_unresolvable(), tag_unresolvable()); -} - -template<template<class Arg> class Predicate, class Default, - class Arg0, class Arg1, class Arg2> -auto resolve_arg(Arg0&& a0, Arg1&& a1, Arg2&& a2) --> decltype(typename arg_resolver<Predicate, Default, Arg0, Arg1, Arg2>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), tag_unresolvable(), tag_unresolvable(), tag_unresolvable())) { - return typename arg_resolver<Predicate, Default, Arg0, Arg1, Arg2>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), tag_unresolvable(), tag_unresolvable(), tag_unresolvable()); -} - -template<template<class Arg> class Predicate, class Default, - class Arg0, class Arg1, class Arg2, class Arg3> -auto resolve_arg(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) --> decltype(typename arg_resolver<Predicate, Default, Arg0, Arg1, Arg2, Arg3>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), tag_unresolvable(), tag_unresolvable())) { - return typename arg_resolver<Predicate, Default, Arg0, Arg1, Arg2, Arg3>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), tag_unresolvable(), tag_unresolvable()); -} - -template<template<class Arg> class Predicate, class Default, - class Arg0, class Arg1, class Arg2, class Arg3, class Arg4> -auto resolve_arg(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4) --> decltype(typename arg_resolver<Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), tag_unresolvable())) { - return typename arg_resolver<Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), tag_unresolvable()); -} -template<template<class Arg> class Predicate, class Default, - class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -auto resolve_arg(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4, Arg5&& a5) --> decltype(typename arg_resolver<Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5))) { - return typename arg_resolver<Predicate, Default, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5>::type::make( - std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)); -} -#endif +template<class... TagN> +struct tag_set {}; -struct arg_resolver_term {}; +template<class TagSet> +struct arg_resolver_set; -// -// use to build a set of tags -// -template<class Tag, class NextSet = arg_resolver_term> -struct tag_set +template<class Tag0, class... TagN> +struct arg_resolver_set<tag_set<Tag0, TagN...>> { - typedef Tag tag; - typedef NextSet next_set; -}; + template<class Tag, class... ArgN> + struct expand + { + typedef typename arg_resolver<Tag::template predicate, typename Tag::default_type, ArgN...>::resolved_type type; + }; -template<class Tag> -struct arg_resolver_set; + template<class Result> + struct expanded; -template<> -struct arg_resolver_set<arg_resolver_term> -{ - inline std::tuple<> operator()(...){ - return std::tuple<>(); - } -}; + template<class Resolved0> + struct expanded<std::tuple<Resolved0>> + { + template<class... ArgN> + static std::tuple<Resolved0> make(ArgN&&... an) { + return std::tuple<Resolved0>(Resolved0::make(std::forward<ArgN>(an)...)); + } + }; + + template<class Resolved0, class... ResolvedN> + struct expanded<std::tuple<Resolved0, ResolvedN...>> + { + typedef std::tuple<Resolved0, ResolvedN...> result_type; + template<class... ArgN> + static result_type make(ArgN&&... an) { + return std::tuple_cat(std::tuple<Resolved0>(Resolved0::make(std::forward<ArgN>(an)...)), expanded<std::tuple<ResolvedN...>>::make(std::forward<ArgN>(an)...)); + } + }; -template<class TagSet> -struct arg_resolver_set -{ - typedef typename TagSet::tag tag; - typedef arg_resolver_set<typename TagSet::next_set> next_set; -#if RXCPP_USE_VARIADIC_TEMPLATES template<class... ArgN> auto operator()(ArgN&&... an) - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<ArgN>(an)...)), - next_set()(std::forward<ArgN>(an)...))) { - return std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<ArgN>(an)...)), - next_set()(std::forward<ArgN>(an)...)); - } -#else - inline auto operator()() - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>()), - next_set()())) { - return std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>()), - next_set()()); - } - template<class Arg0> - auto operator()(Arg0&& a0) - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0))), - next_set()(std::forward<Arg0>(a0)))) { - return std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0))), - next_set()(std::forward<Arg0>(a0))); - } - template<class Arg0, class Arg1> - auto operator()(Arg0&& a0, Arg1&& a1) - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1)))) { - return std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1))); - } - template<class Arg0, class Arg1, class Arg2> - auto operator()(Arg0&& a0, Arg1&& a1, Arg2&& a2) - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)))) { - return std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))); + -> std::tuple< typename expand<Tag0, ArgN...>::type, + typename expand<TagN, ArgN...>::type...> { + typedef std::tuple< typename expand<Tag0, ArgN...>::type, + typename expand<TagN, ArgN...>::type...> out_type; + static_assert(std::tuple_size<out_type>::value == (sizeof...(TagN) + 1), "tuple must have a value per tag"); + return expanded<out_type>::make(std::forward<ArgN>(an)...); } - template<class Arg0, class Arg1, class Arg2, class Arg3> - auto operator()(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)))) { - return std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))); - } - template<class Arg0, class Arg1, class Arg2, class Arg3, class Arg4> - auto operator()(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4) - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)))) { - return std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4))); - } - template<class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> - auto operator()(Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4, Arg5&& a5) - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)))) { - return std::tuple_cat( - std::make_tuple(resolve_arg<tag::template predicate, typename tag::default_type>(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5))), - next_set()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5))); - } -#endif }; -#if RXCPP_USE_VARIADIC_TEMPLATES -template<class... ArgN> -inline std::tuple<> resolve_arg_set(arg_resolver_term&&, ArgN&&... ) { - return std::tuple<>(); -} - template<class TagSet, class... ArgN> -auto resolve_arg_set(TagSet&&, ArgN&&... an) - -> decltype(std::tuple_cat( - std::make_tuple(resolve_arg<TagSet::tag::template predicate, typename TagSet::tag::default_type>( - std::forward<ArgN>(an)...)), - resolve_arg_set(typename TagSet::next_set(), - std::forward<ArgN>(an)...))) { - return std::tuple_cat( - std::make_tuple(resolve_arg<TagSet::tag::template predicate, typename TagSet::tag::default_type>( - std::forward<ArgN>(an)...)), - resolve_arg_set(typename TagSet::next_set(), - std::forward<ArgN>(an)...)); -} -#else -template<class TagSet> -auto resolve_arg_set(TagSet&&) - -> decltype(arg_resolver_set<TagSet>()()) { - return arg_resolver_set<TagSet>()(); -} -template<class TagSet, class Arg0> -auto resolve_arg_set(TagSet&&, Arg0&& a0) - -> decltype(arg_resolver_set<TagSet>()(std::forward<Arg0>(a0))) { - return arg_resolver_set<TagSet>()(std::forward<Arg0>(a0)); -} -template<class TagSet, class Arg0, class Arg1> -auto resolve_arg_set(TagSet&&, Arg0&& a0, Arg1&& a1) - -> decltype(arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1))) { - return arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1)); -} -template<class TagSet, class Arg0, class Arg1, class Arg2> -auto resolve_arg_set(TagSet&&, Arg0&& a0, Arg1&& a1, Arg2&& a2) - -> decltype(arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2))) { - return arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2)); +auto resolve_arg_set(const TagSet&, ArgN&&... an) + -> decltype(arg_resolver_set<TagSet>()(std::forward<ArgN>(an)...)) { + return arg_resolver_set<TagSet>()(std::forward<ArgN>(an)...); } -template<class TagSet, class Arg0, class Arg1, class Arg2, class Arg3> -auto resolve_arg_set(TagSet&&, Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3) - -> decltype(arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3))) { - return arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3)); -} -template<class TagSet, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4> -auto resolve_arg_set(TagSet&&, Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4) - -> decltype(arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4))) { - return arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4)); -} -template<class TagSet, class Arg0, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> -auto resolve_arg_set(TagSet&&, Arg0&& a0, Arg1&& a1, Arg2&& a2, Arg3&& a3, Arg4&& a4, Arg5&& a5) - -> decltype(arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5))) { - return arg_resolver_set<TagSet>()(std::forward<Arg0>(a0), std::forward<Arg1>(a1), std::forward<Arg2>(a2), std::forward<Arg3>(a3), std::forward<Arg4>(a4), std::forward<Arg5>(a5)); -} -#endif } diff --git a/Rx/v2/test/subjects/subject.cpp b/Rx/v2/test/subjects/subject.cpp index 9a7544a..6b5df0b 100644 --- a/Rx/v2/test/subjects/subject.cpp +++ b/Rx/v2/test/subjects/subject.cpp @@ -42,6 +42,12 @@ SCENARIO("subject test", "[hide][subject][subjects][perf]"){ { int c = 0; int n = 1; +#if 0 + auto onnext = [&c](int){++c;}; + auto onerror = [](std::exception_ptr){abort();}; + + auto oex = rxu::detail::arg_resolver_set<rx::detail::tag_observer_set<int>::type>()(onnext, onerror); +#endif auto o = rx::make_observer<int>( [&c](int){++c;}, [](std::exception_ptr){abort();}); @@ -77,6 +83,22 @@ SCENARIO("subject test", "[hide][subject][subjects][perf]"){ int c = 0; int n = 1; auto start = clock::now(); +#if 0 + auto rso = rxu::detail::arg_resolver_set<rx::detail::tag_subscriber_set<int>::type>()( + [&c](int){ + ++c; + }, + [](std::exception_ptr){abort();}); + static_assert(std::tuple_size<decltype(rso)>::value == 7, "object must resolve 7 args"); + auto rsf = rxu::detail::resolve_arg_set( + rx::detail::tag_subscriber_set<int>::type(), + [&c](int){ + ++c; + }, + [](std::exception_ptr){abort();}); + static_assert(std::tuple_size<decltype(rsf)>::value == 7, "func must resolve 7 args"); + auto ss = rx::detail::make_subscriber_resolved<int>(rsf); +#endif rxs::range<int>(0, onnextcalls).subscribe( [&c](int){ ++c; |