3 #include <ozo/type_traits.h> 
    5 #include <ozo/deadline.h> 
    6 #include <ozo/connection.h> 
   23 #ifdef OZO_DOCUMENTATION 
  117 template <
typename T>
 
  129 template <
typename T>
 
  134 namespace ozo::failover {
 
  136 namespace hana = boost::hana;
 
  148     typename TimeConstraint,
 
  151     static_assert(ozo::TimeConstraint<TimeConstraint>, 
"TimeConstraint should models ozo::TimeConstraint");
 
  152     static_assert(ozo::ConnectionProvider<ConnectionProvider>, 
"ConnectionProvider should models ozo::ConnectionProvider");
 
  156     hana::tuple<std::decay_t<Args>...> 
args; 
 
  168       args(std::forward<Args>(
args)...) {}
 
  171 template <
typename FailoverStrategy, 
typename Operation>
 
  172 struct get_first_try_impl {
 
  173     template <
typename Allocator, 
typename ...Args>
 
  174     static auto apply(
const Operation& op, 
const FailoverStrategy& s, 
const Allocator& alloc, Args&& ...args) {
 
  175         return s.get_first_try(op, alloc, std::forward<Args>(args)...);
 
  212 template <
typename FailoverStrategy, 
typename Operation, 
typename Allocator, 
typename ...Args>
 
  214     return get_first_try_impl<FailoverStrategy, Operation>::apply(op, strategy, alloc, std::forward<Args>(args)...);
 
  217 template <
typename Try>
 
  218 struct get_try_context_impl {
 
  219     static decltype(
auto) apply(const Try& a_try) {
 
  220         return a_try.get_context();
 
  251 template <
typename FailoverTry>
 
  253     auto res = detail::apply<get_try_context_impl>(
ozo::unwrap(a_try));
 
  254     static_assert(HanaSequence<decltype(res)>,
 
  255         "get_try_context_impl::apply() should provide HanaSequence");
 
  259 template <
typename Try>
 
  260 struct get_next_try_impl {
 
  261     template <
typename Conn>
 
  262     static auto apply(Try& a_try, 
error_code ec, Conn&& conn) {
 
  263         return a_try.get_next_try(ec, conn);
 
  305 template <
typename Try, 
typename Connection>
 
  307     return detail::apply<get_next_try_impl>(
ozo::unwrap(a_try), ec, conn);
 
  310 template <
typename Try>
 
  311 struct initiate_next_try_impl {
 
  312     template <
typename Connection, 
typename Initiator>
 
  315             init(std::move(next));
 
  360 template <
typename Try, 
typename Connection, 
typename Initiator>
 
  362     return detail::apply<initiate_next_try_impl>(
ozo::unwrap(a_try), ec, conn, std::forward<Initiator>(init));
 
  367 template <
template<
typename...> 
typename Template, 
typename Allocator, 
typename ...Ts>
 
  368 static auto allocate_shared(
const Allocator& alloc, Ts&& ...vs) {
 
  369     using type = decltype(Template{std::forward<Ts>(vs)...});
 
  370     return std::allocate_shared<type>(alloc, std::forward<Ts>(vs)...);
 
  373 template <
typename Try, 
typename Operation, 
typename Handler>
 
  374 inline void initiate_operation(
const Operation&, Try&&, 
Handler&&);
 
  376 template <
typename Operation, 
typename Try, 
typename Handler>
 
  377 struct continuation {
 
  382     continuation(
const Operation& op, Try a_try, 
Handler handler)
 
  383     : op_(op), try_(std::move(a_try)), handler_(std::move(handler)) {}
 
  385     template <
typename Connection>
 
  387         static_assert(ozo::Connection<Connection>, 
"conn should model Connection concept");
 
  389             bool initiated = 
false;
 
  392                 initiate_operation(op_, std::move(next_try), std::move(handler_));
 
  400         handler_(std::move(ec), std::forward<Connection>(conn));
 
  403     using executor_type = decltype(asio::get_associated_executor(handler_));
 
  406         return asio::get_associated_executor(handler_);
 
  409     using allocator_type = decltype(asio::get_associated_allocator(handler_));
 
  411     allocator_type get_allocator()
 const {
 
  412         return asio::get_associated_allocator(handler_);
 
  416 template <
typename Try, 
typename Operation, 
typename Handler>
 
  417 inline void initiate_operation(
const Operation& op, Try&& a_try, 
Handler&& handler) {
 
  420             continuation{op, std::forward<Try>(a_try), std::forward<Handler>(handler)},
 
  421             std::forward<decltype(args)>(args)...
 
  426 template <
typename FailoverStrategy, 
typename Operation>
 
  427 struct operation_initiator {
 
  431     constexpr operation_initiator(
FailoverStrategy strategy, 
const Operation& op)
 
  432     : strategy_(std::move(strategy)), op_(op) {}
 
  434     template <
typename Handler, 
typename ...Args>
 
  435     void operator() (
Handler&& handler, Args&& ...args)
 const {
 
  436         auto first_try = 
get_first_try(op_, strategy_, asio::get_associated_allocator(handler), std::forward<Args>(args)...);
 
  437         initiate_operation(op_, std::move(first_try), std::forward<Handler>(handler));
 
  443 struct construct_initiator_impl {
 
  444     template <
typename FailoverStrategy, 
typename Op>
 
  446         return detail::operation_initiator(std::forward<FailoverStrategy>(strategy), op);