diff options
author | Grigoriy Chudnov <g.chudnov@gmail.com> | 2017-01-14 01:21:53 +0300 |
---|---|---|
committer | Kirk Shoop <kirk.shoop@microsoft.com> | 2017-01-13 14:21:53 -0800 |
commit | 7923baae257f7036eea164d30055756e88cea498 (patch) | |
tree | 0132149172a41458e08af8eaa937154bddf2dba9 /Rx/v2/src | |
parent | dd1702ba6e6ff5ed622d44964f11f938ca5e23a4 (diff) | |
download | RxCpp-7923baae257f7036eea164d30055756e88cea498.tar.gz |
decouple tap from observable (#328)
* decouple tap from observable
* decouple tap from observable - fix clang
Diffstat (limited to 'Rx/v2/src')
-rw-r--r-- | Rx/v2/src/rxcpp/operators/rx-tap.hpp | 76 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-includes.hpp | 1 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-observable.hpp | 28 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-operators.hpp | 8 |
4 files changed, 72 insertions, 41 deletions
diff --git a/Rx/v2/src/rxcpp/operators/rx-tap.hpp b/Rx/v2/src/rxcpp/operators/rx-tap.hpp index b75883b..51bfb2f 100644 --- a/Rx/v2/src/rxcpp/operators/rx-tap.hpp +++ b/Rx/v2/src/rxcpp/operators/rx-tap.hpp @@ -2,6 +2,27 @@ #pragma once +/*! \file rx-tap.hpp + + \brief inspect calls to on_next, on_error and on_completed. + + \tparam MakeObserverArgN... these args are passed to make_observer. + + \param an these args are passed to make_observer. + + \return Observable that emits the same items as the source observable to both the subscriber and the observer. + + \note If an on_error method is not supplied the observer will ignore errors rather than call std::terminate() + + \sample + \snippet tap.cpp tap sample + \snippet output.txt tap sample + + If the source observable generates an error, the observer passed to tap is called: + \snippet tap.cpp error tap sample + \snippet output.txt error tap sample +*/ + #if !defined(RXCPP_OPERATORS_RX_TAP_HPP) #define RXCPP_OPERATORS_RX_TAP_HPP @@ -13,6 +34,16 @@ namespace operators { namespace detail { +template<class... AN> +struct tap_invalid_arguments {}; + +template<class... AN> +struct tap_invalid : public rxo::operator_base<tap_invalid_arguments<AN...>> { + using type = observable<tap_invalid_arguments<AN...>, tap_invalid<AN...>>; +}; +template<class... AN> +using tap_invalid_t = typename tap_invalid<AN...>::type; + template<class T, class MakeObserverArgN> struct tap_observer_factory; @@ -82,30 +113,39 @@ struct tap } }; -template<class MakeObserverArgN> -class tap_factory -{ - typedef rxu::decay_t<MakeObserverArgN> args_type; - args_type args; -public: - tap_factory(args_type a) : args(std::move(a)) {} - template<class Observable> - auto operator()(Observable&& source) - -> decltype(source.template lift<rxu::value_type_t<rxu::decay_t<Observable>>>(tap<rxu::value_type_t<rxu::decay_t<Observable>>, args_type>(args))) { - return source.template lift<rxu::value_type_t<rxu::decay_t<Observable>>>(tap<rxu::value_type_t<rxu::decay_t<Observable>>, args_type>(args)); - } -}; - } -template<class... MakeObserverArgN> -auto tap(MakeObserverArgN&&... an) - -> detail::tap_factory<std::tuple<rxu::decay_t<MakeObserverArgN>...>> { - return detail::tap_factory<std::tuple<rxu::decay_t<MakeObserverArgN>...>>(std::make_tuple(std::forward<MakeObserverArgN>(an)...)); +/*! @copydoc rx-tap.hpp +*/ +template<class... AN> +auto tap(AN&&... an) + -> operator_factory<tap_tag, AN...> { + return operator_factory<tap_tag, AN...>(std::make_tuple(std::forward<AN>(an)...)); } } +template<> +struct member_overload<tap_tag> +{ + template<class Observable, class... MakeObserverArgN, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>>, + class SourceValue = rxu::value_type_t<Observable>, + class Tap = rxo::detail::tap<SourceValue, std::tuple<rxu::decay_t<MakeObserverArgN>...>>> + static auto member(Observable&& o, MakeObserverArgN&&... an) + -> decltype(o.template lift<SourceValue>(Tap(std::make_tuple(std::forward<MakeObserverArgN>(an)...)))) { + return o.template lift<SourceValue>(Tap(std::make_tuple(std::forward<MakeObserverArgN>(an)...))); + } + + template<class... AN> + static operators::detail::tap_invalid_t<AN...> member(const AN&...) { + std::terminate(); + return {}; + static_assert(sizeof...(AN) == 10000, "tap takes (MakeObserverArgN...)"); + } +}; + } #endif diff --git a/Rx/v2/src/rxcpp/rx-includes.hpp b/Rx/v2/src/rxcpp/rx-includes.hpp index 7fbdf83..91a641f 100644 --- a/Rx/v2/src/rxcpp/rx-includes.hpp +++ b/Rx/v2/src/rxcpp/rx-includes.hpp @@ -216,6 +216,7 @@ #include "operators/rx-take_last.hpp" #include "operators/rx-take_until.hpp" #include "operators/rx-take_while.hpp" +#include "operators/rx-tap.hpp" #include "operators/rx-time_interval.hpp" #include "operators/rx-timeout.hpp" #include "operators/rx-timestamp.hpp" diff --git a/Rx/v2/src/rxcpp/rx-observable.hpp b/Rx/v2/src/rxcpp/rx-observable.hpp index e77068c..74c4218 100644 --- a/Rx/v2/src/rxcpp/rx-observable.hpp +++ b/Rx/v2/src/rxcpp/rx-observable.hpp @@ -849,31 +849,15 @@ public: return observable_member(sequence_equal_tag{}, *this, std::forward<AN>(an)...); } - /*! inspect calls to on_next, on_error and on_completed. - - \tparam MakeObserverArgN... these args are passed to make_observer - - \param an these args are passed to make_observer. - - \return Observable that emits the same items as the source observable to both the subscriber and the observer. - - \note If an on_error method is not supplied the observer will ignore errors rather than call std::terminate() - - \sample - \snippet tap.cpp tap sample - \snippet output.txt tap sample - - If the source observable generates an error, the observer passed to tap is called: - \snippet tap.cpp error tap sample - \snippet output.txt error tap sample - */ - template<class... MakeObserverArgN> - auto tap(MakeObserverArgN&&... an) const + /*! @copydoc rx-tap.hpp + */ + template<class... AN> + auto tap(AN&&... an) const /// \cond SHOW_SERVICE_MEMBERS - -> decltype(EXPLICIT_THIS lift<T>(rxo::detail::tap<T, std::tuple<MakeObserverArgN...>>(std::make_tuple(std::forward<MakeObserverArgN>(an)...)))) + -> decltype(observable_member(tap_tag{}, *(this_type*)nullptr, std::forward<AN>(an)...)) /// \endcond { - return lift<T>(rxo::detail::tap<T, std::tuple<MakeObserverArgN...>>(std::make_tuple(std::forward<MakeObserverArgN>(an)...))); + return observable_member(tap_tag{}, *this, std::forward<AN>(an)...); } /*! @copydoc rx-time_interval.hpp diff --git a/Rx/v2/src/rxcpp/rx-operators.hpp b/Rx/v2/src/rxcpp/rx-operators.hpp index 2aaa935..5bf6109 100644 --- a/Rx/v2/src/rxcpp/rx-operators.hpp +++ b/Rx/v2/src/rxcpp/rx-operators.hpp @@ -109,7 +109,6 @@ public: #include "operators/rx-subscribe_on.hpp" #include "operators/rx-switch_if_empty.hpp" #include "operators/rx-switch_on_next.hpp" -#include "operators/rx-tap.hpp" namespace rxcpp { @@ -369,6 +368,13 @@ struct take_until_tag { }; }; +struct tap_tag { + template<class Included> + struct include_header{ + static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-rap.hpp>"); + }; +}; + struct timeout_tag { template<class Included> struct include_header{ |