// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. #pragma once /*! \file rx-pairwise.hpp \brief Take values pairwise from this observable. \return Observable that emits tuples of two the most recent items emitted by the source observable. \sample \snippet pairwise.cpp pairwise sample \snippet output.txt pairwise sample If the source observable emits less than two items, no pairs are emitted by the source observable: \snippet pairwise.cpp pairwise short sample \snippet output.txt pairwise short sample */ #if !defined(RXCPP_OPERATORS_RX_PAIRWISE_HPP) #define RXCPP_OPERATORS_RX_PAIRWISE_HPP #include "../rx-includes.hpp" namespace rxcpp { namespace operators { namespace detail { template struct pairwise_invalid_arguments {}; template struct pairwise_invalid : public rxo::operator_base> { using type = observable, pairwise_invalid>; }; template using pairwise_invalid_t = typename pairwise_invalid::type; template struct pairwise { typedef rxu::decay_t source_value_type; typedef std::tuple value_type; template struct pairwise_observer { typedef pairwise_observer this_type; typedef std::tuple value_type; typedef rxu::decay_t dest_type; typedef observer observer_type; dest_type dest; mutable rxu::detail::maybe remembered; pairwise_observer(dest_type d) : dest(std::move(d)) { } void on_next(source_value_type v) const { if (remembered.empty()) { remembered.reset(v); return; } dest.on_next(std::make_tuple(remembered.get(), v)); remembered.reset(v); } void on_error(std::exception_ptr e) const { dest.on_error(e); } void on_completed() const { dest.on_completed(); } static subscriber make(dest_type d) { auto cs = d.get_subscription(); return make_subscriber(std::move(cs), observer_type(this_type(std::move(d)))); } }; template auto operator()(Subscriber dest) const -> decltype(pairwise_observer::make(std::move(dest))) { return pairwise_observer::make(std::move(dest)); } }; } /*! @copydoc rx-pairwise.hpp */ template auto pairwise(AN&&... an) -> operator_factory { return operator_factory(std::make_tuple(std::forward(an)...)); } } template<> struct member_overload { template>, class SourceValue = rxu::value_type_t, class Pairwise = rxo::detail::pairwise, class Value = rxu::value_type_t> static auto member(Observable&& o) -> decltype(o.template lift(Pairwise())) { return o.template lift(Pairwise()); } template static operators::detail::pairwise_invalid_t member(AN...) { std::terminate(); return {}; static_assert(sizeof...(AN) == 10000, "pairwise takes no arguments"); } }; } #endif