Nexus HTTP/3
A QUIC and HTTP/3 library
stream_open_handler.hpp
1 #pragma once
2 
3 #include <memory>
4 #include <boost/asio/associated_allocator.hpp>
5 #include <boost/asio/associated_executor.hpp>
6 #include <nexus/error_code.hpp>
7 
8 namespace nexus::quic::detail {
9 
10 struct stream_impl;
11 
14 template <typename Stream>
15 struct stream_factory {
16  static Stream create(std::unique_ptr<stream_impl> s) { return s; }
17 };
18 
21 template <typename Stream, typename Handler>
22 struct stream_open_handler {
23  Handler handler;
24  explicit stream_open_handler(Handler&& handler)
25  : handler(std::move(handler))
26  {}
27  void operator()(error_code ec, std::unique_ptr<stream_impl> s) &
28  {
29  handler(ec, stream_factory<Stream>::create(std::move(s)));
30  }
31  void operator()(error_code ec, std::unique_ptr<stream_impl> s) &&
32  {
33  std::move(handler)(ec, stream_factory<Stream>::create(std::move(s)));
34  }
35 
36  using allocator_type = boost::asio::associated_allocator_t<Handler>;
37  allocator_type get_allocator() const noexcept {
38  return boost::asio::get_associated_allocator(handler);
39  }
40 };
41 
42 } // namespace nexus::quic::detail
43 
44 namespace boost::asio {
45 
46 // specialize associated_executor<> for stream_open_handler
47 template <typename Stream, typename Handler, typename Executor>
48 struct associated_executor<nexus::quic::detail::stream_open_handler<Stream, Handler>, Executor> {
49  using type = associated_executor_t<Handler, Executor>;
50 
51  static type get(const nexus::quic::detail::stream_open_handler<Stream, Handler>& handler,
52  const Executor& ex = Executor()) noexcept {
53  return get_associated_executor(handler.handler, ex);
54  }
55 };
56 
57 } // namespace boost::asio
networking
Definition: error_code.hpp:8