• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // sender.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/sender.hpp>
18 
19 #include <boost/system/error_code.hpp>
20 #include "../unit_test.hpp"
21 
22 namespace exec = boost::asio::execution;
23 
24 struct not_a_sender
25 {
26 };
27 
28 struct sender_using_base :
29   boost::asio::execution::sender_base
30 {
sender_using_basesender_using_base31   sender_using_base()
32   {
33   }
34 };
35 
36 struct executor
37 {
executorexecutor38   executor()
39   {
40   }
41 
executorexecutor42   executor(const executor&) BOOST_ASIO_NOEXCEPT
43   {
44   }
45 
46 #if defined(BOOST_ASIO_HAS_MOVE)
executorexecutor47   executor(executor&&) BOOST_ASIO_NOEXCEPT
48   {
49   }
50 #endif // defined(BOOST_ASIO_HAS_MOVE)
51 
52   template <typename F>
executeexecutor53   void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
54   {
55     (void)f;
56   }
57 
operator ==executor58   bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
59   {
60     return true;
61   }
62 
operator !=executor63   bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
64   {
65     return false;
66   }
67 };
68 
69 namespace boost {
70 namespace asio {
71 namespace traits {
72 
73 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
74 
75 template <typename F>
76 struct execute_member<executor, F>
77 {
78   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
79   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
80   typedef void result_type;
81 };
82 
83 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
84 #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
85 
86 template <>
87 struct equality_comparable<executor>
88 {
89   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
90   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
91 };
92 
93 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
94 
95 } // namespace traits
96 } // namespace asio
97 } // namespace boost
98 
99 #if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
100 
101 struct operation_state
102 {
startoperation_state103   void start() BOOST_ASIO_NOEXCEPT
104   {
105   }
106 };
107 
108 namespace boost {
109 namespace asio {
110 namespace traits {
111 
112 #if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
113 
114 template <>
115 struct start_member<operation_state>
116 {
117   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
118   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
119   typedef void result_type;
120 };
121 
122 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
123 
124 } // namespace traits
125 } // namespace asio
126 } // namespace boost
127 
128 struct typed_sender
129 {
130   template <
131       template <typename...> class Tuple,
132       template <typename...> class Variant>
133   using value_types = Variant<Tuple<int>>;
134 
135   template <template <typename...> class Variant>
136   using error_types = Variant<boost::system::error_code>;
137 
138   BOOST_ASIO_STATIC_CONSTEXPR(bool, sends_done = true);
139 
typed_sendertyped_sender140   typed_sender()
141   {
142   }
143 
144   template <typename R>
connecttyped_sender145   operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
146   {
147     (void)r;
148     return operation_state();
149   }
150 };
151 
152 namespace boost {
153 namespace asio {
154 namespace traits {
155 
156 #if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
157 
158 template <typename R>
159 struct connect_member<const typed_sender, R>
160 {
161   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
162   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
163   typedef operation_state result_type;
164 };
165 
166 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
167 
168 } // namespace traits
169 } // namespace asio
170 } // namespace boost
171 
172 #endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
173 
174 template <typename T>
is_unspecialised(T *,...)175 bool is_unspecialised(T*, ...)
176 {
177   return false;
178 }
179 
180 template <typename T>
is_unspecialised(T *,typename boost::asio::void_type<typename exec::sender_traits<T>::asio_execution_sender_traits_base_is_unspecialised>::type *)181 bool is_unspecialised(T*,
182     typename boost::asio::void_type<
183       typename exec::sender_traits<
184         T>::asio_execution_sender_traits_base_is_unspecialised
185     >::type*)
186 {
187   return true;
188 }
189 
test_sender_traits()190 void test_sender_traits()
191 {
192   not_a_sender s1;
193   BOOST_ASIO_CHECK(is_unspecialised(&s1, static_cast<void*>(0)));
194 
195   sender_using_base s2;
196   BOOST_ASIO_CHECK(!is_unspecialised(&s2, static_cast<void*>(0)));
197 
198   executor s3;
199   BOOST_ASIO_CHECK(!is_unspecialised(&s3, static_cast<void*>(0)));
200 
201 #if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
202   typed_sender s4;
203   BOOST_ASIO_CHECK(!is_unspecialised(&s4, static_cast<void*>(0)));
204 #endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
205 }
206 
test_is_sender()207 void test_is_sender()
208 {
209   BOOST_ASIO_CHECK(!exec::is_sender<void>::value);
210   BOOST_ASIO_CHECK(!exec::is_sender<not_a_sender>::value);
211   BOOST_ASIO_CHECK(exec::is_sender<sender_using_base>::value);
212   BOOST_ASIO_CHECK(exec::is_sender<executor>::value);
213 
214 #if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
215   BOOST_ASIO_CHECK(exec::is_sender<typed_sender>::value);
216 #endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
217 }
218 
test_is_typed_sender()219 void test_is_typed_sender()
220 {
221   BOOST_ASIO_CHECK(!exec::is_typed_sender<void>::value);
222   BOOST_ASIO_CHECK(!exec::is_typed_sender<not_a_sender>::value);
223   BOOST_ASIO_CHECK(!exec::is_typed_sender<sender_using_base>::value);
224 
225 #if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
226   BOOST_ASIO_CHECK(exec::is_typed_sender<executor>::value);
227   BOOST_ASIO_CHECK(exec::is_typed_sender<typed_sender>::value);
228 #endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
229 }
230 
231 BOOST_ASIO_TEST_SUITE
232 (
233   "sender",
234   BOOST_ASIO_TEST_CASE(test_sender_traits)
235   BOOST_ASIO_TEST_CASE(test_is_sender)
236   BOOST_ASIO_TEST_CASE(test_is_typed_sender)
237 )
238