1 //
2 // set_error.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/set_error.hpp>
18 
19 #include <boost/system/error_code.hpp>
20 #include "../unit_test.hpp"
21 
22 namespace exec = boost::asio::execution;
23 
24 static int call_count = 0;
25 
26 struct no_set_error
27 {
28 };
29 
30 struct const_member_set_error
31 {
32   template <typename E>
set_errorconst_member_set_error33   void set_error(BOOST_ASIO_MOVE_ARG(E) e) const BOOST_ASIO_NOEXCEPT
34   {
35     typename boost::asio::decay<E>::type tmp(BOOST_ASIO_MOVE_CAST(E)(e));
36     (void)tmp;
37     ++call_count;
38   }
39 };
40 
41 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
42 
43 namespace boost {
44 namespace asio {
45 namespace traits {
46 
47 template <typename E>
48 struct set_error_member<const const_member_set_error, E>
49 {
50   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
51   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
52   typedef void result_type;
53 };
54 
55 } // namespace traits
56 } // namespace asio
57 } // namespace boost
58 
59 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
60 
61 struct free_set_error_const_receiver
62 {
63   template <typename E>
set_error(const free_set_error_const_receiver &,BOOST_ASIO_MOVE_ARG (E)e)64   friend void set_error(const free_set_error_const_receiver&,
65       BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
66   {
67     typename boost::asio::decay<E>::type tmp(BOOST_ASIO_MOVE_CAST(E)(e));
68     (void)tmp;
69     ++call_count;
70   }
71 };
72 
73 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)
74 
75 namespace boost {
76 namespace asio {
77 namespace traits {
78 
79 template <typename E>
80 struct set_error_free<const free_set_error_const_receiver, E>
81 {
82   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
83   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
84   typedef void result_type;
85 };
86 
87 } // namespace traits
88 } // namespace asio
89 } // namespace boost
90 
91 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)
92 
93 struct non_const_member_set_error
94 {
95   template <typename E>
set_errornon_const_member_set_error96   void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
97   {
98     typename boost::asio::decay<E>::type tmp(BOOST_ASIO_MOVE_CAST(E)(e));
99     (void)tmp;
100     ++call_count;
101   }
102 };
103 
104 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
105 
106 namespace boost {
107 namespace asio {
108 namespace traits {
109 
110 template <typename E>
111 struct set_error_member<non_const_member_set_error, E>
112 {
113   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
114   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
115   typedef void result_type;
116 };
117 
118 } // namespace traits
119 } // namespace asio
120 } // namespace boost
121 
122 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
123 
124 struct free_set_error_non_const_receiver
125 {
126   template <typename E>
set_error(free_set_error_non_const_receiver &,BOOST_ASIO_MOVE_ARG (E)e)127   friend void set_error(free_set_error_non_const_receiver&,
128       BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
129   {
130     typename boost::asio::decay<E>::type tmp(BOOST_ASIO_MOVE_CAST(E)(e));
131     (void)tmp;
132     ++call_count;
133   }
134 };
135 
136 #if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)
137 
138 namespace boost {
139 namespace asio {
140 namespace traits {
141 
142 template <typename E>
143 struct set_error_free<free_set_error_non_const_receiver, E>
144 {
145   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
146   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
147   typedef void result_type;
148 };
149 
150 } // namespace traits
151 } // namespace asio
152 } // namespace boost
153 
154 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)
155 
test_can_set_error()156 void test_can_set_error()
157 {
158   BOOST_ASIO_CONSTEXPR bool b1 = exec::can_set_error<
159       no_set_error&, boost::system::error_code>::value;
160   BOOST_ASIO_CHECK(b1 == false);
161 
162   BOOST_ASIO_CONSTEXPR bool b2 = exec::can_set_error<
163       const no_set_error&, boost::system::error_code>::value;
164   BOOST_ASIO_CHECK(b2 == false);
165 
166   BOOST_ASIO_CONSTEXPR bool b3 = exec::can_set_error<
167       const_member_set_error&, boost::system::error_code>::value;
168   BOOST_ASIO_CHECK(b3 == true);
169 
170   BOOST_ASIO_CONSTEXPR bool b4 = exec::can_set_error<
171       const const_member_set_error&, boost::system::error_code>::value;
172   BOOST_ASIO_CHECK(b4 == true);
173 
174   BOOST_ASIO_CONSTEXPR bool b5 = exec::can_set_error<
175       free_set_error_const_receiver&, boost::system::error_code>::value;
176   BOOST_ASIO_CHECK(b5 == true);
177 
178   BOOST_ASIO_CONSTEXPR bool b6 = exec::can_set_error<
179       const free_set_error_const_receiver&, boost::system::error_code>::value;
180   BOOST_ASIO_CHECK(b6 == true);
181 
182   BOOST_ASIO_CONSTEXPR bool b7 = exec::can_set_error<
183       non_const_member_set_error&, boost::system::error_code>::value;
184   BOOST_ASIO_CHECK(b7 == true);
185 
186   BOOST_ASIO_CONSTEXPR bool b8 = exec::can_set_error<
187       const non_const_member_set_error&, boost::system::error_code>::value;
188   BOOST_ASIO_CHECK(b8 == false);
189 
190   BOOST_ASIO_CONSTEXPR bool b9 = exec::can_set_error<
191       free_set_error_non_const_receiver&, boost::system::error_code>::value;
192   BOOST_ASIO_CHECK(b9 == true);
193 
194   BOOST_ASIO_CONSTEXPR bool b10 = exec::can_set_error<
195       const free_set_error_non_const_receiver&, boost::system::error_code>::value;
196   BOOST_ASIO_CHECK(b10 == false);
197 }
198 
increment(int * count)199 void increment(int* count)
200 {
201   ++(*count);
202 }
203 
test_set_error()204 void test_set_error()
205 {
206   boost::system::error_code ec;
207 
208   call_count = 0;
209   const_member_set_error ex1 = {};
210   exec::set_error(ex1, ec);
211   BOOST_ASIO_CHECK(call_count == 1);
212 
213   call_count = 0;
214   const const_member_set_error ex2 = {};
215   exec::set_error(ex2, ec);
216   BOOST_ASIO_CHECK(call_count == 1);
217 
218   call_count = 0;
219   exec::set_error(const_member_set_error(), ec);
220   BOOST_ASIO_CHECK(call_count == 1);
221 
222   call_count = 0;
223   free_set_error_const_receiver ex3 = {};
224   exec::set_error(ex3, ec);
225   BOOST_ASIO_CHECK(call_count == 1);
226 
227   call_count = 0;
228   const free_set_error_const_receiver ex4 = {};
229   exec::set_error(ex4, ec);
230   BOOST_ASIO_CHECK(call_count == 1);
231 
232   call_count = 0;
233   exec::set_error(free_set_error_const_receiver(), ec);
234   BOOST_ASIO_CHECK(call_count == 1);
235 
236   call_count = 0;
237   non_const_member_set_error ex5 = {};
238   exec::set_error(ex5, ec);
239   BOOST_ASIO_CHECK(call_count == 1);
240 
241   call_count = 0;
242   free_set_error_non_const_receiver ex6 = {};
243   exec::set_error(ex6, ec);
244   BOOST_ASIO_CHECK(call_count == 1);
245 }
246 
247 BOOST_ASIO_TEST_SUITE
248 (
249   "set_error",
250   BOOST_ASIO_TEST_CASE(test_can_set_error)
251   BOOST_ASIO_TEST_CASE(test_set_error)
252 )
253