]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // |
2 | // experimental/as_single.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_EXPERIMENTAL_AS_SINGLE_HPP | |
12 | #define BOOST_ASIO_EXPERIMENTAL_AS_SINGLE_HPP | |
13 | ||
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 | # pragma once | |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | ||
18 | #include <boost/asio/detail/config.hpp> | |
19 | #include <boost/asio/detail/type_traits.hpp> | |
20 | ||
21 | #include <boost/asio/detail/push_options.hpp> | |
22 | ||
23 | namespace boost { | |
24 | namespace asio { | |
25 | namespace experimental { | |
26 | ||
27 | /// Completion token type used to specify that the completion handler | |
28 | /// arguments should be combined into a single argument. | |
29 | /** | |
30 | * The as_single_t class is used to indicate that any arguments to the | |
31 | * completion handler should be combined and passed as a single argument. | |
32 | * If there is already one argument, that argument is passed as-is. If | |
33 | * there is more than argument, the arguments are first moved into a | |
34 | * @c std::tuple and that tuple is then passed to the completion handler. | |
35 | */ | |
36 | template <typename CompletionToken> | |
37 | class as_single_t | |
38 | { | |
39 | public: | |
40 | /// Tag type used to prevent the "default" constructor from being used for | |
41 | /// conversions. | |
42 | struct default_constructor_tag {}; | |
43 | ||
44 | /// Default constructor. | |
45 | /** | |
46 | * This constructor is only valid if the underlying completion token is | |
47 | * default constructible and move constructible. The underlying completion | |
48 | * token is itself defaulted as an argument to allow it to capture a source | |
49 | * location. | |
50 | */ | |
51 | BOOST_ASIO_CONSTEXPR as_single_t( | |
52 | default_constructor_tag = default_constructor_tag(), | |
53 | CompletionToken token = CompletionToken()) | |
54 | : token_(BOOST_ASIO_MOVE_CAST(CompletionToken)(token)) | |
55 | { | |
56 | } | |
57 | ||
58 | /// Constructor. | |
59 | template <typename T> | |
60 | BOOST_ASIO_CONSTEXPR explicit as_single_t( | |
61 | BOOST_ASIO_MOVE_ARG(T) completion_token) | |
62 | : token_(BOOST_ASIO_MOVE_CAST(T)(completion_token)) | |
63 | { | |
64 | } | |
65 | ||
66 | /// Adapts an executor to add the @c as_single_t completion token as the | |
67 | /// default. | |
68 | template <typename InnerExecutor> | |
69 | struct executor_with_default : InnerExecutor | |
70 | { | |
71 | /// Specify @c as_single_t as the default completion token type. | |
72 | typedef as_single_t default_completion_token_type; | |
73 | ||
74 | /// Construct the adapted executor from the inner executor type. | |
75 | executor_with_default(const InnerExecutor& ex) BOOST_ASIO_NOEXCEPT | |
76 | : InnerExecutor(ex) | |
77 | { | |
78 | } | |
79 | ||
80 | /// Convert the specified executor to the inner executor type, then use | |
81 | /// that to construct the adapted executor. | |
82 | template <typename OtherExecutor> | |
83 | executor_with_default(const OtherExecutor& ex, | |
84 | typename enable_if< | |
85 | is_convertible<OtherExecutor, InnerExecutor>::value | |
86 | >::type* = 0) BOOST_ASIO_NOEXCEPT | |
87 | : InnerExecutor(ex) | |
88 | { | |
89 | } | |
90 | }; | |
91 | ||
92 | /// Type alias to adapt an I/O object to use @c as_single_t as its | |
93 | /// default completion token type. | |
94 | #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) \ | |
95 | || defined(GENERATING_DOCUMENTATION) | |
96 | template <typename T> | |
97 | using as_default_on_t = typename T::template rebind_executor< | |
98 | executor_with_default<typename T::executor_type> >::other; | |
99 | #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) | |
100 | // || defined(GENERATING_DOCUMENTATION) | |
101 | ||
102 | /// Function helper to adapt an I/O object to use @c as_single_t as its | |
103 | /// default completion token type. | |
104 | template <typename T> | |
105 | static typename decay<T>::type::template rebind_executor< | |
106 | executor_with_default<typename decay<T>::type::executor_type> | |
107 | >::other | |
108 | as_default_on(BOOST_ASIO_MOVE_ARG(T) object) | |
109 | { | |
110 | return typename decay<T>::type::template rebind_executor< | |
111 | executor_with_default<typename decay<T>::type::executor_type> | |
112 | >::other(BOOST_ASIO_MOVE_CAST(T)(object)); | |
113 | } | |
114 | ||
115 | //private: | |
116 | CompletionToken token_; | |
117 | }; | |
118 | ||
119 | /// Create a completion token to specify that the completion handler arguments | |
120 | /// should be combined into a single argument. | |
121 | template <typename CompletionToken> | |
122 | inline BOOST_ASIO_CONSTEXPR as_single_t<typename decay<CompletionToken>::type> | |
123 | as_single(BOOST_ASIO_MOVE_ARG(CompletionToken) completion_token) | |
124 | { | |
125 | return as_single_t<typename decay<CompletionToken>::type>( | |
126 | BOOST_ASIO_MOVE_CAST(CompletionToken)(completion_token)); | |
127 | } | |
128 | ||
129 | } // namespace experimental | |
130 | } // namespace asio | |
131 | } // namespace boost | |
132 | ||
133 | #include <boost/asio/detail/pop_options.hpp> | |
134 | ||
135 | #include <boost/asio/experimental/impl/as_single.hpp> | |
136 | ||
137 | #endif // BOOST_ASIO_EXPERIMENTAL_AS_SINGLE_HPP |