1
0
miroir de https://github.com/tearshark/librf.git synchronisé 2024-10-01 15:57:07 +08:00
librf/asio/asio_task_1.12.0.inl
2021-11-01 17:59:08 +08:00

197 lignes
5.5 KiB
C++
Brut Annotations Historique

Ce fichier contient des caractères Unicode ambigus.

Ce fichier contient des caractères Unicode qui peuvent être confondus avec d'autres caractères. Si vous pensez que c'est intentionnel, vous pouvez ignorer cet avertissement. Utilisez le bouton Échappe pour les dévoiler.

#include <memory>
#include "asio/detail/push_options.hpp"
namespace asio {
/**
* @brief 用于指示asio相关异步函数返回librf::future_t<>的类型,从而变成支持 librf 的协程函数。
*/
template <typename Executor = executor>
struct rf_task_t
{
ASIO_CONSTEXPR rf_task_t() {}
};
/**
* @brief 用于指示asio相关异步函数返回librf::future_t<>的常量,从而变成支持 librf 的协程函数。
*/
constexpr rf_task_t<> rf_task;
namespace librf {
template <typename Executor, typename T>
struct promise_handler_base
{
public:
typedef T result_type;
typedef librf::state_t<result_type> state_type;
promise_handler_base()
: state_(librf::state_future_t::_Alloc_state<state_type>(true))
{
}
librf::counted_ptr<state_type> state_;
promise_handler_base(promise_handler_base &&) = default;
promise_handler_base(const promise_handler_base &) = default;
promise_handler_base & operator = (promise_handler_base &&) = default;
promise_handler_base & operator = (const promise_handler_base &) = default;
};
template <typename, typename...>
struct promise_handler;
template <typename Executor>
struct promise_handler<Executor, void> : public promise_handler_base<Executor, void>
{
using promise_handler_base<Executor, void>::promise_handler_base;
void operator()() const
{
this->state_->set_value();
}
};
template <typename Executor>
struct promise_handler<Executor, asio::error_code> : public promise_handler_base<Executor, void>
{
using promise_handler_base<Executor, void>::promise_handler_base;
void operator()(const asio::error_code& ec) const
{
if (!ec)
this->state_->set_value();
else
this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec)));
}
};
template <typename Executor>
struct promise_handler<Executor, std::exception_ptr> : public promise_handler_base<Executor, void>
{
using promise_handler_base<Executor, void>::promise_handler_base;
void operator()(std::exception_ptr ex) const
{
if (!ex)
this->state_->set_value();
else
this->state_->set_exception(ex);
}
};
template <typename Executor, typename T>
struct promise_handler<Executor, T> : public promise_handler_base<Executor, T>
{
using promise_handler_base<Executor, T>::promise_handler_base;
template <typename Arg>
void operator()(Arg&& arg) const
{
this->state_->set_value(std::forward<Arg>(arg));
}
};
template <typename Executor, typename T>
struct promise_handler<Executor, asio::error_code, T> : public promise_handler_base<Executor, T>
{
using promise_handler_base<Executor, T>::promise_handler_base;
template <typename Arg>
void operator()(const asio::error_code& ec, Arg&& arg) const
{
if (!ec)
this->state_->set_value(std::forward<Arg>(arg));
else
this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec)));
}
};
template <typename Executor, typename T>
struct promise_handler<Executor, std::exception_ptr, T> : public promise_handler_base<Executor, T>
{
using promise_handler_base<Executor, T>::promise_handler_base;
template <typename Arg>
void operator()(std::exception_ptr ex, Arg&& arg) const
{
if (!ex)
this->state_->set_value(std::forward<Arg>(arg));
else
this->state_->set_exception(ex);
}
};
template <typename Executor, typename... Ts>
struct promise_handler : public promise_handler_base<Executor, std::tuple<Ts...>>
{
using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base;
template <typename... Args>
void operator()(Args&&... args) const
{
this->state_->set_value(std::make_tuple(std::forward<Args>(args)...));
}
};
template <typename Executor, typename... Ts>
struct promise_handler<Executor, asio::error_code, Ts...> : public promise_handler_base<Executor, std::tuple<Ts...>>
{
using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base;
template <typename... Args>
void operator()(const asio::error_code& ec, Args&&... args) const
{
if (!ec)
this->state_->set_value(std::make_tuple(std::forward<Args>(args)...));
else
this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec)));
}
};
template <typename Executor, typename... Ts>
struct promise_handler<Executor, std::exception_ptr, Ts...> : public promise_handler_base<Executor, std::tuple<Ts...>>
{
using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base;
template <typename... Args>
void operator()(std::exception_ptr ex, Args&&... args) const
{
if (!ex)
this->state_->set_value(std::make_tuple(std::forward<Args>(args)...));
else
this->state_->set_exception(ex);
}
};
} // namespace librf
template <typename Executor, typename R, typename... Args>
class async_result<rf_task_t<Executor>, R(Args...)>
{
public:
typedef librf::promise_handler<Executor, Args...> handler_type;
typedef typename handler_type::result_type result_type;
typedef librf::future_t<result_type> return_type;
template <typename Initiation, typename... InitArgs>
static return_type initiate(ASIO_MOVE_ARG(Initiation) initiation,
rf_task_t<Executor>, ASIO_MOVE_ARG(InitArgs)... args)
{
handler_type handler{};
return_type future{ handler.state_ };
std::move(initiation)(std::move(handler), std::move(args)...);
return std::move(future);
}
};
} // namespace asio
#include "asio/detail/pop_options.hpp"