From 3651142cdd4811a50b80a37fc92e74138702f7aa Mon Sep 17 00:00:00 2001 From: Kirk Shoop Date: Wed, 19 Oct 2016 08:50:13 -0700 Subject: decouple group_by lifter from observable --- Rx/v2/src/rxcpp/operators/rx-group_by.hpp | 113 ++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 14 deletions(-) (limited to 'Rx/v2/src/rxcpp/operators/rx-group_by.hpp') diff --git a/Rx/v2/src/rxcpp/operators/rx-group_by.hpp b/Rx/v2/src/rxcpp/operators/rx-group_by.hpp index 6414f22..4eadbab 100644 --- a/Rx/v2/src/rxcpp/operators/rx-group_by.hpp +++ b/Rx/v2/src/rxcpp/operators/rx-group_by.hpp @@ -2,6 +2,30 @@ #pragma once +/*! \file rx-group_by.hpp + + \brief Return an observable that emits grouped_observables, each of which corresponds to a unique key value and each of which emits those items from the source observable that share that key value. + + \tparam KeySelector the type of the key extracting function + \tparam MarbleSelector the type of the element extracting function + \tparam BinaryPredicate the type of the key comparing function + + \param ks a function that extracts the key for each item (optional) + \param ms a function that extracts the return element for each item (optional) + \param p a function that implements comparison of two keys (optional) + + \return Observable that emits values of grouped_observable type, each of which corresponds to a unique key value and each of which emits those items from the source observable that share that key value. + + \sample + \snippet group_by.cpp group_by full intro + \snippet group_by.cpp group_by full sample + \snippet output.txt group_by full sample + + \sample + \snippet group_by.cpp group_by sample + \snippet output.txt group_by sample +*/ + #if !defined(RXCPP_OPERATORS_RX_GROUP_BY_HPP) #define RXCPP_OPERATORS_RX_GROUP_BY_HPP @@ -13,6 +37,16 @@ namespace operators { namespace detail { +template +struct group_by_invalid_arguments {}; + +template +struct group_by_invalid : public rxo::operator_base> { + using type = observable, group_by_invalid>; +}; +template +using group_by_invalid_t = typename group_by_invalid::type; + template struct is_group_by_selector_for { @@ -241,25 +275,76 @@ public: } -template -inline auto group_by(KeySelector ks, MarbleSelector ms, BinaryPredicate p) - -> detail::group_by_factory { - return detail::group_by_factory(std::move(ks), std::move(ms), std::move(p)); +/*! @copydoc rx-group_by.hpp +*/ +template +auto group_by(AN&&... an) + -> operator_factory { + return operator_factory(std::make_tuple(std::forward(an)...)); } -template -inline auto group_by(KeySelector ks, MarbleSelector ms) - -> detail::group_by_factory { - return detail::group_by_factory(std::move(ks), std::move(ms), rxu::less(), identity_current_thread()); } -template -inline auto group_by(KeySelector ks) - -> detail::group_by_factory, rxu::less> { - return detail::group_by_factory, rxu::less>(std::move(ks), rxu::take_at<0>(), rxu::less()); -} +template<> +struct member_overload +{ + template, + class Traits = rxo::detail::group_by_traits, KeySelector, MarbleSelector, BinaryPredicate>, + class GroupBy = rxo::detail::group_by, rxu::decay_t, rxu::decay_t, rxu::decay_t>, + class Value = typename Traits::grouped_observable_type> + static auto member(Observable&& o, KeySelector&& ks, MarbleSelector&& ms, BinaryPredicate&& p) + -> decltype(o.template lift(GroupBy(std::forward(ks), std::forward(ms), std::forward(p)))) { + return o.template lift(GroupBy(std::forward(ks), std::forward(ms), std::forward(p))); + } -} + template, + class Traits = rxo::detail::group_by_traits, KeySelector, MarbleSelector, BinaryPredicate>, + class GroupBy = rxo::detail::group_by, rxu::decay_t, rxu::decay_t, rxu::decay_t>, + class Value = typename Traits::grouped_observable_type> + static auto member(Observable&& o, KeySelector&& ks, MarbleSelector&& ms) + -> decltype(o.template lift(GroupBy(std::forward(ks), std::forward(ms), rxu::less()))) { + return o.template lift(GroupBy(std::forward(ks), std::forward(ms), rxu::less())); + } + + + template, + class BinaryPredicate=rxu::less, + class SourceValue = rxu::value_type_t, + class Traits = rxo::detail::group_by_traits, KeySelector, MarbleSelector, BinaryPredicate>, + class GroupBy = rxo::detail::group_by, rxu::decay_t, rxu::decay_t, rxu::decay_t>, + class Value = typename Traits::grouped_observable_type> + static auto member(Observable&& o, KeySelector&& ks) + -> decltype(o.template lift(GroupBy(std::forward(ks), rxu::detail::take_at<0>(), rxu::less()))) { + return o.template lift(GroupBy(std::forward(ks), rxu::detail::take_at<0>(), rxu::less())); + } + + template, + class MarbleSelector=rxu::detail::take_at<0>, + class BinaryPredicate=rxu::less, + class Enabled = rxu::enable_if_all_true_type_t< + all_observables>, + class SourceValue = rxu::value_type_t, + class Traits = rxo::detail::group_by_traits, KeySelector, MarbleSelector, BinaryPredicate>, + class GroupBy = rxo::detail::group_by, rxu::decay_t, rxu::decay_t, rxu::decay_t>, + class Value = typename Traits::grouped_observable_type> + static auto member(Observable&& o) + -> decltype(o.template lift(GroupBy(rxu::detail::take_at<0>(), rxu::detail::take_at<0>(), rxu::less()))) { + return o.template lift(GroupBy(rxu::detail::take_at<0>(), rxu::detail::take_at<0>(), rxu::less())); + } + + template + static operators::detail::group_by_invalid_t member(const AN&...) { + std::terminate(); + return {}; + static_assert(sizeof...(AN) == 10000, "group_by takes (optional KeySelector, optional MarbleSelector, optional BinaryKeyPredicate), KeySelector takes (Observable::value_type) -> KeyValue, MarbleSelector takes (Observable::value_type) -> MarbleValue, BinaryKeyPredicate takes (KeyValue, KeyValue) -> bool"); + } + +}; } -- cgit v1.2.3