diff options
author | Grigoriy Chudnov <g.chudnov@gmail.com> | 2017-01-10 12:55:20 +0300 |
---|---|---|
committer | Kirk Shoop <kirk.shoop@microsoft.com> | 2017-01-10 08:14:03 -0800 |
commit | 13d406282a025f799f7674513dc2222f68d15dd4 (patch) | |
tree | 045a49c6cd0ce6030f81bb1c58a975e350a926cc /Rx/v2/src | |
parent | 37ab993f9f364f22f361a228bac988d6c798f3d2 (diff) | |
download | RxCpp-13d406282a025f799f7674513dc2222f68d15dd4.tar.gz |
decouple window_toggle from observable
Diffstat (limited to 'Rx/v2/src')
-rw-r--r-- | Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp | 138 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-includes.hpp | 1 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-observable.hpp | 51 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-operators.hpp | 10 |
4 files changed, 98 insertions, 102 deletions
diff --git a/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp b/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp index c0195d8..1460feb 100644 --- a/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp +++ b/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp @@ -2,6 +2,29 @@ #pragma once +/*! \file rx-window_toggle.hpp + + \brief Return an observable that emits observables every period time interval and collects items from this observable for period of time into each produced observable, on the specified scheduler. + + \tparam Openings observable<OT> + \tparam ClosingSelector a function of type observable<CT>(OT) + \tparam Coordination the type of the scheduler (optional). + + \param opens each value from this observable opens a new window. + \param closes this function is called for each opened window and returns an observable. the first value from the returned observable will close the window. + \param coordination the scheduler for the windows (optional). + + \return Observable that emits an observable for each opened window. + + \sample + \snippet window.cpp window toggle+coordination sample + \snippet output.txt window toggle+coordination sample + + \sample + \snippet window.cpp window toggle sample + \snippet output.txt window toggle sample +*/ + #if !defined(RXCPP_OPERATORS_RX_WINDOW_TOGGLE_HPP) #define RXCPP_OPERATORS_RX_WINDOW_TOGGLE_HPP @@ -13,43 +36,29 @@ namespace operators { namespace detail { -template<class T, class Openings, class ClosingSelector, class Coordination> -struct window_toggle_traits { - - using source_value_type = rxu::decay_t<T>; - using coordination_type = rxu::decay_t<Coordination>; - using openings_type = rxu::decay_t<Openings>; - using openings_value_type = typename openings_type::value_type; - using closing_selector_type = rxu::decay_t<ClosingSelector>; - - static_assert(is_observable<openings_type>::value, "window_toggle Openings must be an observable"); +template<class... AN> +struct window_toggle_invalid_arguments {}; - struct tag_not_valid {}; - template<class CS, class CV> - static auto check(int) -> decltype((*(CS*)nullptr)((*(CV*)nullptr))); - template<class CS, class CV> - static tag_not_valid check(...); - - static_assert(is_observable<decltype(check<closing_selector_type, openings_value_type>(0))>::value, "window_toggle ClosingSelector must be a function with the signature observable<U>(Openings::value_type)"); - - using closings_type = rxu::decay_t<decltype(check<closing_selector_type, openings_value_type>(0))>; - using closings_value_type = typename closings_type::value_type; +template<class... AN> +struct window_toggle_invalid : public rxo::operator_base<window_toggle_invalid_arguments<AN...>> { + using type = observable<window_toggle_invalid_arguments<AN...>, window_toggle_invalid<AN...>>; }; +template<class... AN> +using window_toggle_invalid_t = typename window_toggle_invalid<AN...>::type; template<class T, class Openings, class ClosingSelector, class Coordination> struct window_toggle { typedef window_toggle<T, Openings, ClosingSelector, Coordination> this_type; - typedef window_toggle_traits<T, Openings, ClosingSelector, Coordination> traits; - - using source_value_type = typename traits::source_value_type; - using coordination_type = typename traits::coordination_type; + using source_value_type = rxu::decay_t<T>; + using coordination_type = rxu::decay_t<Coordination>; using coordinator_type = typename coordination_type::coordinator_type; - using openings_type = typename traits::openings_type; - using openings_value_type = typename traits::openings_value_type; - using closing_selector_type = typename traits::closing_selector_type; - using closings_value_type = typename traits::closings_value_type; + using openings_type = rxu::decay_t<Openings>; + using openings_value_type = typename openings_type::value_type; + using closing_selector_type = rxu::decay_t<ClosingSelector>; + using closings_type = rxu::result_of_t<closing_selector_type(openings_value_type)>; + using closings_value_type = typename closings_type::value_type; struct window_toggle_values { @@ -256,40 +265,57 @@ struct window_toggle } }; -template<class Openings, class ClosingSelector, class Coordination> -class window_toggle_factory -{ - typedef rxu::decay_t<Openings> openings_type; - typedef rxu::decay_t<ClosingSelector> closing_selector_type; - typedef rxu::decay_t<Coordination> coordination_type; - - openings_type openings; - closing_selector_type closingSelector; - coordination_type coordination; -public: - window_toggle_factory(openings_type opens, closing_selector_type closes, coordination_type c) : openings(opens), closingSelector(closes), coordination(c) {} - template<class Observable> - auto operator()(Observable&& source) - -> decltype(source.template lift<observable<rxu::value_type_t<rxu::decay_t<Observable>>>>(window_toggle<rxu::value_type_t<rxu::decay_t<Observable>>, Openings, ClosingSelector, Coordination>(openings, closingSelector, coordination))) { - return source.template lift<observable<rxu::value_type_t<rxu::decay_t<Observable>>>>(window_toggle<rxu::value_type_t<rxu::decay_t<Observable>>, Openings, ClosingSelector, Coordination>(openings, closingSelector, coordination)); - } -}; - } -template<class Openings, class ClosingSelector, class Coordination> -inline auto window_toggle(Openings openings, ClosingSelector closingSelector, Coordination coordination) - -> detail::window_toggle_factory<Openings, ClosingSelector, Coordination> { - return detail::window_toggle_factory<Openings, ClosingSelector, Coordination>(openings, closingSelector, coordination); +/*! @copydoc rx-window_toggle.hpp +*/ +template<class... AN> +auto window_toggle(AN&&... an) + -> operator_factory<window_toggle_tag, AN...> { + return operator_factory<window_toggle_tag, AN...>(std::make_tuple(std::forward<AN>(an)...)); } -template<class Openings, class ClosingSelector> -inline auto window_toggle(Openings openings, ClosingSelector closingSelector) - -> detail::window_toggle_factory<Openings, ClosingSelector, identity_one_worker> { - return detail::window_toggle_factory<Openings, ClosingSelector, identity_one_worker>(openings, closingSelector, identity_immediate()); } -} +template<> +struct member_overload<window_toggle_tag> +{ + template<class Observable, class Openings, class ClosingSelector, + class ClosingSelectorType = rxu::decay_t<ClosingSelector>, + class OpeningsType = rxu::decay_t<Openings>, + class OpeningsValueType = typename OpeningsType::value_type, + class Enabled = rxu::enable_if_all_true_type_t< + all_observables<Observable, Openings, rxu::result_of_t<ClosingSelectorType(OpeningsValueType)>>>, + class SourceValue = rxu::value_type_t<Observable>, + class WindowToggle = rxo::detail::window_toggle<SourceValue, rxu::decay_t<Openings>, rxu::decay_t<ClosingSelector>, identity_one_worker>, + class Value = observable<SourceValue>> + static auto member(Observable&& o, Openings&& openings, ClosingSelector&& closingSelector) + -> decltype(o.template lift<Value>(WindowToggle(std::forward<Openings>(openings), std::forward<ClosingSelector>(closingSelector), identity_immediate()))) { + return o.template lift<Value>(WindowToggle(std::forward<Openings>(openings), std::forward<ClosingSelector>(closingSelector), identity_immediate())); + } + + template<class Observable, class Openings, class ClosingSelector, class Coordination, + class ClosingSelectorType = rxu::decay_t<ClosingSelector>, + class OpeningsType = rxu::decay_t<Openings>, + class OpeningsValueType = typename OpeningsType::value_type, + class Enabled = rxu::enable_if_all_true_type_t< + all_observables<Observable, Openings, rxu::result_of_t<ClosingSelectorType(OpeningsValueType)>>, + is_coordination<Coordination>>, + class SourceValue = rxu::value_type_t<Observable>, + class WindowToggle = rxo::detail::window_toggle<SourceValue, rxu::decay_t<Openings>, rxu::decay_t<ClosingSelector>, rxu::decay_t<Coordination>>, + class Value = observable<SourceValue>> + static auto member(Observable&& o, Openings&& openings, ClosingSelector&& closingSelector, Coordination&& cn) + -> decltype(o.template lift<Value>(WindowToggle(std::forward<Openings>(openings), std::forward<ClosingSelector>(closingSelector), std::forward<Coordination>(cn)))) { + return o.template lift<Value>(WindowToggle(std::forward<Openings>(openings), std::forward<ClosingSelector>(closingSelector), std::forward<Coordination>(cn))); + } + + template<class... AN> + static operators::detail::window_toggle_invalid_t<AN...> member(AN...) { + std::terminate(); + return {}; + static_assert(sizeof...(AN) == 10000, "window_toggle takes (Openings, ClosingSelector, optional Coordination)"); + } +}; } diff --git a/Rx/v2/src/rxcpp/rx-includes.hpp b/Rx/v2/src/rxcpp/rx-includes.hpp index 35fa20e..3af27f4 100644 --- a/Rx/v2/src/rxcpp/rx-includes.hpp +++ b/Rx/v2/src/rxcpp/rx-includes.hpp @@ -220,6 +220,7 @@ #include "operators/rx-window.hpp" #include "operators/rx-window_time.hpp" #include "operators/rx-window_time_count.hpp" +#include "operators/rx-window_toggle.hpp" #include "operators/rx-with_latest_from.hpp" #include "operators/rx-zip.hpp" #endif diff --git a/Rx/v2/src/rxcpp/rx-observable.hpp b/Rx/v2/src/rxcpp/rx-observable.hpp index 01ceb88..81a626a 100644 --- a/Rx/v2/src/rxcpp/rx-observable.hpp +++ b/Rx/v2/src/rxcpp/rx-observable.hpp @@ -1030,52 +1030,15 @@ public: return observable_member(window_with_time_or_count_tag{}, *this, std::forward<AN>(an)...); } - /*! Return an observable that emits observables every period time interval and collects items from this observable for period of time into each produced observable, on the specified scheduler. - - \tparam Openings observable<OT> - \tparam ClosingSelector a function of type observable<CT>(OT) - \tparam Coordination the type of the scheduler - - \param opens each value from this observable opens a new window. - \param closes this function is called for each opened window and returns an observable. the first value from the returned observable will close the window - \param coordination the scheduler for the windows - - \return Observable that emits an observable for each opened window. - - \sample - \snippet window.cpp window toggle+coordination sample - \snippet output.txt window toggle+coordination sample + /*! @copydoc rx-window_toggle.hpp */ - template<class Openings, class ClosingSelector, class Coordination, class Reqiures = typename rxu::types_checked_from<typename Coordination::coordination_tag>::type> - auto window_toggle(Openings opens, ClosingSelector closes, Coordination coordination) const - /// \cond SHOW_SERVICE_MEMBERS - -> decltype(EXPLICIT_THIS lift<observable<T>>(rxo::detail::window_toggle<T, Openings, ClosingSelector, Coordination>(opens, closes, coordination))) - /// \endcond - { - return lift<observable<T>>(rxo::detail::window_toggle<T, Openings, ClosingSelector, Coordination>(opens, closes, coordination)); - } - - /*! Return an observable that emits connected, non-overlapping windows represending items emitted by the source observable during fixed, consecutive durations. - - \tparam Openings observable<OT> - \tparam ClosingSelector a function of type observable<CT>(OT) - - \param opens each value from this observable opens a new window. - \param closes this function is called for each opened window and returns an observable. the first value from the returned observable will close the window - - \return Observable that emits an observable for each opened window. - - \sample - \snippet window.cpp window toggle sample - \snippet output.txt window toggle sample - */ - template<class Openings, class ClosingSelector> - auto window_toggle(Openings opens, ClosingSelector closes) const - /// \cond SHOW_SERVICE_MEMBERS - -> decltype(EXPLICIT_THIS lift<observable<T>>(rxo::detail::window_toggle<T, Openings, ClosingSelector, identity_one_worker>(opens, closes, identity_current_thread()))) - /// \endcond + template<class... AN> + auto window_toggle(AN&&... an) const + /// \cond SHOW_SERVICE_MEMBERS + -> decltype(observable_member(window_toggle_tag{}, *(this_type*)nullptr, std::forward<AN>(an)...)) + /// \endcond { - return lift<observable<T>>(rxo::detail::window_toggle<T, Openings, ClosingSelector, identity_one_worker>(opens, closes, identity_current_thread())); + return observable_member(window_toggle_tag{}, *this, std::forward<AN>(an)...); } /*! @copydoc rx-buffer_count.hpp diff --git a/Rx/v2/src/rxcpp/rx-operators.hpp b/Rx/v2/src/rxcpp/rx-operators.hpp index fdf49fd..e1f333f 100644 --- a/Rx/v2/src/rxcpp/rx-operators.hpp +++ b/Rx/v2/src/rxcpp/rx-operators.hpp @@ -112,7 +112,6 @@ public: #include "operators/rx-switch_if_empty.hpp" #include "operators/rx-switch_on_next.hpp" #include "operators/rx-tap.hpp" -#include "operators/rx-window_toggle.hpp" namespace rxcpp { @@ -393,13 +392,20 @@ struct window_with_time_tag { }; }; - struct window_with_time_or_count_tag { +struct window_with_time_or_count_tag { template<class Included> struct include_header{ static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_time_count.hpp>"); }; }; +struct window_toggle_tag { + template<class Included> + struct include_header{ + static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-window_toggle.hpp>"); + }; +}; + struct with_latest_from_tag { template<class Included> struct include_header{ |