diff options
author | Grigoriy Chudnov <g.chudnov@gmail.com> | 2017-01-05 00:28:28 +0300 |
---|---|---|
committer | Kirk Shoop <kirk.shoop@microsoft.com> | 2017-01-04 14:37:51 -0800 |
commit | 4b22ef4d55a93071be7313440ef6cb75455daa08 (patch) | |
tree | 0b06449907b529d16b285ae3a1ea0ce99ce18143 /Rx/v2 | |
parent | 8baebf74d8fd65fcfc71d99da8ae2f342dfd565e (diff) | |
download | RxCpp-4b22ef4d55a93071be7313440ef6cb75455daa08.tar.gz |
decouple sample_with_time from observable
Diffstat (limited to 'Rx/v2')
-rw-r--r-- | Rx/v2/src/rxcpp/operators/rx-sample_time.hpp | 107 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-includes.hpp | 1 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-observable.hpp | 40 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-operators.hpp | 8 | ||||
-rw-r--r-- | Rx/v2/test/operators/sample.cpp | 5 |
5 files changed, 94 insertions, 67 deletions
diff --git a/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp b/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp index 09447c1..fe1caa2 100644 --- a/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp +++ b/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp @@ -2,6 +2,23 @@ #pragma once +/*! \file rx-sample_time.hpp + + \brief Return an Observable that emits the most recent items emitted by the source Observable within periodic time intervals. + + \tparam Duration the type of time interval. + \tparam Coordination the type of the scheduler (optional). + + \param period the period of time to sample the source observable. + \param coordination the scheduler for the items (optional). + + \return Observable that emits the most recently emitted item since the previous sampling. + + \sample + \snippet sample.cpp sample period sample + \snippet output.txt sample period sample +*/ + #if !defined(RXCPP_OPERATORS_RX_SAMPLE_WITH_TIME_HPP) #define RXCPP_OPERATORS_RX_SAMPLE_WITH_TIME_HPP @@ -13,12 +30,19 @@ namespace operators { namespace detail { +template<class... AN> +struct sample_with_time_invalid_arguments {}; + +template<class... AN> +struct sample_with_time_invalid : public rxo::operator_base<sample_with_time_invalid_arguments<AN...>> { + using type = observable<sample_with_time_invalid_arguments<AN...>, sample_with_time_invalid<AN...>>; +}; +template<class... AN> +using sample_with_time_invalid_t = typename sample_with_time_invalid<AN...>::type; + template<class T, class Duration, class Coordination> struct sample_with_time { - static_assert(std::is_convertible<Duration, rxsc::scheduler::clock_type::duration>::value, "Duration parameter must convert to rxsc::scheduler::clock_type::duration"); - static_assert(is_coordination<Coordination>::value, "Coordination parameter must satisfy the requirements for a Coordination"); - typedef rxu::decay_t<T> source_value_type; typedef rxu::decay_t<Coordination> coordination_type; typedef typename coordination_type::coordinator_type coordinator_type; @@ -169,38 +193,63 @@ struct sample_with_time } }; -template<class Duration, class Coordination> -class sample_with_time_factory -{ - typedef rxu::decay_t<Duration> duration_type; - typedef rxu::decay_t<Coordination> coordination_type; - - duration_type period; - coordination_type coordination; -public: - sample_with_time_factory(duration_type p, coordination_type c) : period(p), coordination(c) {} - template<class Observable> - auto operator()(Observable&& source) - -> decltype(source.template lift<rxu::value_type_t<rxu::decay_t<Observable>>>(sample_with_time<rxu::value_type_t<rxu::decay_t<Observable>>, Duration, Coordination>(period, coordination))) { - return source.template lift<rxu::value_type_t<rxu::decay_t<Observable>>>(sample_with_time<rxu::value_type_t<rxu::decay_t<Observable>>, Duration, Coordination>(period, coordination)); - } -}; - } -template<class Duration, class Coordination> -inline auto sample_with_time(Duration period, Coordination coordination) - -> detail::sample_with_time_factory<Duration, Coordination> { - return detail::sample_with_time_factory<Duration, Coordination>(period, coordination); +/*! @copydoc rx-sample_time.hpp +*/ +template<class... AN> +auto sample_with_time(AN&&... an) + -> operator_factory<sample_with_time_tag, AN...> { + return operator_factory<sample_with_time_tag, AN...>(std::make_tuple(std::forward<AN>(an)...)); } -template<class Duration> -inline auto sample_with_time(Duration period) - -> detail::sample_with_time_factory<Duration, identity_one_worker> { - return detail::sample_with_time_factory<Duration, identity_one_worker>(period, identity_current_thread()); } -} +template<> +struct member_overload<sample_with_time_tag> +{ + template<class Observable, class Duration, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>, + rxu::is_duration<Duration>>, + class SourceValue = rxu::value_type_t<Observable>, + class SampleWithTime = rxo::detail::sample_with_time<SourceValue, rxu::decay_t<Duration>, identity_one_worker>> + static auto member(Observable&& o, Duration&& d) + -> decltype(o.template lift<SourceValue>(SampleWithTime(std::forward<Duration>(d), identity_current_thread()))) { + return o.template lift<SourceValue>(SampleWithTime(std::forward<Duration>(d), identity_current_thread())); + } + + template<class Observable, class Coordination, class Duration, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>, + is_coordination<Coordination>, + rxu::is_duration<Duration>>, + class SourceValue = rxu::value_type_t<Observable>, + class SampleWithTime = rxo::detail::sample_with_time<SourceValue, rxu::decay_t<Duration>, rxu::decay_t<Coordination>>> + static auto member(Observable&& o, Coordination&& cn, Duration&& d) + -> decltype(o.template lift<SourceValue>(SampleWithTime(std::forward<Duration>(d), std::forward<Coordination>(cn)))) { + return o.template lift<SourceValue>(SampleWithTime(std::forward<Duration>(d), std::forward<Coordination>(cn))); + } + + template<class Observable, class Coordination, class Duration, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>, + is_coordination<Coordination>, + rxu::is_duration<Duration>>, + class SourceValue = rxu::value_type_t<Observable>, + class SampleWithTime = rxo::detail::sample_with_time<SourceValue, rxu::decay_t<Duration>, rxu::decay_t<Coordination>>> + static auto member(Observable&& o, Duration&& d, Coordination&& cn) + -> decltype(o.template lift<SourceValue>(SampleWithTime(std::forward<Duration>(d), std::forward<Coordination>(cn)))) { + return o.template lift<SourceValue>(SampleWithTime(std::forward<Duration>(d), std::forward<Coordination>(cn))); + } + + template<class... AN> + static operators::detail::sample_with_time_invalid_t<AN...> member(const AN&...) { + std::terminate(); + return {}; + static_assert(sizeof...(AN) == 10000, "sample_with_time takes (optional Coordination, required Duration) or (required Duration, optional Coordination)"); + } +}; } diff --git a/Rx/v2/src/rxcpp/rx-includes.hpp b/Rx/v2/src/rxcpp/rx-includes.hpp index e73e498..2bec757 100644 --- a/Rx/v2/src/rxcpp/rx-includes.hpp +++ b/Rx/v2/src/rxcpp/rx-includes.hpp @@ -204,6 +204,7 @@ #include "operators/rx-reduce.hpp" #include "operators/rx-repeat.hpp" #include "operators/rx-retry.hpp" +#include "operators/rx-sample_time.hpp" #include "operators/rx-sequence_equal.hpp" #include "operators/rx-skip.hpp" #include "operators/rx-take.hpp" diff --git a/Rx/v2/src/rxcpp/rx-observable.hpp b/Rx/v2/src/rxcpp/rx-observable.hpp index 90adf36..eeef943 100644 --- a/Rx/v2/src/rxcpp/rx-observable.hpp +++ b/Rx/v2/src/rxcpp/rx-observable.hpp @@ -2094,45 +2094,15 @@ public: rxo::detail::scan<T, this_type, Accumulator, Seed>(*this, std::forward<Accumulator>(a), seed)); } - /*! Return an Observable that emits the most recent items emitted by the source Observable within periodic time intervals. - - \param period the period of time to sample the source observable. - \param coordination the scheduler for the items. - - \return Observable that emits the most recently emitted item since the previous sampling. - - \sample - \snippet sample.cpp sample period sample - \snippet output.txt sample period sample - */ - template<class Coordination, - class Requires = typename std::enable_if<is_coordination<Coordination>::value, rxu::types_checked>::type> - auto sample_with_time(rxsc::scheduler::clock_type::duration period, Coordination coordination) const - /// \cond SHOW_SERVICE_MEMBERS - -> decltype(EXPLICIT_THIS lift<T>(rxo::detail::sample_with_time<T, rxsc::scheduler::clock_type::duration, Coordination>(period, coordination))) - /// \endcond - { - return lift<T>(rxo::detail::sample_with_time<T, rxsc::scheduler::clock_type::duration, Coordination>(period, coordination)); - } - - /*! Return an Observable that emits the most recent items emitted by the source Observable within periodic time intervals. - - \param period the period of time to sample the source observable. - - \return Observable that emits the most recently emitted item since the previous sampling. - - \sample - \snippet sample.cpp sample period sample - \snippet output.txt sample period sample - */ + /*! @copydoc rx-sample_time.hpp + */ template<class... AN> - auto sample_with_time(rxsc::scheduler::clock_type::duration period, AN**...) const + auto sample_with_time(AN&&... an) const /// \cond SHOW_SERVICE_MEMBERS - -> decltype(EXPLICIT_THIS lift<T>(rxo::detail::sample_with_time<T, rxsc::scheduler::clock_type::duration, identity_one_worker>(period, identity_current_thread()))) + -> decltype(observable_member(sample_with_time_tag{}, *(this_type*)nullptr, std::forward<AN>(an)...)) /// \endcond { - return lift<T>(rxo::detail::sample_with_time<T, rxsc::scheduler::clock_type::duration, identity_one_worker>(period, identity_current_thread())); - static_assert(sizeof...(AN) == 0, "sample_with_time(period) was passed too many arguments."); + return observable_member(sample_with_time_tag{}, *this, std::forward<AN>(an)...); } /*! @copydoc rx-skip.hpp diff --git a/Rx/v2/src/rxcpp/rx-operators.hpp b/Rx/v2/src/rxcpp/rx-operators.hpp index 6d06e2b..64e6db5 100644 --- a/Rx/v2/src/rxcpp/rx-operators.hpp +++ b/Rx/v2/src/rxcpp/rx-operators.hpp @@ -106,7 +106,6 @@ public: #include "operators/rx-publish.hpp" #include "operators/rx-ref_count.hpp" #include "operators/rx-replay.hpp" -#include "operators/rx-sample_time.hpp" #include "operators/rx-scan.hpp" #include "operators/rx-skip_last.hpp" #include "operators/rx-skip_until.hpp" @@ -294,6 +293,13 @@ struct retry_tag { }; }; +struct sample_with_time_tag { + template<class Included> + struct include_header{ + static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-sample_time.hpp>"); + }; +}; + struct sequence_equal_tag { template<class Included> struct include_header{ diff --git a/Rx/v2/test/operators/sample.cpp b/Rx/v2/test/operators/sample.cpp index 5dfc007..7c49ac3 100644 --- a/Rx/v2/test/operators/sample.cpp +++ b/Rx/v2/test/operators/sample.cpp @@ -1,4 +1,5 @@ #include "../test.h" +#include "rxcpp/operators/rx-sample_time.hpp" SCENARIO("sample with time, error", "[sample_with_time][operators]"){ GIVEN("1 hot observable of ints."){ @@ -27,8 +28,8 @@ SCENARIO("sample with time, error", "[sample_with_time][operators]"){ auto res = w.start( [&]() { return xs - .sample_with_time(milliseconds(100), so) - .as_dynamic(); + | rxo::sample_with_time(milliseconds(100), so) + | rxo::as_dynamic(); } ); |