• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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