• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // bulk_execute.cpp
3 // ~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 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 // Disable autolinking for unit tests.
12 #if !defined(BOOST_ALL_NO_LIB)
13 #define BOOST_ALL_NO_LIB 1
14 #endif // !defined(BOOST_ALL_NO_LIB)
15 
16 // Test that header file is self-contained.
17 #include <boost/asio/execution/bulk_execute.hpp>
18 
19 #include <boost/asio/execution.hpp>
20 #include "../unit_test.hpp"
21 
22 namespace exec = boost::asio::execution;
23 
24 int call_count = 0;
25 
26 struct operation_state
27 {
startoperation_state28   void start() BOOST_ASIO_NOEXCEPT
29   {
30   }
31 };
32 
33 namespace boost {
34 namespace asio {
35 namespace traits {
36 
37 #if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
38 
39 template <>
40 struct start_member<operation_state>
41 {
42   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
43   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
44   typedef void result_type;
45 };
46 
47 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
48 
49 } // namespace traits
50 } // namespace asio
51 } // namespace boost
52 
53 struct sender : exec::sender_base
54 {
sendersender55   sender()
56   {
57   }
58 
59   template <typename R>
connectsender60   operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
61   {
62     (void)r;
63     return operation_state();
64   }
65 };
66 
67 namespace boost {
68 namespace asio {
69 namespace traits {
70 
71 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
72 
73 template <typename R>
74 struct connect_member<const sender, R>
75 {
76   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
77   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
78   typedef operation_state result_type;
79 };
80 
81 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
82 
83 } // namespace traits
84 } // namespace asio
85 } // namespace boost
86 
87 struct no_bulk_execute
88 {
89 };
90 
91 struct const_member_bulk_execute
92 {
const_member_bulk_executeconst_member_bulk_execute93   const_member_bulk_execute()
94   {
95   }
96 
97   template <typename F>
bulk_executeconst_member_bulk_execute98   sender bulk_execute(BOOST_ASIO_MOVE_ARG(F), std::size_t) const
99   {
100     ++call_count;
101     return sender();
102   }
103 };
104 
105 namespace boost {
106 namespace asio {
107 namespace traits {
108 
109 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
110 
111 template <typename F, typename N>
112 struct bulk_execute_member<const const_member_bulk_execute, F, N>
113 {
114   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
115   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
116   typedef sender result_type;
117 };
118 
119 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
120 
121 } // namespace traits
122 } // namespace asio
123 } // namespace boost
124 
125 struct free_bulk_execute
126 {
free_bulk_executefree_bulk_execute127   free_bulk_execute()
128   {
129   }
130 
131   template <typename F>
bulk_execute(const free_bulk_execute &,BOOST_ASIO_MOVE_ARG (F),std::size_t)132   friend sender bulk_execute(const free_bulk_execute&,
133       BOOST_ASIO_MOVE_ARG(F), std::size_t)
134   {
135     ++call_count;
136     return sender();
137   }
138 };
139 
140 namespace boost {
141 namespace asio {
142 namespace traits {
143 
144 #if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
145 
146 template <typename F, typename N>
147 struct bulk_execute_free<const free_bulk_execute, F, N>
148 {
149   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
150   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
151   typedef sender result_type;
152 };
153 
154 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
155 
156 } // namespace traits
157 } // namespace asio
158 } // namespace boost
159 
160 struct executor
161 {
executorexecutor162   executor()
163   {
164   }
165 
executorexecutor166   executor(const executor&) BOOST_ASIO_NOEXCEPT
167   {
168   }
169 
170 #if defined(BOOST_ASIO_HAS_MOVE)
executorexecutor171   executor(executor&&) BOOST_ASIO_NOEXCEPT
172   {
173   }
174 #endif // defined(BOOST_ASIO_HAS_MOVE)
175 
176   template <typename F>
executeexecutor177   void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
178   {
179     typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
180     tmp();
181   }
182 
operator ==executor183   bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
184   {
185     return true;
186   }
187 
operator !=executor188   bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
189   {
190     return false;
191   }
192 };
193 
194 namespace boost {
195 namespace asio {
196 namespace traits {
197 
198 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
199 
200 template <typename F>
201 struct execute_member<executor, F>
202 {
203   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
204   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
205   typedef void result_type;
206 };
207 
208 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
209 #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
210 
211 template <>
212 struct equality_comparable<executor>
213 {
214   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
215   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
216 };
217 
218 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
219 
220 } // namespace traits
221 } // namespace asio
222 } // namespace boost
223 
test_can_bulk_execute()224 void test_can_bulk_execute()
225 {
226   BOOST_ASIO_CONSTEXPR bool b1 = exec::can_bulk_execute<
227       no_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
228   BOOST_ASIO_CHECK(b1 == false);
229 
230   BOOST_ASIO_CONSTEXPR bool b2 = exec::can_bulk_execute<
231       const no_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
232   BOOST_ASIO_CHECK(b2 == false);
233 
234   BOOST_ASIO_CONSTEXPR bool b3 = exec::can_bulk_execute<
235       const_member_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
236   BOOST_ASIO_CHECK(b3 == true);
237 
238   BOOST_ASIO_CONSTEXPR bool b4 = exec::can_bulk_execute<
239       const const_member_bulk_execute&,
240       exec::invocable_archetype, std::size_t>::value;
241   BOOST_ASIO_CHECK(b4 == true);
242 
243   BOOST_ASIO_CONSTEXPR bool b5 = exec::can_bulk_execute<
244       free_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
245   BOOST_ASIO_CHECK(b5 == true);
246 
247   BOOST_ASIO_CONSTEXPR bool b6 = exec::can_bulk_execute<
248       const free_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
249   BOOST_ASIO_CHECK(b6 == true);
250 
251   BOOST_ASIO_CONSTEXPR bool b7 = exec::can_bulk_execute<
252       executor&, exec::invocable_archetype, std::size_t>::value;
253   BOOST_ASIO_CHECK(b7 == true);
254 
255   BOOST_ASIO_CONSTEXPR bool b8 = exec::can_bulk_execute<
256       const executor&, exec::invocable_archetype, std::size_t>::value;
257   BOOST_ASIO_CHECK(b8 == true);
258 }
259 
handler(std::size_t)260 void handler(std::size_t)
261 {
262 }
263 
counting_handler(std::size_t)264 void counting_handler(std::size_t)
265 {
266   ++call_count;
267 }
268 
completion_handler()269 void completion_handler()
270 {
271   ++call_count;
272 }
273 
test_bulk_execute()274 void test_bulk_execute()
275 {
276   call_count = 0;
277   const_member_bulk_execute ex1;
278   exec::bulk_execute(ex1, handler, 2);
279   BOOST_ASIO_CHECK(call_count == 1);
280 
281   call_count = 0;
282   const const_member_bulk_execute ex2;
283   exec::bulk_execute(ex2, handler, 2);
284   BOOST_ASIO_CHECK(call_count == 1);
285 
286   call_count = 0;
287   exec::bulk_execute(const_member_bulk_execute(), handler, 2);
288   BOOST_ASIO_CHECK(call_count == 1);
289 
290   call_count = 0;
291   free_bulk_execute ex3;
292   exec::bulk_execute(ex3, handler, 2);
293   BOOST_ASIO_CHECK(call_count == 1);
294 
295   call_count = 0;
296   const free_bulk_execute ex4;
297   exec::bulk_execute(ex4, handler, 2);
298   BOOST_ASIO_CHECK(call_count == 1);
299 
300   call_count = 0;
301   exec::bulk_execute(free_bulk_execute(), handler, 2);
302   BOOST_ASIO_CHECK(call_count == 1);
303 
304   call_count = 0;
305   executor ex5;
306   exec::execute(
307       exec::bulk_execute(ex5, counting_handler, 10u),
308       completion_handler);
309   BOOST_ASIO_CHECK(call_count == 11);
310 
311   call_count = 0;
312   const executor ex6;
313   exec::execute(
314       exec::bulk_execute(ex6, counting_handler, 10u),
315       completion_handler);
316   BOOST_ASIO_CHECK(call_count == 11);
317 
318   call_count = 0;
319   exec::execute(
320       exec::bulk_execute(executor(), counting_handler, 10u),
321       completion_handler);
322   BOOST_ASIO_CHECK(call_count == 11);
323 }
324 
325 BOOST_ASIO_TEST_SUITE
326 (
327   "bulk_execute",
328   BOOST_ASIO_TEST_CASE(test_can_bulk_execute)
329   BOOST_ASIO_TEST_CASE(test_bulk_execute)
330 )
331