// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. #pragma once /*! \file rx-retry.hpp \brief Retry this observable for the given number of times. \tparam Count the type of the counter (optional) \param t the total number of tries (optional), i.e. retry(2) means one normal try, before an error occurs, and one retry. If not specified, infinitely retries the source observable. Specifying 0 returns immediately without subscribing \return An observable that mirrors the source observable, resubscribing to it if it calls on_error up to a specified number of retries. \sample \snippet retry.cpp retry count sample \snippet output.txt retry count sample */ #if !defined(RXCPP_OPERATORS_RX_RETRY_HPP) #define RXCPP_OPERATORS_RX_RETRY_HPP #include "../rx-includes.hpp" #include "rx-retry-repeat-common.hpp" namespace rxcpp { namespace operators { namespace detail { template struct retry_invalid_arguments {}; template struct retry_invalid : public rxo::operator_base> { using type = observable, retry_invalid>; }; template using retry_invalid_t = typename retry_invalid::type; // Contain retry variations in a namespace namespace retry { struct event_handlers { template static inline void on_error(State& state, rxu::error_ptr& e) { state->update(); // Use specialized predicate for finite/infinte case if (state->completed_predicate()) { state->out.on_error(e); } else { state->do_subscribe(); } } template static inline void on_completed(State& state) { state->out.on_completed(); } }; // Finite repeat case (explicitely limited with the number of times) template using finite = ::rxcpp::operators::detail::retry_repeat_common::finite ; // Infinite repeat case template using infinite = ::rxcpp::operators::detail::retry_repeat_common::infinite ; } } // detail /*! @copydoc rx-retry.hpp */ template auto retry(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 Retry = rxo::detail::retry::infinite>, class Value = rxu::value_type_t, class Result = observable > static Result member(Observable&& o) { return Result(Retry(std::forward(o))); } template>, class SourceValue = rxu::value_type_t, class Retry = rxo::detail::retry::finite, rxu::decay_t>, class Value = rxu::value_type_t, class Result = observable > static Result member(Observable&& o, Count&& c) { return Result(Retry(std::forward(o), std::forward(c))); } template static operators::detail::retry_invalid_t member(const AN&...) { std::terminate(); return {}; static_assert(sizeof...(AN) == 10000, "retry takes (optional Count)"); } }; } #endif