diff options
author | Grigoriy Chudnov <g.chudnov@gmail.com> | 2016-12-17 21:39:39 +0300 |
---|---|---|
committer | Kirk Shoop <kirk.shoop@microsoft.com> | 2016-12-17 10:39:39 -0800 |
commit | fa9428c65f09f76024f0f2acfb819f22f0875320 (patch) | |
tree | 87b965c6e028320e597f106a06dac0eae7253773 /Rx/v2/src/rxcpp | |
parent | a5c54e7008395c86fb34a5544faf40405255a8fc (diff) | |
download | RxCpp-fa9428c65f09f76024f0f2acfb819f22f0875320.tar.gz |
decouple sequence_equal from observable (#295)
* decouple sequence_equal from observable
* refactoring to fix msvc2013
Diffstat (limited to 'Rx/v2/src/rxcpp')
-rw-r--r-- | Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp | 141 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-includes.hpp | 1 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-observable.hpp | 106 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-operators.hpp | 8 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-util.hpp | 11 |
5 files changed, 122 insertions, 145 deletions
diff --git a/Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp b/Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp index 32a0d30..06253b4 100644 --- a/Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp +++ b/Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp @@ -2,6 +2,25 @@ #pragma once +/*! \file rx-sequence_equal.hpp + + \brief Determine whether two Observables emit the same sequence of items. + + \tparam OtherSource the type of the other observable. + \tparam BinaryPredicate the type of the value comparing function (optional). The signature should be equivalent to the following: bool pred(const T1& a, const T2& b); + \tparam Coordination the type of the scheduler (optional). + + \param t the other Observable that emits items to compare. + \param pred the function that implements comparison of two values (optional). + \param cn the scheduler (optional). + + \return Observable that emits true only if both sequences terminate normally after emitting the same sequence of items in the same order; otherwise it will emit false. + + \sample + \snippet sequence_equal.cpp sequence_equal sample + \snippet output.txt sequence_equal sample +*/ + #if !defined(RXCPP_OPERATORS_RX_SEQUENCE_EQUAL_HPP) #define RXCPP_OPERATORS_RX_SEQUENCE_EQUAL_HPP @@ -13,6 +32,16 @@ namespace operators { namespace detail { +template<class... AN> +struct sequence_equal_invalid_arguments {}; + +template<class... AN> +struct sequence_equal_invalid : public rxo::operator_base<sequence_equal_invalid_arguments<AN...>> { + using type = observable<sequence_equal_invalid_arguments<AN...>, sequence_equal_invalid<AN...>>; +}; +template<class... AN> +using sequence_equal_invalid_t = typename sequence_equal_invalid<AN...>::type; + template<class T, class Observable, class OtherObservable, class BinaryPredicate, class Coordination> struct sequence_equal : public operator_base<bool> { @@ -173,60 +202,80 @@ struct sequence_equal : public operator_base<bool> } }; -template<class OtherObservable, class BinaryPredicate, class Coordination> -class sequence_equal_factory -{ - typedef rxu::decay_t<OtherObservable> other_source_type; - typedef rxu::decay_t<Coordination> coordination_type; - typedef rxu::decay_t<BinaryPredicate> predicate_type; - - other_source_type other_source; - coordination_type coordination; - predicate_type pred; - -public: - sequence_equal_factory(other_source_type t, predicate_type p, coordination_type sf) - : other_source(std::move(t)) - , coordination(std::move(sf)) - , pred(std::move(p)) - { - } - - template<class Observable> - auto operator()(Observable&& source) - -> observable<bool, sequence_equal<rxu::value_type_t<rxu::decay_t<Observable>>, Observable, other_source_type, BinaryPredicate, Coordination>> { - return observable<bool, sequence_equal<rxu::value_type_t<rxu::decay_t<Observable>>, Observable, other_source_type, BinaryPredicate, Coordination>>( - sequence_equal<rxu::value_type_t<rxu::decay_t<Observable>>, Observable, other_source_type, BinaryPredicate, Coordination>(std::forward<Observable>(source), other_source, pred, coordination)); - } -}; - } -template<class OtherObservable> -inline auto sequence_equal(OtherObservable&& t) - -> detail::sequence_equal_factory<OtherObservable, rxu::equal_to<>, identity_one_worker> { - return detail::sequence_equal_factory<OtherObservable, rxu::equal_to<>, identity_one_worker>(std::forward<OtherObservable>(t), rxu::equal_to<>(), identity_current_thread()); +/*! @copydoc rx-sequence_equal.hpp +*/ +template<class... AN> +auto sequence_equal(AN&&... an) + -> operator_factory<sequence_equal_tag, AN...> { + return operator_factory<sequence_equal_tag, AN...>(std::make_tuple(std::forward<AN>(an)...)); } -template<class OtherObservable, class BinaryPredicate, class Check = typename std::enable_if<!is_coordination<BinaryPredicate>::value>::type> -inline auto sequence_equal(OtherObservable&& t, BinaryPredicate&& pred) - -> detail::sequence_equal_factory<OtherObservable, BinaryPredicate, identity_one_worker> { - return detail::sequence_equal_factory<OtherObservable, BinaryPredicate, identity_one_worker>(std::forward<OtherObservable>(t), std::forward<BinaryPredicate>(pred), identity_current_thread()); } -template<class OtherObservable, class Coordination, class Check = typename std::enable_if<is_coordination<Coordination>::value>::type> -inline auto sequence_equal(OtherObservable&& t, Coordination&& cn) - -> detail::sequence_equal_factory<OtherObservable, rxu::equal_to<>, Coordination> { - return detail::sequence_equal_factory<OtherObservable, rxu::equal_to<>, Coordination>(std::forward<OtherObservable>(t), rxu::equal_to<>(), std::forward<Coordination>(cn)); -} +template<> +struct member_overload<sequence_equal_tag> +{ + template<class Observable, class OtherObservable, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>, + is_observable<OtherObservable>>, + class SourceValue = rxu::value_type_t<Observable>, + class SequenceEqual = rxo::detail::sequence_equal<SourceValue, rxu::decay_t<Observable>, rxu::decay_t<OtherObservable>, rxu::equal_to<>, identity_one_worker>, + class Value = rxu::value_type_t<SequenceEqual>, + class Result = observable<Value, SequenceEqual>> + static Result member(Observable&& o, OtherObservable&& t) { + return Result(SequenceEqual(std::forward<Observable>(o), std::forward<OtherObservable>(t), rxu::equal_to<>(), identity_current_thread())); + } -template<class OtherObservable, class BinaryPredicate, class Coordination> -inline auto sequence_equal(OtherObservable&& t, BinaryPredicate&& pred, Coordination&& cn) - -> detail::sequence_equal_factory<OtherObservable, BinaryPredicate, Coordination> { - return detail::sequence_equal_factory<OtherObservable, BinaryPredicate, Coordination>(std::forward<OtherObservable>(t), std::forward<BinaryPredicate>(pred), std::forward<Coordination>(cn)); -} + template<class Observable, class OtherObservable, class BinaryPredicate, + class IsCoordination = is_coordination<BinaryPredicate>, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>, + is_observable<OtherObservable>, + rxu::negation<IsCoordination>>, + class SourceValue = rxu::value_type_t<Observable>, + class SequenceEqual = rxo::detail::sequence_equal<SourceValue, rxu::decay_t<Observable>, rxu::decay_t<OtherObservable>, rxu::decay_t<BinaryPredicate>, identity_one_worker>, + class Value = rxu::value_type_t<SequenceEqual>, + class Result = observable<Value, SequenceEqual>> + static Result member(Observable&& o, OtherObservable&& t, BinaryPredicate&& pred) { + return Result(SequenceEqual(std::forward<Observable>(o), std::forward<OtherObservable>(t), std::forward<BinaryPredicate>(pred), identity_current_thread())); + } -} + template<class Observable, class OtherObservable, class Coordination, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>, + is_observable<OtherObservable>, + is_coordination<Coordination>>, + class SourceValue = rxu::value_type_t<Observable>, + class SequenceEqual = rxo::detail::sequence_equal<SourceValue, rxu::decay_t<Observable>, rxu::decay_t<OtherObservable>, rxu::equal_to<>, rxu::decay_t<Coordination>>, + class Value = rxu::value_type_t<SequenceEqual>, + class Result = observable<Value, SequenceEqual>> + static Result member(Observable&& o, OtherObservable&& t, Coordination&& cn) { + return Result(SequenceEqual(std::forward<Observable>(o), std::forward<OtherObservable>(t), rxu::equal_to<>(), std::forward<Coordination>(cn))); + } + + template<class Observable, class OtherObservable, class BinaryPredicate, class Coordination, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>, + is_observable<OtherObservable>, + is_coordination<Coordination>>, + class SourceValue = rxu::value_type_t<Observable>, + class SequenceEqual = rxo::detail::sequence_equal<SourceValue, rxu::decay_t<Observable>, rxu::decay_t<OtherObservable>, rxu::decay_t<BinaryPredicate>, rxu::decay_t<Coordination>>, + class Value = rxu::value_type_t<SequenceEqual>, + class Result = observable<Value, SequenceEqual>> + static Result member(Observable&& o, OtherObservable&& t, BinaryPredicate&& pred, Coordination&& cn) { + return Result(SequenceEqual(std::forward<Observable>(o), std::forward<OtherObservable>(t), std::forward<BinaryPredicate>(pred), std::forward<Coordination>(cn))); + } + + template<class... AN> + static operators::detail::sequence_equal_invalid_t<AN...> member(const AN&...) { + std::terminate(); + return {}; + static_assert(sizeof...(AN) == 10000, "sequence_equal takes (OtherObservable, optional BinaryPredicate, optional Coordination)"); + } +}; } diff --git a/Rx/v2/src/rxcpp/rx-includes.hpp b/Rx/v2/src/rxcpp/rx-includes.hpp index 2feec7d..283793e 100644 --- a/Rx/v2/src/rxcpp/rx-includes.hpp +++ b/Rx/v2/src/rxcpp/rx-includes.hpp @@ -197,6 +197,7 @@ #include "operators/rx-map.hpp" #include "operators/rx-on_error_resume_next.hpp" #include "operators/rx-reduce.hpp" +#include "operators/rx-sequence_equal.hpp" #include "operators/rx-take_while.hpp" #include "operators/rx-retry.hpp" #include "operators/rx-with_latest_from.hpp" diff --git a/Rx/v2/src/rxcpp/rx-observable.hpp b/Rx/v2/src/rxcpp/rx-observable.hpp index 2ff85ae..ff68936 100644 --- a/Rx/v2/src/rxcpp/rx-observable.hpp +++ b/Rx/v2/src/rxcpp/rx-observable.hpp @@ -838,105 +838,15 @@ public: return switch_if_empty(rxs::from(std::move(v))); } - /*! Determine whether two Observables emit the same sequence of items. - - \tparam OtherSource the type of the other observable. - \tparam BinaryPredicate the type of the value comparing function. The signature should be equivalent to the following: bool pred(const T1& a, const T2& b); - \tparam Coordination the type of the scheduler. - - \param t the other Observable that emits items to compare. - \param pred the function that implements comparison of two values. - \param cn the scheduler. - - \return Observable that emits true only if both sequences terminate normally after emitting the same sequence of items in the same order; otherwise it will emit false. - - \sample - \snippet sequence_equal.cpp sequence_equal sample - \snippet output.txt sequence_equal sample - */ - template<class OtherSource, class BinaryPredicate, class Coordination> - auto sequence_equal(OtherSource&& t, BinaryPredicate&& pred, Coordination&& cn) const - /// \cond SHOW_SERVICE_MEMBERS - -> typename std::enable_if<is_observable<OtherSource>::value, - observable<bool, rxo::detail::sequence_equal<T, this_type, OtherSource, BinaryPredicate, Coordination>>>::type - /// \endcond - { - return observable<bool, rxo::detail::sequence_equal<T, this_type, OtherSource, BinaryPredicate, Coordination>>( - rxo::detail::sequence_equal<T, this_type, OtherSource, BinaryPredicate, Coordination>(*this, std::forward<OtherSource>(t), std::forward<BinaryPredicate>(pred), std::forward<Coordination>(cn))); - } - - - /*! Determine whether two Observables emit the same sequence of items. - - \tparam OtherSource the type of the other observable. - \tparam BinaryPredicate the type of the value comparing function. The signature should be equivalent to the following: bool pred(const T1& a, const T2& b); - - \param t the other Observable that emits items to compare. - \param pred the function that implements comparison of two values. - - \return Observable that emits true only if both sequences terminate normally after emitting the same sequence of items in the same order; otherwise it will emit false. - - \sample - \snippet sequence_equal.cpp sequence_equal sample - \snippet output.txt sequence_equal sample - */ - template<class OtherSource, class BinaryPredicate> - auto sequence_equal(OtherSource&& t, BinaryPredicate&& pred) const - /// \cond SHOW_SERVICE_MEMBERS - -> typename std::enable_if<is_observable<OtherSource>::value && !is_coordination<BinaryPredicate>::value, - observable<bool, rxo::detail::sequence_equal<T, this_type, OtherSource, BinaryPredicate, identity_one_worker>>>::type - /// \endcond - { - return observable<bool, rxo::detail::sequence_equal<T, this_type, OtherSource, BinaryPredicate, identity_one_worker>>( - rxo::detail::sequence_equal<T, this_type, OtherSource, BinaryPredicate, identity_one_worker>(*this, std::forward<OtherSource>(t), std::forward<BinaryPredicate>(pred), identity_one_worker(rxsc::make_current_thread()))); - } - - /*! Determine whether two Observables emit the same sequence of items. - - \tparam OtherSource the type of the other observable. - \tparam Coordination the type of the scheduler. - - \param t the other Observable that emits items to compare. - \param cn the scheduler. - - \return Observable that emits true only if both sequences terminate normally after emitting the same sequence of items in the same order; otherwise it will emit false. - - \sample - \snippet sequence_equal.cpp sequence_equal sample - \snippet output.txt sequence_equal sample - */ - template<class OtherSource, class Coordination> - auto sequence_equal(OtherSource&& t, Coordination&& cn) const - /// \cond SHOW_SERVICE_MEMBERS - -> typename std::enable_if<is_observable<OtherSource>::value && is_coordination<Coordination>::value, - observable<bool, rxo::detail::sequence_equal<T, this_type, OtherSource, rxu::equal_to<>, Coordination>>>::type - /// \endcond - { - return observable<bool, rxo::detail::sequence_equal<T, this_type, OtherSource, rxu::equal_to<>, Coordination>>( - rxo::detail::sequence_equal<T, this_type, OtherSource, rxu::equal_to<>, Coordination>(*this, std::forward<OtherSource>(t), rxu::equal_to<>(), std::forward<Coordination>(cn))); - } - - /*! Determine whether two Observables emit the same sequence of items. - - \tparam OtherSource the type of the other observable. - - \param t the other Observable that emits items to compare. - - \return Observable that emits true only if both sequences terminate normally after emitting the same sequence of items in the same order; otherwise it will emit false. - - \sample - \snippet sequence_equal.cpp sequence_equal sample - \snippet output.txt sequence_equal sample - */ - template<class OtherSource> - auto sequence_equal(OtherSource&& t) const - /// \cond SHOW_SERVICE_MEMBERS - -> typename std::enable_if<is_observable<OtherSource>::value, - observable<bool, rxo::detail::sequence_equal<T, this_type, OtherSource, rxu::equal_to<>, identity_one_worker>>>::type - /// \endcond + /*! @copydoc rx-sequence_equal.hpp + */ + template<class... AN> + auto sequence_equal(AN... an) const + /// \cond SHOW_SERVICE_MEMBERS + -> decltype(observable_member(sequence_equal_tag{}, *(this_type*)nullptr, std::forward<AN>(an)...)) + /// \endcond { - return observable<bool, rxo::detail::sequence_equal<T, this_type, OtherSource, rxu::equal_to<>, identity_one_worker>>( - rxo::detail::sequence_equal<T, this_type, OtherSource, rxu::equal_to<>, identity_one_worker>(*this, std::forward<OtherSource>(t), rxu::equal_to<>(), identity_one_worker(rxsc::make_current_thread()))); + return observable_member(sequence_equal_tag{}, *this, std::forward<AN>(an)...); } /*! inspect calls to on_next, on_error and on_completed. diff --git a/Rx/v2/src/rxcpp/rx-operators.hpp b/Rx/v2/src/rxcpp/rx-operators.hpp index be4d485..975c4e6 100644 --- a/Rx/v2/src/rxcpp/rx-operators.hpp +++ b/Rx/v2/src/rxcpp/rx-operators.hpp @@ -114,7 +114,6 @@ public: #include "operators/rx-replay.hpp" #include "operators/rx-sample_time.hpp" #include "operators/rx-scan.hpp" -#include "operators/rx-sequence_equal.hpp" #include "operators/rx-skip.hpp" #include "operators/rx-skip_last.hpp" #include "operators/rx-skip_until.hpp" @@ -274,6 +273,13 @@ struct retry_tag { }; }; +struct sequence_equal_tag { + template<class Included> + struct include_header{ + static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-sequence_equal.hpp>"); + }; +}; + struct with_latest_from_tag { template<class Included> struct include_header{ diff --git a/Rx/v2/src/rxcpp/rx-util.hpp b/Rx/v2/src/rxcpp/rx-util.hpp index 3ddc0b9..0e09301 100644 --- a/Rx/v2/src/rxcpp/rx-util.hpp +++ b/Rx/v2/src/rxcpp/rx-util.hpp @@ -780,6 +780,17 @@ namespace detail { template <class T, class Decayed = decay_t<T>> struct is_duration : detail::is_duration<Decayed> {}; + +// C++17 negation +namespace detail { + template<class T> + struct not_value : std::conditional<T::value, std::false_type, std::true_type>::type { + }; +} + +template <class T> +struct negation : detail::not_value<T> {}; + } namespace rxu=util; |