daily pastebin goal
17%
SHARE
TWEET

Untitled

a guest Apr 20th, 2018 57 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2.  
  3. #include <exception>
  4. #include <variant>
  5.  
  6. #include <experimental/coroutine>
  7. #include <experimental/net>
  8.  
  9. namespace ams::async {
  10. using std::experimental::coroutine_handle;
  11.  
  12. template <typename Object, typename Function, typename Result>
  13. struct Awaiter {
  14.   Object& _object;
  15.   Function _func;
  16.   std::variant<std::monostate, Result, std::error_code> _result;
  17.  
  18.   Awaiter(Object& object, Function&& func)
  19.       : _object{object}, _func{std::forward<Function>(func)}, _result{} {}
  20.  
  21.   bool await_ready() { return false; }
  22.  
  23.   Result await_resume() {
  24.     if (_result.index() == 2) throw std::system_error(std::get<2>(_result));
  25.  
  26.     return std::get<1>(std::move(_result));
  27.   }
  28.  
  29.   void await_suspend(coroutine_handle<> coro) {
  30.     _func(_object, [this, coro](std::error_code const& ec, Result r) mutable {
  31.       if (!ec) {
  32.         _result.template emplace<1>(std::move(r));
  33.       } else {
  34.         _result.template emplace<2>(ec);
  35.       }
  36.       coro.resume();
  37.     });
  38.   }
  39. };
  40.  
  41. template <typename Object, typename Function>
  42. struct Awaiter<Object, Function, void> {
  43.   Object& _object;
  44.   Function _func;
  45.   std::variant<std::monostate, std::error_code> _result;
  46.  
  47.   Awaiter(Object& object, Function&& func)
  48.       : _object{object}, _func{std::forward<Function>(func)}, _result{} {}
  49.  
  50.   bool await_ready() { return false; }
  51.  
  52.   void await_resume() {
  53.     if (_result.index() == 1) throw std::system_error(std::get<1>(_result));
  54.   }
  55.  
  56.   void await_suspend(coroutine_handle<> coro) {
  57.     _func(_object, [this, coro](std::error_code const& ec) mutable {
  58.       if (ec) {
  59.         this->_result.template emplace<1>(ec);
  60.       }
  61.       coro.resume();
  62.     });
  63.   }
  64. };
  65.  
  66. template <typename Result, typename Object, typename Function>
  67. auto make_awaiter(Object& object, Function&& function) {
  68.   return Awaiter<Object, Function, Result>{object,
  69.                                            std::forward<Function>(function)};
  70. }
  71.  
  72. template <typename Acceptor>
  73. auto async_accept(Acceptor& a) {
  74.   return make_awaiter<typename Acceptor::protocol_type::socket>(
  75.       a, [](Acceptor& acceptor, auto&& callback) {
  76.         acceptor.async_accept(std::forward<decltype(callback)>(callback));
  77.       });
  78. }
  79.  
  80. template <typename Socket, typename Endpoint>
  81. auto async_connect(Socket& socket, Endpoint ep) {
  82.   return make_awaiter<void>(
  83.       socket, [ep = std::move(ep)](Socket & socket, auto&& callback) {
  84.         socket.async_connect(ep, std::forward<decltype(callback)>(callback));
  85.       });
  86. }
  87.  
  88. template <typename Socket, typename MutableBuffer>
  89. auto async_read(Socket& socket, MutableBuffer buffer) {
  90.   return make_awaiter<const unsigned long>(
  91.       socket, [buffer = std::move(buffer)](Socket & socket, auto&& callback) {
  92.         std::experimental::net::async_read(
  93.             socket, buffer, std::forward<decltype(callback)>(callback));
  94.       });
  95. }
  96.  
  97. template <typename Socket, typename ConstantBuffer>
  98. auto async_write(Socket& socket, ConstantBuffer buffer) {
  99.   return make_awaiter<const unsigned long>(
  100.       socket, [buffer = std::move(buffer)](Socket & socket, auto&& callback) {
  101.         std::experimental::net::async_write(
  102.             socket, buffer, std::forward<decltype(callback)>(callback));
  103.       });
  104. }
  105. }  // namespace ams::async
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top