/src/boost/boost/system/result.hpp
Line | Count | Source |
1 | | #ifndef BOOST_SYSTEM_RESULT_HPP_INCLUDED |
2 | | #define BOOST_SYSTEM_RESULT_HPP_INCLUDED |
3 | | |
4 | | // Copyright 2017, 2021-2025 Peter Dimov. |
5 | | // Distributed under the Boost Software License, Version 1.0. |
6 | | // https://www.boost.org/LICENSE_1_0.txt |
7 | | |
8 | | #include <boost/system/errc.hpp> |
9 | | #include <boost/system/system_error.hpp> |
10 | | #include <boost/system/detail/error_code.hpp> |
11 | | #include <boost/system/detail/error_category_impl.hpp> |
12 | | #include <boost/variant2/variant.hpp> |
13 | | #include <boost/compat/invoke.hpp> |
14 | | #include <boost/throw_exception.hpp> |
15 | | #include <boost/assert/source_location.hpp> |
16 | | #include <boost/assert.hpp> |
17 | | #include <boost/config.hpp> |
18 | | #include <type_traits> |
19 | | #include <utility> |
20 | | #include <iosfwd> |
21 | | #include <system_error> |
22 | | #include <exception> |
23 | | |
24 | | // |
25 | | |
26 | | namespace boost |
27 | | { |
28 | | namespace system |
29 | | { |
30 | | |
31 | | // throw_exception_from_error |
32 | | |
33 | | #if defined(__GNUC__) && __GNUC__ >= 7 && __GNUC__ <= 8 |
34 | | # pragma GCC diagnostic push |
35 | | # pragma GCC diagnostic ignored "-Wattributes" |
36 | | #endif |
37 | | |
38 | | BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( error_code const & e, boost::source_location const& loc ) |
39 | 0 | { |
40 | 0 | boost::throw_with_location( system_error( e ), loc ); |
41 | 0 | } |
42 | | |
43 | | BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( errc::errc_t const & e, boost::source_location const& loc ) |
44 | 0 | { |
45 | 0 | boost::throw_with_location( system_error( make_error_code( e ) ), loc ); |
46 | 0 | } |
47 | | |
48 | | BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( std::error_code const & e, boost::source_location const& loc ) |
49 | 0 | { |
50 | 0 | boost::throw_with_location( std::system_error( e ), loc ); |
51 | 0 | } |
52 | | |
53 | | BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( std::errc const & e, boost::source_location const& loc ) |
54 | 0 | { |
55 | 0 | boost::throw_with_location( std::system_error( make_error_code( e ) ), loc ); |
56 | 0 | } |
57 | | |
58 | | BOOST_NORETURN BOOST_NOINLINE inline void throw_exception_from_error( std::exception_ptr const & p, boost::source_location const& loc ) |
59 | 0 | { |
60 | 0 | if( p ) |
61 | 0 | { |
62 | 0 | std::rethrow_exception( p ); |
63 | 0 | } |
64 | 0 | else |
65 | 0 | { |
66 | 0 | boost::throw_with_location( std::bad_exception(), loc ); |
67 | 0 | } |
68 | 0 | } |
69 | | |
70 | | #if defined(__GNUC__) && __GNUC__ >= 7 && __GNUC__ <= 8 |
71 | | # pragma GCC diagnostic pop |
72 | | #endif |
73 | | |
74 | | // in_place_* |
75 | | |
76 | | using in_place_value_t = variant2::in_place_index_t<0>; |
77 | | BOOST_INLINE_CONSTEXPR in_place_value_t in_place_value{}; |
78 | | |
79 | | using in_place_error_t = variant2::in_place_index_t<1>; |
80 | | BOOST_INLINE_CONSTEXPR in_place_error_t in_place_error{}; |
81 | | |
82 | | namespace detail |
83 | | { |
84 | | |
85 | | template<class T> using remove_cvref = typename std::remove_cv< typename std::remove_reference<T>::type >::type; |
86 | | |
87 | | template<class... T> using is_errc_t = std::is_same<mp11::mp_list<remove_cvref<T>...>, mp11::mp_list<errc::errc_t>>; |
88 | | |
89 | | template<class T, class... A> struct is_constructible: std::is_constructible<T, A...> {}; |
90 | | template<class A> struct is_constructible<bool, A>: std::is_convertible<A, bool> {}; |
91 | | template<class A> struct is_constructible<bool const, A>: std::is_convertible<A, bool> {}; |
92 | | |
93 | | } // namespace detail |
94 | | |
95 | | // result |
96 | | |
97 | | template<class T, class E = error_code> class result |
98 | | { |
99 | | private: |
100 | | |
101 | | variant2::variant<T, E> v_; |
102 | | |
103 | | public: |
104 | | |
105 | | using value_type = T; |
106 | | using error_type = E; |
107 | | |
108 | | static constexpr in_place_value_t in_place_value{}; |
109 | | static constexpr in_place_error_t in_place_error{}; |
110 | | |
111 | | public: |
112 | | |
113 | | // constructors |
114 | | |
115 | | // default |
116 | | template<class En2 = void, class En = typename std::enable_if< |
117 | | std::is_void<En2>::value && |
118 | | std::is_default_constructible<T>::value |
119 | | >::type> |
120 | | constexpr result() |
121 | | noexcept( std::is_nothrow_default_constructible<T>::value ) |
122 | | : v_( in_place_value ) |
123 | | { |
124 | | } |
125 | | |
126 | | // implicit, value |
127 | | template<class A = T, typename std::enable_if< |
128 | | std::is_convertible<A, T>::value && |
129 | | !(detail::is_errc_t<A>::value && std::is_arithmetic<T>::value) && |
130 | | !std::is_convertible<A, E>::value, int>::type = 0> |
131 | | constexpr result( A&& a ) |
132 | | noexcept( std::is_nothrow_constructible<T, A>::value ) |
133 | 0 | : v_( in_place_value, std::forward<A>(a) ) |
134 | 0 | { |
135 | 0 | } Unexecuted instantiation: _ZN5boost6system6resultIlNS0_10error_codeEEC2IRKlTnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_lEE5valuentaasr6detail9is_errc_tIS9_EE5valueL_ZNS7_17integral_constantIbLb1EE5valueEEntsr3std14is_convertibleIS9_S2_EE5valueEiE4typeELi0EEEOS9_ Unexecuted instantiation: _ZN5boost6system6resultImNS0_10error_codeEEC2IRKmTnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_mEE5valuentaasr6detail9is_errc_tIS9_EE5valueL_ZNS7_17integral_constantIbLb1EE5valueEEntsr3std14is_convertibleIS9_S2_EE5valueEiE4typeELi0EEEOS9_ Unexecuted instantiation: _ZN5boost6system6resultIdNS0_10error_codeEEC2IRKdTnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_dEE5valuentaasr6detail9is_errc_tIS9_EE5valueL_ZNS7_17integral_constantIbLb1EE5valueEEntsr3std14is_convertibleIS9_S2_EE5valueEiE4typeELi0EEEOS9_ Unexecuted instantiation: _ZN5boost6system6resultIbNS0_10error_codeEEC2IRKbTnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_bEE5valuentaasr6detail9is_errc_tIS9_EE5valueL_ZNS7_17integral_constantIbLb1EE5valueEEntsr3std14is_convertibleIS9_S2_EE5valueEiE4typeELi0EEEOS9_ Unexecuted instantiation: _ZN5boost6system6resultIDnNS0_10error_codeEEC2IDnTnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_DnEE5valuentaasr6detail9is_errc_tIS7_EE5valueL_ZNS5_17integral_constantIbLb0EE5valueEEntsr3std14is_convertibleIS7_S2_EE5valueEiE4typeELi0EEEOS7_ |
136 | | |
137 | | // implicit, error |
138 | | template<class A = E, class = void, typename std::enable_if< |
139 | | std::is_convertible<A, E>::value && |
140 | | !std::is_convertible<A, T>::value, int>::type = 0> |
141 | | constexpr result( A&& a ) |
142 | | noexcept( std::is_nothrow_constructible<E, A>::value ) |
143 | 0 | : v_( in_place_error, std::forward<A>(a) ) |
144 | 0 | { |
145 | 0 | } Unexecuted instantiation: _ZN5boost6system6resultIlNS0_10error_codeEEC2IS2_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S2_EE5valuentsr3std14is_convertibleIS7_lEE5valueEiE4typeELi0EEEOS7_ Unexecuted instantiation: _ZN5boost6system6resultImNS0_10error_codeEEC2IS2_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S2_EE5valuentsr3std14is_convertibleIS7_mEE5valueEiE4typeELi0EEEOS7_ Unexecuted instantiation: _ZN5boost6system6resultIdNS0_10error_codeEEC2IS2_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S2_EE5valuentsr3std14is_convertibleIS7_dEE5valueEiE4typeELi0EEEOS7_ Unexecuted instantiation: _ZN5boost6system6resultIbNS0_10error_codeEEC2IS2_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S2_EE5valuentsr3std14is_convertibleIS7_bEE5valueEiE4typeELi0EEEOS7_ Unexecuted instantiation: _ZN5boost6system6resultIDnNS0_10error_codeEEC2IS2_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S2_EE5valuentsr3std14is_convertibleIS7_DnEE5valueEiE4typeELi0EEEOS7_ |
146 | | |
147 | | // explicit, value |
148 | | template<class... A, class En = typename std::enable_if< |
149 | | detail::is_constructible<T, A...>::value && |
150 | | !(detail::is_errc_t<A...>::value && std::is_arithmetic<T>::value) && |
151 | | !detail::is_constructible<E, A...>::value && |
152 | | sizeof...(A) >= 1 |
153 | | >::type> |
154 | | explicit constexpr result( A&&... a ) |
155 | | noexcept( std::is_nothrow_constructible<T, A...>::value ) |
156 | | : v_( in_place_value, std::forward<A>(a)... ) |
157 | | { |
158 | | } |
159 | | |
160 | | // explicit, error |
161 | | template<class... A, class En2 = void, class En = typename std::enable_if< |
162 | | !detail::is_constructible<T, A...>::value && |
163 | | detail::is_constructible<E, A...>::value && |
164 | | sizeof...(A) >= 1 |
165 | | >::type> |
166 | | explicit constexpr result( A&&... a ) |
167 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
168 | | : v_( in_place_error, std::forward<A>(a)... ) |
169 | | { |
170 | | } |
171 | | |
172 | | // tagged, value |
173 | | template<class... A, class En = typename std::enable_if< |
174 | | std::is_constructible<T, A...>::value |
175 | | >::type> |
176 | | constexpr result( in_place_value_t, A&&... a ) |
177 | | noexcept( std::is_nothrow_constructible<T, A...>::value ) |
178 | | : v_( in_place_value, std::forward<A>(a)... ) |
179 | | { |
180 | | } |
181 | | |
182 | | // tagged, error |
183 | | template<class... A, class En = typename std::enable_if< |
184 | | std::is_constructible<E, A...>::value |
185 | | >::type> |
186 | | constexpr result( in_place_error_t, A&&... a ) |
187 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
188 | | : v_( in_place_error, std::forward<A>(a)... ) |
189 | | { |
190 | | } |
191 | | |
192 | | // converting |
193 | | template<class T2, class E2, class En = typename std::enable_if< |
194 | | std::is_convertible<T2, T>::value && |
195 | | std::is_convertible<E2, E>::value && |
196 | | !std::is_convertible<result<T2, E2> const&, T>::value |
197 | | >::type> |
198 | | BOOST_CXX14_CONSTEXPR result( result<T2, E2> const& r2 ) |
199 | | noexcept( |
200 | | std::is_nothrow_constructible<T, T2 const&>::value && |
201 | | std::is_nothrow_constructible<E, E2>::value && |
202 | | std::is_nothrow_default_constructible<E2>::value && |
203 | | std::is_nothrow_copy_constructible<E2>::value ) |
204 | | : v_( in_place_error, r2.error() ) |
205 | | { |
206 | | if( r2 ) |
207 | | { |
208 | | v_.template emplace<0>( *r2 ); |
209 | | } |
210 | | } |
211 | | |
212 | | template<class T2, class E2, class En = typename std::enable_if< |
213 | | std::is_convertible<T2, T>::value && |
214 | | std::is_convertible<E2, E>::value && |
215 | | !std::is_convertible<result<T2, E2>&&, T>::value |
216 | | >::type> |
217 | | BOOST_CXX14_CONSTEXPR result( result<T2, E2>&& r2 ) |
218 | | noexcept( |
219 | | std::is_nothrow_constructible<T, T2&&>::value && |
220 | | std::is_nothrow_constructible<E, E2>::value && |
221 | | std::is_nothrow_default_constructible<E2>::value && |
222 | | std::is_nothrow_copy_constructible<E2>::value ) |
223 | | : v_( in_place_error, r2.error() ) |
224 | | { |
225 | | if( r2 ) |
226 | | { |
227 | | v_.template emplace<0>( std::move( *r2 ) ); |
228 | | } |
229 | | } |
230 | | |
231 | | // queries |
232 | | |
233 | | constexpr bool has_value() const noexcept |
234 | 0 | { |
235 | 0 | return v_.index() == 0; |
236 | 0 | } Unexecuted instantiation: boost::system::result<long, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<unsigned long, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<double, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<bool, boost::system::error_code>::has_value() const |
237 | | |
238 | | constexpr bool has_error() const noexcept |
239 | | { |
240 | | return v_.index() == 1; |
241 | | } |
242 | | |
243 | | constexpr explicit operator bool() const noexcept |
244 | | { |
245 | | return v_.index() == 0; |
246 | | } |
247 | | |
248 | | // checked value access |
249 | | #if defined( BOOST_NO_CXX11_REF_QUALIFIERS ) |
250 | | |
251 | | BOOST_CXX14_CONSTEXPR T value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const |
252 | | { |
253 | | if( has_value() ) |
254 | | { |
255 | | return variant2::unsafe_get<0>( v_ ); |
256 | | } |
257 | | else |
258 | | { |
259 | | throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc ); |
260 | | } |
261 | | } |
262 | | |
263 | | #else |
264 | | |
265 | | BOOST_CXX14_CONSTEXPR T& value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) & |
266 | 0 | { |
267 | 0 | if( has_value() ) |
268 | 0 | { |
269 | 0 | return variant2::unsafe_get<0>( v_ ); |
270 | 0 | } |
271 | 0 | else |
272 | 0 | { |
273 | 0 | throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc ); |
274 | 0 | } |
275 | 0 | } Unexecuted instantiation: boost::system::result<long, boost::system::error_code>::value(boost::source_location const&) & Unexecuted instantiation: boost::system::result<unsigned long, boost::system::error_code>::value(boost::source_location const&) & Unexecuted instantiation: boost::system::result<double, boost::system::error_code>::value(boost::source_location const&) & Unexecuted instantiation: boost::system::result<bool, boost::system::error_code>::value(boost::source_location const&) & |
276 | | |
277 | | BOOST_CXX14_CONSTEXPR T const& value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const& |
278 | | { |
279 | | if( has_value() ) |
280 | | { |
281 | | return variant2::unsafe_get<0>( v_ ); |
282 | | } |
283 | | else |
284 | | { |
285 | | throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc ); |
286 | | } |
287 | | } |
288 | | |
289 | | template<class U = T> |
290 | | BOOST_CXX14_CONSTEXPR |
291 | | typename std::enable_if<std::is_move_constructible<U>::value, T>::type |
292 | | value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) && |
293 | 0 | { |
294 | 0 | return std::move( value( loc ) ); |
295 | 0 | } Unexecuted instantiation: _ZNO5boost6system6resultIlNS0_10error_codeEE5valueIlEENSt3__19enable_ifIXsr3std21is_move_constructibleIT_EE5valueElE4typeERKNS_15source_locationE Unexecuted instantiation: _ZNO5boost6system6resultImNS0_10error_codeEE5valueImEENSt3__19enable_ifIXsr3std21is_move_constructibleIT_EE5valueEmE4typeERKNS_15source_locationE Unexecuted instantiation: _ZNO5boost6system6resultIdNS0_10error_codeEE5valueIdEENSt3__19enable_ifIXsr3std21is_move_constructibleIT_EE5valueEdE4typeERKNS_15source_locationE Unexecuted instantiation: _ZNO5boost6system6resultIbNS0_10error_codeEE5valueIbEENSt3__19enable_ifIXsr3std21is_move_constructibleIT_EE5valueEbE4typeERKNS_15source_locationE |
296 | | |
297 | | template<class U = T> |
298 | | BOOST_CXX14_CONSTEXPR |
299 | | typename std::enable_if<!std::is_move_constructible<U>::value, T&&>::type |
300 | | value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) && |
301 | | { |
302 | | return std::move( value( loc ) ); |
303 | | } |
304 | | |
305 | | template<class U = T> |
306 | | BOOST_CXX14_CONSTEXPR |
307 | | typename std::enable_if<std::is_move_constructible<U>::value, T>::type |
308 | | value() const && = delete; |
309 | | |
310 | | template<class U = T> |
311 | | BOOST_CXX14_CONSTEXPR |
312 | | typename std::enable_if<!std::is_move_constructible<U>::value, T const&&>::type |
313 | | value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const && |
314 | | { |
315 | | return std::move( value( loc ) ); |
316 | | } |
317 | | |
318 | | #endif |
319 | | |
320 | | // unchecked value access |
321 | | |
322 | | BOOST_CXX14_CONSTEXPR T* operator->() noexcept |
323 | | { |
324 | | return variant2::get_if<0>( &v_ ); |
325 | | } |
326 | | |
327 | | BOOST_CXX14_CONSTEXPR T const* operator->() const noexcept |
328 | | { |
329 | | return variant2::get_if<0>( &v_ ); |
330 | | } |
331 | | |
332 | | #if defined( BOOST_NO_CXX11_REF_QUALIFIERS ) |
333 | | |
334 | | BOOST_CXX14_CONSTEXPR T& operator*() noexcept |
335 | | { |
336 | | BOOST_ASSERT( has_value() ); |
337 | | return *operator->(); |
338 | | } |
339 | | |
340 | | BOOST_CXX14_CONSTEXPR T const& operator*() const noexcept |
341 | | { |
342 | | BOOST_ASSERT( has_value() ); |
343 | | return *operator->(); |
344 | | } |
345 | | |
346 | | #else |
347 | | |
348 | | BOOST_CXX14_CONSTEXPR T& operator*() & noexcept |
349 | | { |
350 | | BOOST_ASSERT( has_value() ); |
351 | | return *operator->(); |
352 | | } |
353 | | |
354 | | BOOST_CXX14_CONSTEXPR T const& operator*() const & noexcept |
355 | | { |
356 | | BOOST_ASSERT( has_value() ); |
357 | | return *operator->(); |
358 | | } |
359 | | |
360 | | template<class U = T> |
361 | | BOOST_CXX14_CONSTEXPR |
362 | | typename std::enable_if<std::is_move_constructible<U>::value, T>::type |
363 | | operator*() && noexcept(std::is_nothrow_move_constructible<T>::value) |
364 | | { |
365 | | return std::move(**this); |
366 | | } |
367 | | |
368 | | template<class U = T> |
369 | | BOOST_CXX14_CONSTEXPR |
370 | | typename std::enable_if<!std::is_move_constructible<U>::value, T&&>::type |
371 | | operator*() && noexcept |
372 | | { |
373 | | return std::move(**this); |
374 | | } |
375 | | |
376 | | template<class U = T> |
377 | | BOOST_CXX14_CONSTEXPR |
378 | | typename std::enable_if<std::is_move_constructible<U>::value, T>::type |
379 | | operator*() const && noexcept = delete; |
380 | | |
381 | | template<class U = T> |
382 | | BOOST_CXX14_CONSTEXPR |
383 | | typename std::enable_if<!std::is_move_constructible<U>::value, T const&&>::type |
384 | | operator*() const && noexcept |
385 | | { |
386 | | return std::move(**this); |
387 | | } |
388 | | |
389 | | #endif |
390 | | |
391 | | // error access |
392 | | |
393 | | constexpr E error() const & |
394 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value ) |
395 | | { |
396 | | return has_error()? variant2::unsafe_get<1>( v_ ): E(); |
397 | | } |
398 | | |
399 | | BOOST_CXX14_CONSTEXPR E error() && |
400 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value ) |
401 | | { |
402 | | return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E(); |
403 | | } |
404 | | |
405 | | // emplace |
406 | | |
407 | | template<class... A> |
408 | | BOOST_CXX14_CONSTEXPR T& emplace( A&&... a ) |
409 | | { |
410 | | return v_.template emplace<0>( std::forward<A>(a)... ); |
411 | | } |
412 | | |
413 | | // swap |
414 | | |
415 | | BOOST_CXX14_CONSTEXPR void swap( result& r ) |
416 | | noexcept( noexcept( v_.swap( r.v_ ) ) ) |
417 | | { |
418 | | v_.swap( r.v_ ); |
419 | | } |
420 | | |
421 | | friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 ) |
422 | | noexcept( noexcept( r1.swap( r2 ) ) ) |
423 | | { |
424 | | r1.swap( r2 ); |
425 | | } |
426 | | |
427 | | // equality |
428 | | |
429 | | friend constexpr bool operator==( result const & r1, result const & r2 ) |
430 | | noexcept( noexcept( r1.v_ == r2.v_ ) ) |
431 | | { |
432 | | return r1.v_ == r2.v_; |
433 | | } |
434 | | |
435 | | friend constexpr bool operator!=( result const & r1, result const & r2 ) |
436 | | noexcept( noexcept( !( r1 == r2 ) ) ) |
437 | | { |
438 | | return !( r1 == r2 ); |
439 | | } |
440 | | }; |
441 | | |
442 | | #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) |
443 | | |
444 | | template<class T, class E> constexpr in_place_value_t result<T, E>::in_place_value; |
445 | | template<class T, class E> constexpr in_place_error_t result<T, E>::in_place_error; |
446 | | |
447 | | #endif |
448 | | |
449 | | template<class Ch, class Tr, class T, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<T, E> const & r ) |
450 | | { |
451 | | if( r.has_value() ) |
452 | | { |
453 | | os << "value:" << *r; |
454 | | } |
455 | | else |
456 | | { |
457 | | os << "error:" << r.error(); |
458 | | } |
459 | | |
460 | | return os; |
461 | | } |
462 | | |
463 | | // result<void> |
464 | | |
465 | | template<class E> class result<void, E> |
466 | | { |
467 | | private: |
468 | | |
469 | | variant2::variant<variant2::monostate, E> v_; |
470 | | |
471 | | public: |
472 | | |
473 | | using value_type = void; |
474 | | using error_type = E; |
475 | | |
476 | | static constexpr in_place_value_t in_place_value{}; |
477 | | static constexpr in_place_error_t in_place_error{}; |
478 | | |
479 | | public: |
480 | | |
481 | | // constructors |
482 | | |
483 | | // default |
484 | | constexpr result() noexcept |
485 | | : v_( in_place_value ) |
486 | | { |
487 | | } |
488 | | |
489 | | // explicit, error |
490 | | template<class A, class En = typename std::enable_if< |
491 | | std::is_constructible<E, A>::value && |
492 | | !std::is_convertible<A, E>::value |
493 | | >::type> |
494 | | explicit constexpr result( A&& a ) |
495 | | noexcept( std::is_nothrow_constructible<E, A>::value ) |
496 | | : v_( in_place_error, std::forward<A>(a) ) |
497 | | { |
498 | | } |
499 | | |
500 | | // implicit, error |
501 | | template<class A, class En2 = void, class En = typename std::enable_if< |
502 | | std::is_convertible<A, E>::value |
503 | | >::type> |
504 | | constexpr result( A&& a ) |
505 | | noexcept( std::is_nothrow_constructible<E, A>::value ) |
506 | | : v_( in_place_error, std::forward<A>(a) ) |
507 | | { |
508 | | } |
509 | | |
510 | | // more than one arg, error |
511 | | template<class... A, class En2 = void, class En3 = void, class En = typename std::enable_if< |
512 | | std::is_constructible<E, A...>::value && |
513 | | sizeof...(A) >= 2 |
514 | | >::type> |
515 | | constexpr result( A&&... a ) |
516 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
517 | | : v_( in_place_error, std::forward<A>(a)... ) |
518 | | { |
519 | | } |
520 | | |
521 | | // tagged, value |
522 | | constexpr result( in_place_value_t ) noexcept |
523 | | : v_( in_place_value ) |
524 | | { |
525 | | } |
526 | | |
527 | | // tagged, error |
528 | | template<class... A, class En = typename std::enable_if< |
529 | | std::is_constructible<E, A...>::value |
530 | | >::type> |
531 | | constexpr result( in_place_error_t, A&&... a ) |
532 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
533 | | : v_( in_place_error, std::forward<A>(a)... ) |
534 | | { |
535 | | } |
536 | | |
537 | | // converting |
538 | | template<class E2, class En = typename std::enable_if< |
539 | | std::is_convertible<E2, E>::value |
540 | | >::type> |
541 | | BOOST_CXX14_CONSTEXPR result( result<void, E2> const& r2 ) |
542 | | noexcept( |
543 | | std::is_nothrow_constructible<E, E2>::value && |
544 | | std::is_nothrow_default_constructible<E2>::value && |
545 | | std::is_nothrow_copy_constructible<E2>::value ) |
546 | | : v_( in_place_error, r2.error() ) |
547 | | { |
548 | | if( r2 ) |
549 | | { |
550 | | this->emplace(); |
551 | | } |
552 | | } |
553 | | |
554 | | // queries |
555 | | |
556 | | constexpr bool has_value() const noexcept |
557 | | { |
558 | | return v_.index() == 0; |
559 | | } |
560 | | |
561 | | constexpr bool has_error() const noexcept |
562 | | { |
563 | | return v_.index() == 1; |
564 | | } |
565 | | |
566 | | constexpr explicit operator bool() const noexcept |
567 | | { |
568 | | return v_.index() == 0; |
569 | | } |
570 | | |
571 | | // checked value access |
572 | | |
573 | | BOOST_CXX14_CONSTEXPR void value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const |
574 | | { |
575 | | if( has_value() ) |
576 | | { |
577 | | } |
578 | | else |
579 | | { |
580 | | throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc ); |
581 | | } |
582 | | } |
583 | | |
584 | | // unchecked value access |
585 | | |
586 | | BOOST_CXX14_CONSTEXPR void* operator->() noexcept |
587 | | { |
588 | | return variant2::get_if<0>( &v_ ); |
589 | | } |
590 | | |
591 | | BOOST_CXX14_CONSTEXPR void const* operator->() const noexcept |
592 | | { |
593 | | return variant2::get_if<0>( &v_ ); |
594 | | } |
595 | | |
596 | | BOOST_CXX14_CONSTEXPR void operator*() const noexcept |
597 | | { |
598 | | BOOST_ASSERT( has_value() ); |
599 | | } |
600 | | |
601 | | // error access |
602 | | |
603 | | constexpr E error() const & |
604 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value ) |
605 | | { |
606 | | return has_error()? variant2::unsafe_get<1>( v_ ): E(); |
607 | | } |
608 | | |
609 | | BOOST_CXX14_CONSTEXPR E error() && |
610 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value ) |
611 | | { |
612 | | return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E(); |
613 | | } |
614 | | |
615 | | // emplace |
616 | | |
617 | | BOOST_CXX14_CONSTEXPR void emplace() |
618 | | { |
619 | | v_.template emplace<0>(); |
620 | | } |
621 | | |
622 | | // swap |
623 | | |
624 | | BOOST_CXX14_CONSTEXPR void swap( result& r ) |
625 | | noexcept( noexcept( v_.swap( r.v_ ) ) ) |
626 | | { |
627 | | v_.swap( r.v_ ); |
628 | | } |
629 | | |
630 | | friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 ) |
631 | | noexcept( noexcept( r1.swap( r2 ) ) ) |
632 | | { |
633 | | r1.swap( r2 ); |
634 | | } |
635 | | |
636 | | // equality |
637 | | |
638 | | friend constexpr bool operator==( result const & r1, result const & r2 ) |
639 | | noexcept( noexcept( r1.v_ == r2.v_ ) ) |
640 | | { |
641 | | return r1.v_ == r2.v_; |
642 | | } |
643 | | |
644 | | friend constexpr bool operator!=( result const & r1, result const & r2 ) |
645 | | noexcept( noexcept( !( r1 == r2 ) ) ) |
646 | | { |
647 | | return !( r1 == r2 ); |
648 | | } |
649 | | }; |
650 | | |
651 | | #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) |
652 | | |
653 | | template<class E> constexpr in_place_value_t result<void, E>::in_place_value; |
654 | | template<class E> constexpr in_place_error_t result<void, E>::in_place_error; |
655 | | |
656 | | #endif |
657 | | |
658 | | template<class Ch, class Tr, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<void, E> const & r ) |
659 | | { |
660 | | if( r.has_value() ) |
661 | | { |
662 | | os << "value:void"; |
663 | | } |
664 | | else |
665 | | { |
666 | | os << "error:" << r.error(); |
667 | | } |
668 | | |
669 | | return os; |
670 | | } |
671 | | |
672 | | // result<T&, E> |
673 | | |
674 | | namespace detail |
675 | | { |
676 | | |
677 | | template<class U, class A> struct reference_to_temporary: std::integral_constant<bool, |
678 | | !std::is_reference<A>::value || |
679 | | !std::is_convertible<typename std::remove_reference<A>::type*, U*>::value |
680 | | > {}; |
681 | | |
682 | | } // namespace detail |
683 | | |
684 | | template<class U, class E> class result<U&, E> |
685 | | { |
686 | | private: |
687 | | |
688 | | variant2::variant<U*, E> v_; |
689 | | |
690 | | public: |
691 | | |
692 | | using value_type = U&; |
693 | | using error_type = E; |
694 | | |
695 | | static constexpr in_place_value_t in_place_value{}; |
696 | | static constexpr in_place_error_t in_place_error{}; |
697 | | |
698 | | public: |
699 | | |
700 | | // constructors |
701 | | |
702 | | // implicit, value |
703 | | template<class A, typename std::enable_if< |
704 | | std::is_convertible<A, U&>::value && |
705 | | !detail::reference_to_temporary<U, A>::value && |
706 | | !std::is_convertible<A, E>::value, int>::type = 0> |
707 | | constexpr result( A&& a ) |
708 | | noexcept( std::is_nothrow_constructible<U&, A>::value ) |
709 | 0 | : v_( in_place_value, &static_cast<U&>( std::forward<A>(a) ) ) |
710 | 0 | { |
711 | 0 | } Unexecuted instantiation: _ZN5boost6system6resultIRNS_4json5valueENS0_10error_codeEEC2IS4_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S4_EE5valuentsr6detail22reference_to_temporaryIS3_SA_EE5valuentsr3std14is_convertibleISA_S5_EE5valueEiE4typeELi0EEEOSA_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json5valueENS0_10error_codeEEC2IRS3_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S5_EE5valuentsr6detail22reference_to_temporaryIS4_SC_EE5valuentsr3std14is_convertibleISC_S6_EE5valueEiE4typeELi0EEEOSC_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json5valueENS0_10error_codeEEC2IS5_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S5_EE5valuentsr6detail22reference_to_temporaryIS4_SB_EE5valuentsr3std14is_convertibleISB_S6_EE5valueEiE4typeELi0EEEOSB_ Unexecuted instantiation: _ZN5boost6system6resultIRcNS0_10error_codeEEC2IS2_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S2_EE5valuentsr6detail22reference_to_temporaryIcS8_EE5valuentsr3std14is_convertibleIS8_S3_EE5valueEiE4typeELi0EEEOS8_ Unexecuted instantiation: _ZN5boost6system6resultIRKcNS0_10error_codeEEC2IS3_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S3_EE5valuentsr6detail22reference_to_temporaryIS2_S9_EE5valuentsr3std14is_convertibleIS9_S4_EE5valueEiE4typeELi0EEEOS9_ Unexecuted instantiation: _ZN5boost6system6resultIRNS_4json5arrayENS0_10error_codeEEC2IS4_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S4_EE5valuentsr6detail22reference_to_temporaryIS3_SA_EE5valuentsr3std14is_convertibleISA_S5_EE5valueEiE4typeELi0EEEOSA_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json5arrayENS0_10error_codeEEC2IS5_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S5_EE5valuentsr6detail22reference_to_temporaryIS4_SB_EE5valuentsr3std14is_convertibleISB_S6_EE5valueEiE4typeELi0EEEOSB_ Unexecuted instantiation: _ZN5boost6system6resultIRNS_4json6objectENS0_10error_codeEEC2IS4_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S4_EE5valuentsr6detail22reference_to_temporaryIS3_SA_EE5valuentsr3std14is_convertibleISA_S5_EE5valueEiE4typeELi0EEEOSA_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json6objectENS0_10error_codeEEC2IS5_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S5_EE5valuentsr6detail22reference_to_temporaryIS4_SB_EE5valuentsr3std14is_convertibleISB_S6_EE5valueEiE4typeELi0EEEOSB_ Unexecuted instantiation: _ZN5boost6system6resultIRNS_4json6stringENS0_10error_codeEEC2IS4_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S4_EE5valuentsr6detail22reference_to_temporaryIS3_SA_EE5valuentsr3std14is_convertibleISA_S5_EE5valueEiE4typeELi0EEEOSA_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json6stringENS0_10error_codeEEC2IS5_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S5_EE5valuentsr6detail22reference_to_temporaryIS4_SB_EE5valuentsr3std14is_convertibleISB_S6_EE5valueEiE4typeELi0EEEOSB_ Unexecuted instantiation: _ZN5boost6system6resultIRlNS0_10error_codeEEC2IS2_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S2_EE5valuentsr6detail22reference_to_temporaryIlS8_EE5valuentsr3std14is_convertibleIS8_S3_EE5valueEiE4typeELi0EEEOS8_ Unexecuted instantiation: _ZN5boost6system6resultIRmNS0_10error_codeEEC2IS2_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S2_EE5valuentsr6detail22reference_to_temporaryImS8_EE5valuentsr3std14is_convertibleIS8_S3_EE5valueEiE4typeELi0EEEOS8_ Unexecuted instantiation: _ZN5boost6system6resultIRdNS0_10error_codeEEC2IS2_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S2_EE5valuentsr6detail22reference_to_temporaryIdS8_EE5valuentsr3std14is_convertibleIS8_S3_EE5valueEiE4typeELi0EEEOS8_ Unexecuted instantiation: _ZN5boost6system6resultIRbNS0_10error_codeEEC2IS2_TnNSt3__19enable_ifIXaaaasr3std14is_convertibleIT_S2_EE5valuentsr6detail22reference_to_temporaryIbS8_EE5valuentsr3std14is_convertibleIS8_S3_EE5valueEiE4typeELi0EEEOS8_ |
712 | | |
713 | | // implicit, error |
714 | | template<class A = E, class = void, typename std::enable_if< |
715 | | std::is_convertible<A, E>::value && |
716 | | !std::is_convertible<A, U&>::value, int>::type = 0> |
717 | | constexpr result( A&& a ) |
718 | | noexcept( std::is_nothrow_constructible<E, A>::value ) |
719 | 0 | : v_( in_place_error, std::forward<A>(a) ) |
720 | 0 | { |
721 | 0 | } Unexecuted instantiation: _ZN5boost6system6resultIRNS_4json5valueENS0_10error_codeEEC2IS5_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S5_EE5valuentsr3std14is_convertibleISA_S4_EE5valueEiE4typeELi0EEEOSA_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json5valueENS0_10error_codeEEC2IS6_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S6_EE5valuentsr3std14is_convertibleISB_S5_EE5valueEiE4typeELi0EEEOSB_ Unexecuted instantiation: _ZN5boost6system6resultIRcNS0_10error_codeEEC2IS3_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S3_EE5valuentsr3std14is_convertibleIS8_S2_EE5valueEiE4typeELi0EEEOS8_ Unexecuted instantiation: _ZN5boost6system6resultIRKcNS0_10error_codeEEC2IS4_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S4_EE5valuentsr3std14is_convertibleIS9_S3_EE5valueEiE4typeELi0EEEOS9_ Unexecuted instantiation: _ZN5boost6system6resultIRNS_4json5arrayENS0_10error_codeEEC2IS5_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S5_EE5valuentsr3std14is_convertibleISA_S4_EE5valueEiE4typeELi0EEEOSA_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json5arrayENS0_10error_codeEEC2IS6_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S6_EE5valuentsr3std14is_convertibleISB_S5_EE5valueEiE4typeELi0EEEOSB_ Unexecuted instantiation: _ZN5boost6system6resultIRNS_4json6objectENS0_10error_codeEEC2IS5_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S5_EE5valuentsr3std14is_convertibleISA_S4_EE5valueEiE4typeELi0EEEOSA_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json6objectENS0_10error_codeEEC2IS6_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S6_EE5valuentsr3std14is_convertibleISB_S5_EE5valueEiE4typeELi0EEEOSB_ Unexecuted instantiation: _ZN5boost6system6resultIRNS_4json6stringENS0_10error_codeEEC2IS5_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S5_EE5valuentsr3std14is_convertibleISA_S4_EE5valueEiE4typeELi0EEEOSA_ Unexecuted instantiation: _ZN5boost6system6resultIRKNS_4json6stringENS0_10error_codeEEC2IS6_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S6_EE5valuentsr3std14is_convertibleISB_S5_EE5valueEiE4typeELi0EEEOSB_ Unexecuted instantiation: _ZN5boost6system6resultIRlNS0_10error_codeEEC2IS3_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S3_EE5valuentsr3std14is_convertibleIS8_S2_EE5valueEiE4typeELi0EEEOS8_ Unexecuted instantiation: _ZN5boost6system6resultIRmNS0_10error_codeEEC2IS3_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S3_EE5valuentsr3std14is_convertibleIS8_S2_EE5valueEiE4typeELi0EEEOS8_ Unexecuted instantiation: _ZN5boost6system6resultIRdNS0_10error_codeEEC2IS3_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S3_EE5valuentsr3std14is_convertibleIS8_S2_EE5valueEiE4typeELi0EEEOS8_ Unexecuted instantiation: _ZN5boost6system6resultIRbNS0_10error_codeEEC2IS3_vTnNSt3__19enable_ifIXaasr3std14is_convertibleIT_S3_EE5valuentsr3std14is_convertibleIS8_S2_EE5valueEiE4typeELi0EEEOS8_ |
722 | | |
723 | | // explicit, value |
724 | | template<class A, class En = typename std::enable_if< |
725 | | detail::is_constructible<U&, A>::value && |
726 | | !std::is_convertible<A, U&>::value && |
727 | | !detail::reference_to_temporary<U, A>::value && |
728 | | !detail::is_constructible<E, A>::value |
729 | | >::type> |
730 | | explicit constexpr result( A&& a ) |
731 | | noexcept( std::is_nothrow_constructible<U&, A>::value ) |
732 | | : v_( in_place_value, &static_cast<U&>( std::forward<A>(a) ) ) |
733 | | { |
734 | | } |
735 | | |
736 | | // explicit, error |
737 | | template<class... A, class En2 = void, class En = typename std::enable_if< |
738 | | !detail::is_constructible<U&, A...>::value && |
739 | | detail::is_constructible<E, A...>::value && |
740 | | sizeof...(A) >= 1 |
741 | | >::type> |
742 | | explicit constexpr result( A&&... a ) |
743 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
744 | | : v_( in_place_error, std::forward<A>(a)... ) |
745 | | { |
746 | | } |
747 | | |
748 | | // tagged, value |
749 | | template<class A, class En = typename std::enable_if< |
750 | | std::is_constructible<U&, A>::value && |
751 | | !detail::reference_to_temporary<U, A>::value |
752 | | >::type> |
753 | | constexpr result( in_place_value_t, A&& a ) |
754 | | noexcept( std::is_nothrow_constructible<U&, A>::value ) |
755 | | : v_( in_place_value, &static_cast<U&>( std::forward<A>(a) ) ) |
756 | | { |
757 | | } |
758 | | |
759 | | // tagged, error |
760 | | template<class... A, class En = typename std::enable_if< |
761 | | std::is_constructible<E, A...>::value |
762 | | >::type> |
763 | | constexpr result( in_place_error_t, A&&... a ) |
764 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
765 | | : v_( in_place_error, std::forward<A>(a)... ) |
766 | | { |
767 | | } |
768 | | |
769 | | // converting |
770 | | template<class U2, class E2, class En = typename std::enable_if< |
771 | | std::is_convertible<U2&, U&>::value && |
772 | | !detail::reference_to_temporary<U, U2&>::value && |
773 | | std::is_convertible<E2, E>::value && |
774 | | !std::is_convertible<result<U2&, E2> const&, U&>::value |
775 | | >::type> |
776 | | BOOST_CXX14_CONSTEXPR result( result<U2&, E2> const& r2 ) |
777 | | noexcept( |
778 | | std::is_nothrow_constructible<U&, U2&>::value && |
779 | | std::is_nothrow_constructible<E, E2>::value && |
780 | | std::is_nothrow_default_constructible<E2>::value && |
781 | | std::is_nothrow_copy_constructible<E2>::value ) |
782 | | : v_( in_place_error, r2.error() ) |
783 | | { |
784 | | if( r2 ) |
785 | | { |
786 | | this->emplace( *r2 ); |
787 | | } |
788 | | } |
789 | | |
790 | | // queries |
791 | | |
792 | | constexpr bool has_value() const noexcept |
793 | 0 | { |
794 | 0 | return v_.index() == 0; |
795 | 0 | } Unexecuted instantiation: boost::system::result<boost::json::value const&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<boost::json::value&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<char const&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<boost::json::object&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<boost::json::object const&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<boost::json::array&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<boost::json::array const&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<boost::json::string const&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<long&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<unsigned long&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<double&, boost::system::error_code>::has_value() const Unexecuted instantiation: boost::system::result<bool&, boost::system::error_code>::has_value() const |
796 | | |
797 | | constexpr bool has_error() const noexcept |
798 | 0 | { |
799 | 0 | return v_.index() == 1; |
800 | 0 | } Unexecuted instantiation: boost::system::result<boost::json::object&, boost::system::error_code>::has_error() const Unexecuted instantiation: boost::system::result<boost::json::object const&, boost::system::error_code>::has_error() const Unexecuted instantiation: boost::system::result<boost::json::array&, boost::system::error_code>::has_error() const Unexecuted instantiation: boost::system::result<boost::json::array const&, boost::system::error_code>::has_error() const |
801 | | |
802 | | constexpr explicit operator bool() const noexcept |
803 | 0 | { |
804 | 0 | return v_.index() == 0; |
805 | 0 | } Unexecuted instantiation: boost::system::result<boost::json::object&, boost::system::error_code>::operator bool() const Unexecuted instantiation: boost::system::result<boost::json::object const&, boost::system::error_code>::operator bool() const Unexecuted instantiation: boost::system::result<boost::json::array&, boost::system::error_code>::operator bool() const Unexecuted instantiation: boost::system::result<boost::json::array const&, boost::system::error_code>::operator bool() const |
806 | | |
807 | | // checked value access |
808 | | |
809 | | BOOST_CXX14_CONSTEXPR U& value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const |
810 | 0 | { |
811 | 0 | if( has_value() ) |
812 | 0 | { |
813 | 0 | return *variant2::unsafe_get<0>( v_ ); |
814 | 0 | } |
815 | 0 | else |
816 | 0 | { |
817 | 0 | throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc ); |
818 | 0 | } |
819 | 0 | } Unexecuted instantiation: boost::system::result<boost::json::value const&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<boost::json::value&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<char const&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<boost::json::object const&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<boost::json::array const&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<boost::json::string const&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<long&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<unsigned long&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<double&, boost::system::error_code>::value(boost::source_location const&) const Unexecuted instantiation: boost::system::result<bool&, boost::system::error_code>::value(boost::source_location const&) const |
820 | | |
821 | | // unchecked value access |
822 | | |
823 | | BOOST_CXX14_CONSTEXPR U* operator->() const noexcept |
824 | 0 | { |
825 | 0 | return has_value()? variant2::unsafe_get<0>( v_ ): 0; |
826 | 0 | } Unexecuted instantiation: boost::system::result<boost::json::object&, boost::system::error_code>::operator->() const Unexecuted instantiation: boost::system::result<boost::json::object const&, boost::system::error_code>::operator->() const Unexecuted instantiation: boost::system::result<boost::json::array&, boost::system::error_code>::operator->() const Unexecuted instantiation: boost::system::result<boost::json::array const&, boost::system::error_code>::operator->() const |
827 | | |
828 | | BOOST_CXX14_CONSTEXPR U& operator*() const noexcept |
829 | | { |
830 | | BOOST_ASSERT( has_value() ); |
831 | | return *operator->(); |
832 | | } |
833 | | |
834 | | // error access |
835 | | |
836 | | constexpr E error() const & |
837 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value ) |
838 | 0 | { |
839 | 0 | return has_error()? variant2::unsafe_get<1>( v_ ): E(); |
840 | 0 | } Unexecuted instantiation: boost::system::result<boost::json::object&, boost::system::error_code>::error() const & Unexecuted instantiation: boost::system::result<boost::json::object const&, boost::system::error_code>::error() const & Unexecuted instantiation: boost::system::result<boost::json::array&, boost::system::error_code>::error() const & Unexecuted instantiation: boost::system::result<boost::json::array const&, boost::system::error_code>::error() const & |
841 | | |
842 | | BOOST_CXX14_CONSTEXPR E error() && |
843 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value ) |
844 | | { |
845 | | return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E(); |
846 | | } |
847 | | |
848 | | // emplace |
849 | | |
850 | | template<class A, class En = typename std::enable_if< |
851 | | detail::is_constructible<U&, A>::value && |
852 | | !detail::reference_to_temporary<U, A>::value |
853 | | >::type> |
854 | | BOOST_CXX14_CONSTEXPR U& emplace( A&& a ) |
855 | | { |
856 | | return *v_.template emplace<0>( &static_cast<U&>( a ) ); |
857 | | } |
858 | | |
859 | | // swap |
860 | | |
861 | | BOOST_CXX14_CONSTEXPR void swap( result& r ) |
862 | | noexcept( noexcept( v_.swap( r.v_ ) ) ) |
863 | | { |
864 | | v_.swap( r.v_ ); |
865 | | } |
866 | | |
867 | | friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 ) |
868 | | noexcept( noexcept( r1.swap( r2 ) ) ) |
869 | | { |
870 | | r1.swap( r2 ); |
871 | | } |
872 | | |
873 | | // equality |
874 | | |
875 | | friend constexpr bool operator==( result const & r1, result const & r2 ) |
876 | | noexcept( noexcept( r1 && r2? *r1 == *r2: r1.v_ == r2.v_ ) ) |
877 | | { |
878 | | return r1 && r2? *r1 == *r2: r1.v_ == r2.v_; |
879 | | } |
880 | | |
881 | | friend constexpr bool operator!=( result const & r1, result const & r2 ) |
882 | | noexcept( noexcept( !( r1 == r2 ) ) ) |
883 | | { |
884 | | return !( r1 == r2 ); |
885 | | } |
886 | | }; |
887 | | |
888 | | #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) |
889 | | |
890 | | template<class U, class E> constexpr in_place_value_t result<U&, E>::in_place_value; |
891 | | template<class U, class E> constexpr in_place_error_t result<U&, E>::in_place_error; |
892 | | |
893 | | #endif |
894 | | |
895 | | // operator| |
896 | | |
897 | | namespace detail |
898 | | { |
899 | | |
900 | | // is_value_convertible_to |
901 | | |
902 | | template<class T, class U> struct is_value_convertible_to: std::is_convertible<T, U> |
903 | | { |
904 | | }; |
905 | | |
906 | | template<class T, class U> struct is_value_convertible_to<T, U&>: |
907 | | std::integral_constant<bool, |
908 | | std::is_lvalue_reference<T>::value && |
909 | | std::is_convertible<typename std::remove_reference<T>::type*, U*>::value> |
910 | | { |
911 | | }; |
912 | | |
913 | | // is_result |
914 | | |
915 | | template<class T> struct is_result: std::false_type {}; |
916 | | template<class T, class E> struct is_result< result<T, E> >: std::true_type {}; |
917 | | |
918 | | } // namespace detail |
919 | | |
920 | | // result | value |
921 | | |
922 | | template<class T, class E, class U, |
923 | | class En = typename std::enable_if<std::is_convertible<U, typename std::decay<T>::type>::value>::type |
924 | | > |
925 | | typename std::decay<T>::type |
926 | | operator|( result<T, E> const& r, U&& u ) |
927 | | { |
928 | | if( r ) |
929 | | { |
930 | | return *r; |
931 | | } |
932 | | else |
933 | | { |
934 | | return std::forward<U>( u ); |
935 | | } |
936 | | } |
937 | | |
938 | | template<class T, class E, class U, |
939 | | class En = typename std::enable_if<std::is_convertible<U, typename std::decay<T>::type>::value>::type |
940 | | > |
941 | | typename std::decay<T>::type |
942 | | operator|( result<T, E>&& r, U&& u ) |
943 | | { |
944 | | if( r ) |
945 | | { |
946 | | return *std::move( r ); |
947 | | } |
948 | | else |
949 | | { |
950 | | return std::forward<U>( u ); |
951 | | } |
952 | | } |
953 | | |
954 | | // result | nullary-returning-value |
955 | | |
956 | | template<class T, class E, class F, |
957 | | class U = decltype( std::declval<F>()() ), |
958 | | class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
959 | | > |
960 | | T operator|( result<T, E> const& r, F&& f ) |
961 | | { |
962 | | if( r ) |
963 | | { |
964 | | return *r; |
965 | | } |
966 | | else |
967 | | { |
968 | | return std::forward<F>( f )(); |
969 | | } |
970 | | } |
971 | | |
972 | | template<class T, class E, class F, |
973 | | class U = decltype( std::declval<F>()() ), |
974 | | class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
975 | | > |
976 | | T operator|( result<T, E>&& r, F&& f ) |
977 | | { |
978 | | if( r ) |
979 | | { |
980 | | return *std::move( r ); |
981 | | } |
982 | | else |
983 | | { |
984 | | return std::forward<F>( f )(); |
985 | | } |
986 | | } |
987 | | |
988 | | template<class T, class E, class F, |
989 | | class U = decltype( std::declval<F>()() ), |
990 | | class En = typename std::enable_if< |
991 | | std::is_convertible<U, typename std::decay<T>::type>::value && |
992 | | !detail::is_value_convertible_to<U, T&>::value |
993 | | >::type |
994 | | > |
995 | | typename std::decay<T>::type |
996 | | operator|( result<T&, E> const& r, F&& f ) |
997 | | { |
998 | | if( r ) |
999 | | { |
1000 | | return *r; |
1001 | | } |
1002 | | else |
1003 | | { |
1004 | | return std::forward<F>( f )(); |
1005 | | } |
1006 | | } |
1007 | | |
1008 | | // result | nullary-returning-result |
1009 | | |
1010 | | template<class T, class E, class F, |
1011 | | class U = decltype( std::declval<F>()() ), |
1012 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1013 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<T, typename U::value_type>::value>::type |
1014 | | > |
1015 | | U operator|( result<T, E> const& r, F&& f ) |
1016 | | { |
1017 | | if( r ) |
1018 | | { |
1019 | | return *r; |
1020 | | } |
1021 | | else |
1022 | | { |
1023 | | return std::forward<F>( f )(); |
1024 | | } |
1025 | | } |
1026 | | |
1027 | | template<class T, class E, class F, |
1028 | | class U = decltype( std::declval<F>()() ), |
1029 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1030 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<T, typename U::value_type>::value>::type |
1031 | | > |
1032 | | U operator|( result<T, E>&& r, F&& f ) |
1033 | | { |
1034 | | if( r ) |
1035 | | { |
1036 | | return *std::move( r ); |
1037 | | } |
1038 | | else |
1039 | | { |
1040 | | return std::forward<F>( f )(); |
1041 | | } |
1042 | | } |
1043 | | |
1044 | | template<class E, class F, |
1045 | | class U = decltype( std::declval<F>()() ), |
1046 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1047 | | class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type |
1048 | | > |
1049 | | U operator|( result<void, E> const& r, F&& f ) |
1050 | | { |
1051 | | if( r ) |
1052 | | { |
1053 | | return {}; |
1054 | | } |
1055 | | else |
1056 | | { |
1057 | | return std::forward<F>( f )(); |
1058 | | } |
1059 | | } |
1060 | | |
1061 | | template<class E, class F, |
1062 | | class U = decltype( std::declval<F>()() ), |
1063 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1064 | | class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type |
1065 | | > |
1066 | | U operator|( result<void, E>&& r, F&& f ) |
1067 | | { |
1068 | | if( r ) |
1069 | | { |
1070 | | return {}; |
1071 | | } |
1072 | | else |
1073 | | { |
1074 | | return std::forward<F>( f )(); |
1075 | | } |
1076 | | } |
1077 | | |
1078 | | // operator|= |
1079 | | |
1080 | | // result |= value |
1081 | | |
1082 | | template<class T, class E, class U, |
1083 | | class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
1084 | | > |
1085 | | result<T, E>& operator|=( result<T, E>& r, U&& u ) |
1086 | | { |
1087 | | if( !r ) |
1088 | | { |
1089 | | r = std::forward<U>( u ); |
1090 | | } |
1091 | | |
1092 | | return r; |
1093 | | } |
1094 | | |
1095 | | // result |= nullary-returning-value |
1096 | | |
1097 | | template<class T, class E, class F, |
1098 | | class U = decltype( std::declval<F>()() ), |
1099 | | class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
1100 | | > |
1101 | | result<T, E>& operator|=( result<T, E>& r, F&& f ) |
1102 | | { |
1103 | | if( !r ) |
1104 | | { |
1105 | | r = std::forward<F>( f )(); |
1106 | | } |
1107 | | |
1108 | | return r; |
1109 | | } |
1110 | | |
1111 | | // result |= nullary-returning-result |
1112 | | |
1113 | | template<class T, class E, class F, |
1114 | | class U = decltype( std::declval<F>()() ), |
1115 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1116 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<typename U::value_type, T>::value>::type, |
1117 | | class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type |
1118 | | > |
1119 | | result<T, E>& operator|=( result<T, E>& r, F&& f ) |
1120 | | { |
1121 | | if( !r ) |
1122 | | { |
1123 | | r = std::forward<F>( f )(); |
1124 | | } |
1125 | | |
1126 | | return r; |
1127 | | } |
1128 | | |
1129 | | // operator& |
1130 | | |
1131 | | // result & unary-returning-value |
1132 | | |
1133 | | template<class T, class E, class F, |
1134 | | class U = compat::invoke_result_t<F, T&>, |
1135 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1136 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1137 | | > |
1138 | | result<U, E> operator&( result<T, E>& r, F&& f ) |
1139 | | { |
1140 | | if( r.has_error() ) |
1141 | | { |
1142 | | return r.error(); |
1143 | | } |
1144 | | else |
1145 | | { |
1146 | | return compat::invoke( std::forward<F>( f ), *r ); |
1147 | | } |
1148 | | } |
1149 | | |
1150 | | template<class T, class E, class F, |
1151 | | class U = compat::invoke_result_t<F, T const&>, |
1152 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1153 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1154 | | > |
1155 | | result<U, E> operator&( result<T, E> const& r, F&& f ) |
1156 | | { |
1157 | | if( r.has_error() ) |
1158 | | { |
1159 | | return r.error(); |
1160 | | } |
1161 | | else |
1162 | | { |
1163 | | return compat::invoke( std::forward<F>( f ), *r ); |
1164 | | } |
1165 | | } |
1166 | | |
1167 | | template<class T, class E, class F, |
1168 | | class U = typename std::decay< compat::invoke_result_t<F, T> >::type, |
1169 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1170 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1171 | | > |
1172 | | result<U, E> operator&( result<T, E>&& r, F&& f ) |
1173 | | { |
1174 | | if( r.has_error() ) |
1175 | | { |
1176 | | return r.error(); |
1177 | | } |
1178 | | else |
1179 | | { |
1180 | | return compat::invoke( std::forward<F>( f ), *std::move( r ) ); |
1181 | | } |
1182 | | } |
1183 | | |
1184 | | template<class T, class E, class F, |
1185 | | class U = compat::invoke_result_t<F, T&>, |
1186 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1187 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1188 | | > |
1189 | | result<U, E> operator&( result<T&, E>&& r, F&& f ) |
1190 | | { |
1191 | | if( r.has_error() ) |
1192 | | { |
1193 | | return r.error(); |
1194 | | } |
1195 | | else |
1196 | | { |
1197 | | return compat::invoke( std::forward<F>( f ), *std::move( r ) ); |
1198 | | } |
1199 | | } |
1200 | | |
1201 | | template<class T, class E, class F, |
1202 | | class U = compat::invoke_result_t<F, T const&>, |
1203 | | class En = typename std::enable_if<std::is_void<U>::value>::type |
1204 | | > |
1205 | | result<U, E> operator&( result<T, E> const& r, F&& f ) |
1206 | | { |
1207 | | if( r.has_error() ) |
1208 | | { |
1209 | | return r.error(); |
1210 | | } |
1211 | | else |
1212 | | { |
1213 | | compat::invoke( std::forward<F>( f ), *r ); |
1214 | | return {}; |
1215 | | } |
1216 | | } |
1217 | | |
1218 | | template<class T, class E, class F, |
1219 | | class U = compat::invoke_result_t<F, T>, |
1220 | | class En = typename std::enable_if<std::is_void<U>::value>::type |
1221 | | > |
1222 | | result<U, E> operator&( result<T, E>&& r, F&& f ) |
1223 | | { |
1224 | | if( r.has_error() ) |
1225 | | { |
1226 | | return r.error(); |
1227 | | } |
1228 | | else |
1229 | | { |
1230 | | compat::invoke( std::forward<F>( f ), *std::move( r ) ); |
1231 | | return {}; |
1232 | | } |
1233 | | } |
1234 | | |
1235 | | template<class E, class F, |
1236 | | class U = decltype( std::declval<F>()() ), |
1237 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1238 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1239 | | > |
1240 | | result<U, E> operator&( result<void, E> const& r, F&& f ) |
1241 | | { |
1242 | | if( r.has_error() ) |
1243 | | { |
1244 | | return r.error(); |
1245 | | } |
1246 | | else |
1247 | | { |
1248 | | return std::forward<F>( f )(); |
1249 | | } |
1250 | | } |
1251 | | |
1252 | | template<class E, class F, |
1253 | | class U = decltype( std::declval<F>()() ), |
1254 | | class En = typename std::enable_if<std::is_void<U>::value>::type |
1255 | | > |
1256 | | result<U, E> operator&( result<void, E> const& r, F&& f ) |
1257 | | { |
1258 | | if( r.has_error() ) |
1259 | | { |
1260 | | return r.error(); |
1261 | | } |
1262 | | else |
1263 | | { |
1264 | | std::forward<F>( f )(); |
1265 | | return {}; |
1266 | | } |
1267 | | } |
1268 | | |
1269 | | // result & unary-returning-result |
1270 | | |
1271 | | template<class T, class E, class F, |
1272 | | class U = typename std::decay< compat::invoke_result_t<F, T&> >::type, |
1273 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1274 | | class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type |
1275 | | > |
1276 | | U operator&( result<T, E>& r, F&& f ) |
1277 | | { |
1278 | | if( r.has_error() ) |
1279 | | { |
1280 | | return r.error(); |
1281 | | } |
1282 | | else |
1283 | | { |
1284 | | return compat::invoke( std::forward<F>( f ), *r ); |
1285 | | } |
1286 | | } |
1287 | | |
1288 | | template<class T, class E, class F, |
1289 | | class U = typename std::decay< compat::invoke_result_t<F, T const&> >::type, |
1290 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1291 | | class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type |
1292 | | > |
1293 | | U operator&( result<T, E> const& r, F&& f ) |
1294 | | { |
1295 | | if( r.has_error() ) |
1296 | | { |
1297 | | return r.error(); |
1298 | | } |
1299 | | else |
1300 | | { |
1301 | | return compat::invoke( std::forward<F>( f ), *r ); |
1302 | | } |
1303 | | } |
1304 | | |
1305 | | template<class T, class E, class F, |
1306 | | class U = typename std::decay< compat::invoke_result_t<F, T> >::type, |
1307 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1308 | | class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type |
1309 | | > |
1310 | | U operator&( result<T, E>&& r, F&& f ) |
1311 | | { |
1312 | | if( r.has_error() ) |
1313 | | { |
1314 | | return r.error(); |
1315 | | } |
1316 | | else |
1317 | | { |
1318 | | return compat::invoke( std::forward<F>( f ), *std::move( r ) ); |
1319 | | } |
1320 | | } |
1321 | | |
1322 | | template<class E, class F, |
1323 | | class U = decltype( std::declval<F>()() ), |
1324 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1325 | | class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type |
1326 | | > |
1327 | | U operator&( result<void, E> const& r, F&& f ) |
1328 | | { |
1329 | | if( r.has_error() ) |
1330 | | { |
1331 | | return r.error(); |
1332 | | } |
1333 | | else |
1334 | | { |
1335 | | return std::forward<F>( f )(); |
1336 | | } |
1337 | | } |
1338 | | |
1339 | | // operator&= |
1340 | | |
1341 | | // result &= unary-returning-value |
1342 | | |
1343 | | template<class T, class E, class F, |
1344 | | class U = decltype( std::declval<F>()( std::declval<T>() ) ), |
1345 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1346 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
1347 | | > |
1348 | | result<T, E>& operator&=( result<T, E>& r, F&& f ) |
1349 | | { |
1350 | | if( r ) |
1351 | | { |
1352 | | r = std::forward<F>( f )( *std::move( r ) ); |
1353 | | } |
1354 | | |
1355 | | return r; |
1356 | | } |
1357 | | |
1358 | | template<class E, class F, |
1359 | | class U = decltype( std::declval<F>()() ), |
1360 | | class En = typename std::enable_if<!detail::is_result<U>::value>::type |
1361 | | > |
1362 | | result<void, E>& operator&=( result<void, E>& r, F&& f ) |
1363 | | { |
1364 | | if( r ) |
1365 | | { |
1366 | | std::forward<F>( f )(); |
1367 | | } |
1368 | | |
1369 | | return r; |
1370 | | } |
1371 | | |
1372 | | // result &= unary-returning-result |
1373 | | |
1374 | | template<class T, class E, class F, |
1375 | | class U = decltype( std::declval<F>()( std::declval<T>() ) ), |
1376 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1377 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<typename U::value_type, T>::value>::type, |
1378 | | class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type |
1379 | | > |
1380 | | result<T, E>& operator&=( result<T, E>& r, F&& f ) |
1381 | | { |
1382 | | if( r ) |
1383 | | { |
1384 | | r = std::forward<F>( f )( *std::move( r ) ); |
1385 | | } |
1386 | | |
1387 | | return r; |
1388 | | } |
1389 | | |
1390 | | template<class E, class F, |
1391 | | class U = decltype( std::declval<F>()() ), |
1392 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1393 | | class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type, |
1394 | | class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type |
1395 | | > |
1396 | | result<void, E>& operator&=( result<void, E>& r, F&& f ) |
1397 | | { |
1398 | | if( r ) |
1399 | | { |
1400 | | r = std::forward<F>( f )(); |
1401 | | } |
1402 | | |
1403 | | return r; |
1404 | | } |
1405 | | |
1406 | | } // namespace system |
1407 | | } // namespace boost |
1408 | | |
1409 | | #endif // #ifndef BOOST_SYSTEM_RESULT_HPP_INCLUDED |