• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // io_object_impl.hpp
3 // ~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef BOOST_ASIO_DETAIL_IO_OBJECT_IMPL_HPP
12 #define BOOST_ASIO_DETAIL_IO_OBJECT_IMPL_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include <new>
19 #include <boost/asio/detail/config.hpp>
20 #include <boost/asio/detail/type_traits.hpp>
21 #include <boost/asio/execution/executor.hpp>
22 #include <boost/asio/execution/context.hpp>
23 #include <boost/asio/io_context.hpp>
24 #include <boost/asio/query.hpp>
25 
26 #include <boost/asio/detail/push_options.hpp>
27 
28 namespace boost {
29 namespace asio {
30 namespace detail {
31 
32 template <typename IoObjectService,
33     typename Executor = io_context::executor_type>
34 class io_object_impl
35 {
36 public:
37   // The type of the service that will be used to provide I/O operations.
38   typedef IoObjectService service_type;
39 
40   // The underlying implementation type of I/O object.
41   typedef typename service_type::implementation_type implementation_type;
42 
43   // The type of the executor associated with the object.
44   typedef Executor executor_type;
45 
46   // Construct an I/O object using an executor.
io_object_impl(const executor_type & ex)47   explicit io_object_impl(const executor_type& ex)
48     : service_(&boost::asio::use_service<IoObjectService>(
49           io_object_impl::get_context(ex))),
50       executor_(ex)
51   {
52     service_->construct(implementation_);
53   }
54 
55   // Construct an I/O object using an execution context.
56   template <typename ExecutionContext>
io_object_impl(ExecutionContext & context,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)57   explicit io_object_impl(ExecutionContext& context,
58       typename enable_if<is_convertible<
59         ExecutionContext&, execution_context&>::value>::type* = 0)
60     : service_(&boost::asio::use_service<IoObjectService>(context)),
61       executor_(context.get_executor())
62   {
63     service_->construct(implementation_);
64   }
65 
66 #if defined(BOOST_ASIO_HAS_MOVE)
67   // Move-construct an I/O object.
io_object_impl(io_object_impl && other)68   io_object_impl(io_object_impl&& other)
69     : service_(&other.get_service()),
70       executor_(other.get_executor())
71   {
72     service_->move_construct(implementation_, other.implementation_);
73   }
74 
75   // Perform a converting move-construction of an I/O object.
76   template <typename IoObjectService1, typename Executor1>
io_object_impl(io_object_impl<IoObjectService1,Executor1> && other)77   io_object_impl(io_object_impl<IoObjectService1, Executor1>&& other)
78     : service_(&boost::asio::use_service<IoObjectService>(
79             io_object_impl::get_context(other.get_executor()))),
80       executor_(other.get_executor())
81   {
82     service_->converting_move_construct(implementation_,
83         other.get_service(), other.get_implementation());
84   }
85 #endif // defined(BOOST_ASIO_HAS_MOVE)
86 
87   // Destructor.
~io_object_impl()88   ~io_object_impl()
89   {
90     service_->destroy(implementation_);
91   }
92 
93 #if defined(BOOST_ASIO_HAS_MOVE)
94   // Move-assign an I/O object.
operator =(io_object_impl && other)95   io_object_impl& operator=(io_object_impl&& other)
96   {
97     if (this != &other)
98     {
99       service_->move_assign(implementation_,
100           *other.service_, other.implementation_);
101       executor_.~executor_type();
102       new (&executor_) executor_type(
103           std::move(other.executor_));
104       service_ = other.service_;
105     }
106     return *this;
107   }
108 #endif // defined(BOOST_ASIO_HAS_MOVE)
109 
110   // Get the executor associated with the object.
get_executor()111   const executor_type& get_executor() BOOST_ASIO_NOEXCEPT
112   {
113     return executor_;
114   }
115 
116   // Get the service associated with the I/O object.
get_service()117   service_type& get_service()
118   {
119     return *service_;
120   }
121 
122   // Get the service associated with the I/O object.
get_service() const123   const service_type& get_service() const
124   {
125     return *service_;
126   }
127 
128   // Get the underlying implementation of the I/O object.
get_implementation()129   implementation_type& get_implementation()
130   {
131     return implementation_;
132   }
133 
134   // Get the underlying implementation of the I/O object.
get_implementation() const135   const implementation_type& get_implementation() const
136   {
137     return implementation_;
138   }
139 
140 private:
141   // Helper function to get an executor's context.
142   template <typename T>
get_context(const T & t,typename enable_if<execution::is_executor<T>::value>::type * =0)143   static execution_context& get_context(const T& t,
144       typename enable_if<execution::is_executor<T>::value>::type* = 0)
145   {
146     return boost::asio::query(t, execution::context);
147   }
148 
149   // Helper function to get an executor's context.
150   template <typename T>
get_context(const T & t,typename enable_if<!execution::is_executor<T>::value>::type * =0)151   static execution_context& get_context(const T& t,
152       typename enable_if<!execution::is_executor<T>::value>::type* = 0)
153   {
154     return t.context();
155   }
156 
157   // Disallow copying and copy assignment.
158   io_object_impl(const io_object_impl&);
159   io_object_impl& operator=(const io_object_impl&);
160 
161   // The service associated with the I/O object.
162   service_type* service_;
163 
164   // The underlying implementation of the I/O object.
165   implementation_type implementation_;
166 
167   // The associated executor.
168   executor_type executor_;
169 };
170 
171 } // namespace detail
172 } // namespace asio
173 } // namespace boost
174 
175 #include <boost/asio/detail/pop_options.hpp>
176 
177 #endif // BOOST_ASIO_DETAIL_IO_OBJECT_IMPL_HPP
178