diff options
author | Grigoriy Chudnov <g.chudnov@gmail.com> | 2016-12-29 16:42:22 +0300 |
---|---|---|
committer | Kirk Shoop <kirk.shoop@microsoft.com> | 2016-12-29 10:11:40 -0800 |
commit | 588e3ac01c655e224f095c264b6fe90c09381005 (patch) | |
tree | 2e4d7a57931fdc998583d29f4430ed944bbba3c6 /Rx/v2/src | |
parent | c62234770349a638e0296ca0ceca137b4147af06 (diff) | |
download | RxCpp-588e3ac01c655e224f095c264b6fe90c09381005.tar.gz |
decouple take from observable
Diffstat (limited to 'Rx/v2/src')
-rw-r--r-- | Rx/v2/src/rxcpp/operators/rx-take.hpp | 73 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-includes.hpp | 1 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-observable.hpp | 23 | ||||
-rw-r--r-- | Rx/v2/src/rxcpp/rx-operators.hpp | 22 |
4 files changed, 75 insertions, 44 deletions
diff --git a/Rx/v2/src/rxcpp/operators/rx-take.hpp b/Rx/v2/src/rxcpp/operators/rx-take.hpp index c7259a3..054c136 100644 --- a/Rx/v2/src/rxcpp/operators/rx-take.hpp +++ b/Rx/v2/src/rxcpp/operators/rx-take.hpp @@ -2,6 +2,21 @@ #pragma once +/*! \file rx-take.hpp + + \brief For the first count items from this observable emit them from the new observable that is returned. + + \tparam Count the type of the items counter. + + \param t the number of items to take. + + \return An observable that emits only the first t items emitted by the source Observable, or all of the items from the source observable if that observable emits fewer than t items. + + \sample + \snippet take.cpp take sample + \snippet output.txt take sample +*/ + #if !defined(RXCPP_OPERATORS_RX_TAKE_HPP) #define RXCPP_OPERATORS_RX_TAKE_HPP @@ -13,6 +28,16 @@ namespace operators { namespace detail { +template<class... AN> +struct take_invalid_arguments {}; + +template<class... AN> +struct take_invalid : public rxo::operator_base<take_invalid_arguments<AN...>> { + using type = observable<take_invalid_arguments<AN...>, take_invalid<AN...>>; +}; +template<class... AN> +using take_invalid_t = typename take_invalid<AN...>::type; + template<class T, class Observable, class Count> struct take : public operator_base<T> { @@ -100,31 +125,41 @@ struct take : public operator_base<T> } }; -template<class T> -class take_factory -{ - typedef rxu::decay_t<T> count_type; - count_type count; -public: - take_factory(count_type t) : count(std::move(t)) {} - template<class Observable> - auto operator()(Observable&& source) - -> observable<rxu::value_type_t<rxu::decay_t<Observable>>, take<rxu::value_type_t<rxu::decay_t<Observable>>, Observable, count_type>> { - return observable<rxu::value_type_t<rxu::decay_t<Observable>>, take<rxu::value_type_t<rxu::decay_t<Observable>>, Observable, count_type>>( - take<rxu::value_type_t<rxu::decay_t<Observable>>, Observable, count_type>(std::forward<Observable>(source), count)); - } -}; - } -template<class T> -auto take(T&& t) - -> detail::take_factory<T> { - return detail::take_factory<T>(std::forward<T>(t)); +/*! @copydoc rx-take.hpp +*/ +template<class... AN> +auto take(AN&&... an) + -> operator_factory<take_tag, AN...> { + return operator_factory<take_tag, AN...>(std::make_tuple(std::forward<AN>(an)...)); } } +template<> +struct member_overload<take_tag> +{ + template<class Observable, + class Count, + class Enabled = rxu::enable_if_all_true_type_t< + is_observable<Observable>>, + class SourceValue = rxu::value_type_t<Observable>, + class Take = rxo::detail::take<SourceValue, rxu::decay_t<Observable>, rxu::decay_t<Count>>, + class Value = rxu::value_type_t<Take>, + class Result = observable<Value, Take>> + static Result member(Observable&& o, Count&& c) { + return Result(Take(std::forward<Observable>(o), std::forward<Count>(c))); + } + + template<class... AN> + static operators::detail::take_invalid_t<AN...> member(AN...) { + std::terminate(); + return {}; + static_assert(sizeof...(AN) == 10000, "take takes (optional Count)"); + } +}; + } #endif diff --git a/Rx/v2/src/rxcpp/rx-includes.hpp b/Rx/v2/src/rxcpp/rx-includes.hpp index 35a14bb..38607eb 100644 --- a/Rx/v2/src/rxcpp/rx-includes.hpp +++ b/Rx/v2/src/rxcpp/rx-includes.hpp @@ -202,6 +202,7 @@ #include "operators/rx-repeat.hpp" #include "operators/rx-retry.hpp" #include "operators/rx-sequence_equal.hpp" +#include "operators/rx-take.hpp" #include "operators/rx-take_while.hpp" #include "operators/rx-timeout.hpp" #include "operators/rx-time_interval.hpp" diff --git a/Rx/v2/src/rxcpp/rx-observable.hpp b/Rx/v2/src/rxcpp/rx-observable.hpp index 761aa7f..bdd847a 100644 --- a/Rx/v2/src/rxcpp/rx-observable.hpp +++ b/Rx/v2/src/rxcpp/rx-observable.hpp @@ -2517,26 +2517,15 @@ public: rxo::detail::skip_until<T, this_type, TriggerSource, Coordination>(*this, std::forward<TriggerSource>(t), std::forward<Coordination>(cn))); } - /*! For the first count items from this observable emit them from the new observable that is returned. - - \tparam Count the type of the items counter - - \param t the number of items to take - - \return An observable that emits only the first t items emitted by the source Observable, or all of the items from the source observable if that observable emits fewer than t items. - - \sample - \snippet take.cpp take sample - \snippet output.txt take sample - */ - template<class Count> - auto take(Count t) const + /*! @copydoc rx-take.hpp + */ + template<class... AN> + auto take(AN... an) const /// \cond SHOW_SERVICE_MEMBERS - -> observable<T, rxo::detail::take<T, this_type, Count>> + -> decltype(observable_member(take_tag{}, *(this_type*)nullptr, std::forward<AN>(an)...)) /// \endcond { - return observable<T, rxo::detail::take<T, this_type, Count>>( - rxo::detail::take<T, this_type, Count>(*this, t)); + return observable_member(take_tag{}, *this, std::forward<AN>(an)...); } /*! Emit only the final t items emitted by the source Observable. diff --git a/Rx/v2/src/rxcpp/rx-operators.hpp b/Rx/v2/src/rxcpp/rx-operators.hpp index 2ecea1e..0d1a2b4 100644 --- a/Rx/v2/src/rxcpp/rx-operators.hpp +++ b/Rx/v2/src/rxcpp/rx-operators.hpp @@ -119,7 +119,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-take.hpp" #include "operators/rx-take_last.hpp" #include "operators/rx-take_until.hpp" #include "operators/rx-tap.hpp" @@ -260,13 +259,6 @@ struct average_tag : reduce_tag {}; struct min_tag : reduce_tag {}; struct max_tag : reduce_tag {}; -struct take_while_tag { - template<class Included> - struct include_header{ - static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_while.hpp>"); - }; -}; - struct pairwise_tag { template<class Included> struct include_header{ @@ -295,6 +287,20 @@ struct sequence_equal_tag { }; }; +struct take_tag { + template<class Included> + struct include_header{ + static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take.hpp>"); + }; +}; + +struct take_while_tag { + template<class Included> + struct include_header{ + static_assert(Included::value, "missing include: please #include <rxcpp/operators/rx-take_while.hpp>"); + }; +}; + struct timeout_tag { template<class Included> struct include_header{ |