1 //
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9 
10 #ifndef BOOST_BEAST_DETAIL_GET_IO_CONTEXT_HPP
11 #define BOOST_BEAST_DETAIL_GET_IO_CONTEXT_HPP
12 
13 #include <boost/beast/core/stream_traits.hpp>
14 #include <boost/asio/executor.hpp>
15 #include <boost/asio/io_context.hpp>
16 #include <boost/asio/strand.hpp>
17 #include <memory>
18 #include <type_traits>
19 
20 namespace boost {
21 namespace beast {
22 namespace detail {
23 
24 //------------------------------------------------------------------------------
25 
26 inline
27 net::io_context*
get_io_context(net::io_context & ioc)28 get_io_context(net::io_context& ioc)
29 {
30     return std::addressof(ioc);
31 }
32 
33 inline
34 net::io_context*
get_io_context(net::io_context::executor_type const & ex)35 get_io_context(net::io_context::executor_type const& ex)
36 {
37     return std::addressof(ex.context());
38 }
39 
40 inline
41 net::io_context*
get_io_context(net::strand<net::io_context::executor_type> const & ex)42 get_io_context(net::strand<
43     net::io_context::executor_type> const& ex)
44 {
45     return std::addressof(
46         ex.get_inner_executor().context());
47 }
48 
49 template<class Executor>
50 net::io_context*
get_io_context(net::strand<Executor> const & ex)51 get_io_context(net::strand<Executor> const& ex)
52 {
53     return get_io_context(ex.get_inner_executor());
54 }
55 
56 template<
57     class T,
58     class = typename std::enable_if<
59         std::is_same<T, net::executor>::value>::type>
60 net::io_context*
get_io_context(T const & ex)61 get_io_context(T const& ex)
62 {
63     auto p = ex.template target<typename
64         net::io_context::executor_type>();
65     if(! p)
66         return nullptr;
67     return std::addressof(p->context());
68 }
69 
70 inline
71 net::io_context*
get_io_context(...)72 get_io_context(...)
73 {
74     return nullptr;
75 }
76 
77 //------------------------------------------------------------------------------
78 
79 template<class T>
80 net::io_context*
get_io_context_impl(T & t,std::true_type)81 get_io_context_impl(T& t, std::true_type)
82 {
83     return get_io_context(
84         t.get_executor());
85 }
86 
87 template<class T>
88 net::io_context*
get_io_context_impl(T const &,std::false_type)89 get_io_context_impl(T const&, std::false_type)
90 {
91     return nullptr;
92 }
93 
94 // Returns the io_context*, or nullptr, for any object.
95 template<class T>
96 net::io_context*
get_io_context(T & t)97 get_io_context(T& t)
98 {
99     return get_io_context_impl(t,
100         has_get_executor<T>{});
101 }
102 
103 } // detail
104 } // beast
105 } // boost
106 
107 #endif
108