summaryrefslogtreecommitdiff
path: root/Rx/v2/src
diff options
context:
space:
mode:
authorGrigoriy Chudnov <g.chudnov@gmail.com>2017-01-10 12:55:20 +0300
committerKirk Shoop <kirk.shoop@microsoft.com>2017-01-10 08:14:03 -0800
commit13d406282a025f799f7674513dc2222f68d15dd4 (patch)
tree045a49c6cd0ce6030f81bb1c58a975e350a926cc /Rx/v2/src
parent37ab993f9f364f22f361a228bac988d6c798f3d2 (diff)
downloadRxCpp-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.hpp138
-rw-r--r--Rx/v2/src/rxcpp/rx-includes.hpp1
-rw-r--r--Rx/v2/src/rxcpp/rx-observable.hpp51
-rw-r--r--Rx/v2/src/rxcpp/rx-operators.hpp10
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{