1 // 2 // sender.cpp 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 // 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