/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.unsafe_value() ); |
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 ).unsafe_value() ); |
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 | | // checked value access |
321 | | |
322 | | BOOST_CXX14_CONSTEXPR T* operator->() |
323 | | { |
324 | | return &value(); |
325 | | } |
326 | | |
327 | | BOOST_CXX14_CONSTEXPR T const* operator->() const |
328 | | { |
329 | | return &value(); |
330 | | } |
331 | | |
332 | | #if defined( BOOST_NO_CXX11_REF_QUALIFIERS ) |
333 | | |
334 | | BOOST_CXX14_CONSTEXPR T& operator*() |
335 | | { |
336 | | return value(); |
337 | | } |
338 | | |
339 | | BOOST_CXX14_CONSTEXPR T const& operator*() const |
340 | | { |
341 | | return value(); |
342 | | } |
343 | | |
344 | | #else |
345 | | |
346 | | BOOST_CXX14_CONSTEXPR T& operator*() & |
347 | | { |
348 | | return value(); |
349 | | } |
350 | | |
351 | | BOOST_CXX14_CONSTEXPR T const& operator*() const & |
352 | | { |
353 | | return value(); |
354 | | } |
355 | | |
356 | | template<class U = T> |
357 | | BOOST_CXX14_CONSTEXPR |
358 | | typename std::enable_if<std::is_move_constructible<U>::value, T>::type |
359 | | operator*() && |
360 | | { |
361 | | return std::move( value() ); |
362 | | } |
363 | | |
364 | | template<class U = T> |
365 | | BOOST_CXX14_CONSTEXPR |
366 | | typename std::enable_if<!std::is_move_constructible<U>::value, T&&>::type |
367 | | operator*() && |
368 | | { |
369 | | return std::move( value() ); |
370 | | } |
371 | | |
372 | | template<class U = T> |
373 | | BOOST_CXX14_CONSTEXPR |
374 | | typename std::enable_if<std::is_move_constructible<U>::value, T>::type |
375 | | operator*() const && = delete; |
376 | | |
377 | | template<class U = T> |
378 | | BOOST_CXX14_CONSTEXPR |
379 | | typename std::enable_if<!std::is_move_constructible<U>::value, T const&&>::type |
380 | | operator*() const && |
381 | | { |
382 | | return std::move( value() ); |
383 | | } |
384 | | |
385 | | #endif |
386 | | |
387 | | // unchecked value access |
388 | | |
389 | | #if defined( BOOST_NO_CXX11_REF_QUALIFIERS ) |
390 | | |
391 | | BOOST_CXX14_CONSTEXPR T& unsafe_value() |
392 | | { |
393 | | BOOST_ASSERT( has_value() ); |
394 | | return *variant2::get_if<0>( &v_ ); |
395 | | } |
396 | | |
397 | | BOOST_CXX14_CONSTEXPR T const& unsafe_value() const |
398 | | { |
399 | | BOOST_ASSERT( has_value() ); |
400 | | return *variant2::get_if<0>( &v_ ); |
401 | | } |
402 | | |
403 | | #else |
404 | | |
405 | | BOOST_CXX14_CONSTEXPR T& unsafe_value() & |
406 | | { |
407 | | BOOST_ASSERT( has_value() ); |
408 | | return *variant2::get_if<0>( &v_ ); |
409 | | } |
410 | | |
411 | | BOOST_CXX14_CONSTEXPR T const& unsafe_value() const & |
412 | | { |
413 | | BOOST_ASSERT( has_value() ); |
414 | | return *variant2::get_if<0>( &v_ ); |
415 | | } |
416 | | |
417 | | template<class U = T> |
418 | | BOOST_CXX14_CONSTEXPR |
419 | | typename std::enable_if<std::is_move_constructible<U>::value, T>::type |
420 | | unsafe_value() && |
421 | | { |
422 | | BOOST_ASSERT( has_value() ); |
423 | | return std::move( *variant2::get_if<0>( &v_ ) ); |
424 | | } |
425 | | |
426 | | template<class U = T> |
427 | | BOOST_CXX14_CONSTEXPR |
428 | | typename std::enable_if<!std::is_move_constructible<U>::value, T&&>::type |
429 | | unsafe_value() && |
430 | | { |
431 | | BOOST_ASSERT( has_value() ); |
432 | | return std::move( *variant2::get_if<0>( &v_ ) ); |
433 | | } |
434 | | |
435 | | template<class U = T> |
436 | | BOOST_CXX14_CONSTEXPR |
437 | | typename std::enable_if<std::is_move_constructible<U>::value, T>::type |
438 | | unsafe_value() const && = delete; |
439 | | |
440 | | template<class U = T> |
441 | | BOOST_CXX14_CONSTEXPR |
442 | | typename std::enable_if<!std::is_move_constructible<U>::value, T const&&>::type |
443 | | unsafe_value() const && |
444 | | { |
445 | | BOOST_ASSERT( has_value() ); |
446 | | return std::move( *variant2::get_if<0>( &v_ ) ); |
447 | | } |
448 | | |
449 | | #endif |
450 | | |
451 | | // error access |
452 | | |
453 | | constexpr E error() const & |
454 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value ) |
455 | | { |
456 | | return has_error()? variant2::unsafe_get<1>( v_ ): E(); |
457 | | } |
458 | | |
459 | | BOOST_CXX14_CONSTEXPR E error() && |
460 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value ) |
461 | | { |
462 | | return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E(); |
463 | | } |
464 | | |
465 | | // emplace |
466 | | |
467 | | template<class... A> |
468 | | BOOST_CXX14_CONSTEXPR T& emplace( A&&... a ) |
469 | | { |
470 | | return v_.template emplace<0>( std::forward<A>(a)... ); |
471 | | } |
472 | | |
473 | | // swap |
474 | | |
475 | | BOOST_CXX14_CONSTEXPR void swap( result& r ) |
476 | | noexcept( noexcept( v_.swap( r.v_ ) ) ) |
477 | | { |
478 | | v_.swap( r.v_ ); |
479 | | } |
480 | | |
481 | | friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 ) |
482 | | noexcept( noexcept( r1.swap( r2 ) ) ) |
483 | | { |
484 | | r1.swap( r2 ); |
485 | | } |
486 | | |
487 | | // equality |
488 | | |
489 | | friend constexpr bool operator==( result const & r1, result const & r2 ) |
490 | | noexcept( noexcept( r1.v_ == r2.v_ ) ) |
491 | | { |
492 | | return r1.v_ == r2.v_; |
493 | | } |
494 | | |
495 | | friend constexpr bool operator!=( result const & r1, result const & r2 ) |
496 | | noexcept( noexcept( !( r1 == r2 ) ) ) |
497 | | { |
498 | | return !( r1 == r2 ); |
499 | | } |
500 | | }; |
501 | | |
502 | | #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) |
503 | | |
504 | | template<class T, class E> constexpr in_place_value_t result<T, E>::in_place_value; |
505 | | template<class T, class E> constexpr in_place_error_t result<T, E>::in_place_error; |
506 | | |
507 | | #endif |
508 | | |
509 | | 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 ) |
510 | | { |
511 | | if( r.has_value() ) |
512 | | { |
513 | | os << "value:" << r.unsafe_value(); |
514 | | } |
515 | | else |
516 | | { |
517 | | os << "error:" << r.error(); |
518 | | } |
519 | | |
520 | | return os; |
521 | | } |
522 | | |
523 | | // result<void> |
524 | | |
525 | | template<class E> class result<void, E> |
526 | | { |
527 | | private: |
528 | | |
529 | | variant2::variant<variant2::monostate, E> v_; |
530 | | |
531 | | public: |
532 | | |
533 | | using value_type = void; |
534 | | using error_type = E; |
535 | | |
536 | | static constexpr in_place_value_t in_place_value{}; |
537 | | static constexpr in_place_error_t in_place_error{}; |
538 | | |
539 | | public: |
540 | | |
541 | | // constructors |
542 | | |
543 | | // default |
544 | | constexpr result() noexcept |
545 | | : v_( in_place_value ) |
546 | | { |
547 | | } |
548 | | |
549 | | // explicit, error |
550 | | template<class A, class En = typename std::enable_if< |
551 | | std::is_constructible<E, A>::value && |
552 | | !std::is_convertible<A, E>::value |
553 | | >::type> |
554 | | explicit constexpr result( A&& a ) |
555 | | noexcept( std::is_nothrow_constructible<E, A>::value ) |
556 | | : v_( in_place_error, std::forward<A>(a) ) |
557 | | { |
558 | | } |
559 | | |
560 | | // implicit, error |
561 | | template<class A, class En2 = void, class En = typename std::enable_if< |
562 | | std::is_convertible<A, E>::value |
563 | | >::type> |
564 | | constexpr result( A&& a ) |
565 | | noexcept( std::is_nothrow_constructible<E, A>::value ) |
566 | | : v_( in_place_error, std::forward<A>(a) ) |
567 | | { |
568 | | } |
569 | | |
570 | | // more than one arg, error |
571 | | template<class... A, class En2 = void, class En3 = void, class En = typename std::enable_if< |
572 | | std::is_constructible<E, A...>::value && |
573 | | sizeof...(A) >= 2 |
574 | | >::type> |
575 | | constexpr result( A&&... a ) |
576 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
577 | | : v_( in_place_error, std::forward<A>(a)... ) |
578 | | { |
579 | | } |
580 | | |
581 | | // tagged, value |
582 | | constexpr result( in_place_value_t ) noexcept |
583 | | : v_( in_place_value ) |
584 | | { |
585 | | } |
586 | | |
587 | | // tagged, error |
588 | | template<class... A, class En = typename std::enable_if< |
589 | | std::is_constructible<E, A...>::value |
590 | | >::type> |
591 | | constexpr result( in_place_error_t, A&&... a ) |
592 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
593 | | : v_( in_place_error, std::forward<A>(a)... ) |
594 | | { |
595 | | } |
596 | | |
597 | | // converting |
598 | | template<class E2, class En = typename std::enable_if< |
599 | | std::is_convertible<E2, E>::value |
600 | | >::type> |
601 | | BOOST_CXX14_CONSTEXPR result( result<void, E2> const& r2 ) |
602 | | noexcept( |
603 | | std::is_nothrow_constructible<E, E2>::value && |
604 | | std::is_nothrow_default_constructible<E2>::value && |
605 | | std::is_nothrow_copy_constructible<E2>::value ) |
606 | | : v_( in_place_error, r2.error() ) |
607 | | { |
608 | | if( r2 ) |
609 | | { |
610 | | this->emplace(); |
611 | | } |
612 | | } |
613 | | |
614 | | // queries |
615 | | |
616 | | constexpr bool has_value() const noexcept |
617 | | { |
618 | | return v_.index() == 0; |
619 | | } |
620 | | |
621 | | constexpr bool has_error() const noexcept |
622 | | { |
623 | | return v_.index() == 1; |
624 | | } |
625 | | |
626 | | constexpr explicit operator bool() const noexcept |
627 | | { |
628 | | return v_.index() == 0; |
629 | | } |
630 | | |
631 | | // checked value access |
632 | | |
633 | | BOOST_CXX14_CONSTEXPR void value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const |
634 | | { |
635 | | if( has_value() ) |
636 | | { |
637 | | } |
638 | | else |
639 | | { |
640 | | throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc ); |
641 | | } |
642 | | } |
643 | | |
644 | | // checked value access |
645 | | |
646 | | BOOST_CXX14_CONSTEXPR void* operator->() |
647 | | { |
648 | | value(); |
649 | | return &variant2::unsafe_get<0>( v_ ); |
650 | | } |
651 | | |
652 | | BOOST_CXX14_CONSTEXPR void const* operator->() const |
653 | | { |
654 | | value(); |
655 | | return &variant2::unsafe_get<0>( v_ ); |
656 | | } |
657 | | |
658 | | BOOST_CXX14_CONSTEXPR void operator*() const |
659 | | { |
660 | | return value(); |
661 | | } |
662 | | |
663 | | // unchecked value access |
664 | | |
665 | | BOOST_CXX14_CONSTEXPR void unsafe_value() const |
666 | | { |
667 | | BOOST_ASSERT( has_value() ); |
668 | | } |
669 | | |
670 | | // error access |
671 | | |
672 | | constexpr E error() const & |
673 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value ) |
674 | | { |
675 | | return has_error()? variant2::unsafe_get<1>( v_ ): E(); |
676 | | } |
677 | | |
678 | | BOOST_CXX14_CONSTEXPR E error() && |
679 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value ) |
680 | | { |
681 | | return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E(); |
682 | | } |
683 | | |
684 | | // emplace |
685 | | |
686 | | BOOST_CXX14_CONSTEXPR void emplace() |
687 | | { |
688 | | v_.template emplace<0>(); |
689 | | } |
690 | | |
691 | | // swap |
692 | | |
693 | | BOOST_CXX14_CONSTEXPR void swap( result& r ) |
694 | | noexcept( noexcept( v_.swap( r.v_ ) ) ) |
695 | | { |
696 | | v_.swap( r.v_ ); |
697 | | } |
698 | | |
699 | | friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 ) |
700 | | noexcept( noexcept( r1.swap( r2 ) ) ) |
701 | | { |
702 | | r1.swap( r2 ); |
703 | | } |
704 | | |
705 | | // equality |
706 | | |
707 | | friend constexpr bool operator==( result const & r1, result const & r2 ) |
708 | | noexcept( noexcept( r1.v_ == r2.v_ ) ) |
709 | | { |
710 | | return r1.v_ == r2.v_; |
711 | | } |
712 | | |
713 | | friend constexpr bool operator!=( result const & r1, result const & r2 ) |
714 | | noexcept( noexcept( !( r1 == r2 ) ) ) |
715 | | { |
716 | | return !( r1 == r2 ); |
717 | | } |
718 | | }; |
719 | | |
720 | | #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) |
721 | | |
722 | | template<class E> constexpr in_place_value_t result<void, E>::in_place_value; |
723 | | template<class E> constexpr in_place_error_t result<void, E>::in_place_error; |
724 | | |
725 | | #endif |
726 | | |
727 | | template<class Ch, class Tr, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<void, E> const & r ) |
728 | | { |
729 | | if( r.has_value() ) |
730 | | { |
731 | | os << "value:void"; |
732 | | } |
733 | | else |
734 | | { |
735 | | os << "error:" << r.error(); |
736 | | } |
737 | | |
738 | | return os; |
739 | | } |
740 | | |
741 | | // result<T&, E> |
742 | | |
743 | | namespace detail |
744 | | { |
745 | | |
746 | | template<class U, class A> struct reference_to_temporary: std::integral_constant<bool, |
747 | | !std::is_reference<A>::value || |
748 | | !std::is_convertible<typename std::remove_reference<A>::type*, U*>::value |
749 | | > {}; |
750 | | |
751 | | } // namespace detail |
752 | | |
753 | | template<class U, class E> class result<U&, E> |
754 | | { |
755 | | private: |
756 | | |
757 | | variant2::variant<U*, E> v_; |
758 | | |
759 | | public: |
760 | | |
761 | | using value_type = U&; |
762 | | using error_type = E; |
763 | | |
764 | | static constexpr in_place_value_t in_place_value{}; |
765 | | static constexpr in_place_error_t in_place_error{}; |
766 | | |
767 | | public: |
768 | | |
769 | | // constructors |
770 | | |
771 | | // implicit, value |
772 | | template<class A, typename std::enable_if< |
773 | | std::is_convertible<A, U&>::value && |
774 | | !detail::reference_to_temporary<U, A>::value && |
775 | | !std::is_convertible<A, E>::value, int>::type = 0> |
776 | | constexpr result( A&& a ) |
777 | | noexcept( std::is_nothrow_constructible<U&, A>::value ) |
778 | 0 | : v_( in_place_value, &static_cast<U&>( std::forward<A>(a) ) ) |
779 | 0 | { |
780 | 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_ |
781 | | |
782 | | // implicit, error |
783 | | template<class A = E, class = void, typename std::enable_if< |
784 | | std::is_convertible<A, E>::value && |
785 | | !std::is_convertible<A, U&>::value, int>::type = 0> |
786 | | constexpr result( A&& a ) |
787 | | noexcept( std::is_nothrow_constructible<E, A>::value ) |
788 | 0 | : v_( in_place_error, std::forward<A>(a) ) |
789 | 0 | { |
790 | 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_ |
791 | | |
792 | | // explicit, value |
793 | | template<class A, class En = typename std::enable_if< |
794 | | detail::is_constructible<U&, A>::value && |
795 | | !std::is_convertible<A, U&>::value && |
796 | | !detail::reference_to_temporary<U, A>::value && |
797 | | !detail::is_constructible<E, A>::value |
798 | | >::type> |
799 | | explicit constexpr result( A&& a ) |
800 | | noexcept( std::is_nothrow_constructible<U&, A>::value ) |
801 | | : v_( in_place_value, &static_cast<U&>( std::forward<A>(a) ) ) |
802 | | { |
803 | | } |
804 | | |
805 | | // explicit, error |
806 | | template<class... A, class En2 = void, class En = typename std::enable_if< |
807 | | !detail::is_constructible<U&, A...>::value && |
808 | | detail::is_constructible<E, A...>::value && |
809 | | sizeof...(A) >= 1 |
810 | | >::type> |
811 | | explicit constexpr result( A&&... a ) |
812 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
813 | | : v_( in_place_error, std::forward<A>(a)... ) |
814 | | { |
815 | | } |
816 | | |
817 | | // tagged, value |
818 | | template<class A, class En = typename std::enable_if< |
819 | | std::is_constructible<U&, A>::value && |
820 | | !detail::reference_to_temporary<U, A>::value |
821 | | >::type> |
822 | | constexpr result( in_place_value_t, A&& a ) |
823 | | noexcept( std::is_nothrow_constructible<U&, A>::value ) |
824 | | : v_( in_place_value, &static_cast<U&>( std::forward<A>(a) ) ) |
825 | | { |
826 | | } |
827 | | |
828 | | // tagged, error |
829 | | template<class... A, class En = typename std::enable_if< |
830 | | std::is_constructible<E, A...>::value |
831 | | >::type> |
832 | | constexpr result( in_place_error_t, A&&... a ) |
833 | | noexcept( std::is_nothrow_constructible<E, A...>::value ) |
834 | | : v_( in_place_error, std::forward<A>(a)... ) |
835 | | { |
836 | | } |
837 | | |
838 | | // converting |
839 | | template<class U2, class E2, class En = typename std::enable_if< |
840 | | std::is_convertible<U2&, U&>::value && |
841 | | !detail::reference_to_temporary<U, U2&>::value && |
842 | | std::is_convertible<E2, E>::value && |
843 | | !std::is_convertible<result<U2&, E2> const&, U&>::value |
844 | | >::type> |
845 | | BOOST_CXX14_CONSTEXPR result( result<U2&, E2> const& r2 ) |
846 | | noexcept( |
847 | | std::is_nothrow_constructible<U&, U2&>::value && |
848 | | std::is_nothrow_constructible<E, E2>::value && |
849 | | std::is_nothrow_default_constructible<E2>::value && |
850 | | std::is_nothrow_copy_constructible<E2>::value ) |
851 | | : v_( in_place_error, r2.error() ) |
852 | | { |
853 | | if( r2 ) |
854 | | { |
855 | | this->emplace( r2.unsafe_value() ); |
856 | | } |
857 | | } |
858 | | |
859 | | // queries |
860 | | |
861 | | constexpr bool has_value() const noexcept |
862 | 0 | { |
863 | 0 | return v_.index() == 0; |
864 | 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 |
865 | | |
866 | | constexpr bool has_error() const noexcept |
867 | 0 | { |
868 | 0 | return v_.index() == 1; |
869 | 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 |
870 | | |
871 | | constexpr explicit operator bool() const noexcept |
872 | 0 | { |
873 | 0 | return v_.index() == 0; |
874 | 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 |
875 | | |
876 | | // checked value access |
877 | | |
878 | | BOOST_CXX14_CONSTEXPR U& value( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) const |
879 | 0 | { |
880 | 0 | if( has_value() ) |
881 | 0 | { |
882 | 0 | return *variant2::unsafe_get<0>( v_ ); |
883 | 0 | } |
884 | 0 | else |
885 | 0 | { |
886 | 0 | throw_exception_from_error( variant2::unsafe_get<1>( v_ ), loc ); |
887 | 0 | } |
888 | 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 |
889 | | |
890 | | // checked value access |
891 | | |
892 | | BOOST_CXX14_CONSTEXPR U* operator->() const |
893 | | { |
894 | | return &value(); |
895 | | } |
896 | | |
897 | | BOOST_CXX14_CONSTEXPR U& operator*() const |
898 | | { |
899 | | return value(); |
900 | | } |
901 | | |
902 | | // unchecked value access |
903 | | |
904 | | BOOST_CXX14_CONSTEXPR U& unsafe_value() const |
905 | 0 | { |
906 | 0 | BOOST_ASSERT( has_value() ); |
907 | 0 | return *( has_value()? variant2::unsafe_get<0>( v_ ): 0 ); |
908 | 0 | } Unexecuted instantiation: boost::system::result<boost::json::object&, boost::system::error_code>::unsafe_value() const Unexecuted instantiation: boost::system::result<boost::json::object const&, boost::system::error_code>::unsafe_value() const Unexecuted instantiation: boost::system::result<boost::json::array&, boost::system::error_code>::unsafe_value() const Unexecuted instantiation: boost::system::result<boost::json::array const&, boost::system::error_code>::unsafe_value() const |
909 | | |
910 | | // error access |
911 | | |
912 | | constexpr E error() const & |
913 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_copy_constructible<E>::value ) |
914 | 0 | { |
915 | 0 | return has_error()? variant2::unsafe_get<1>( v_ ): E(); |
916 | 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 & |
917 | | |
918 | | BOOST_CXX14_CONSTEXPR E error() && |
919 | | noexcept( std::is_nothrow_default_constructible<E>::value && std::is_nothrow_move_constructible<E>::value ) |
920 | | { |
921 | | return has_error()? std::move( variant2::unsafe_get<1>( v_ ) ): E(); |
922 | | } |
923 | | |
924 | | // emplace |
925 | | |
926 | | template<class A, class En = typename std::enable_if< |
927 | | detail::is_constructible<U&, A>::value && |
928 | | !detail::reference_to_temporary<U, A>::value |
929 | | >::type> |
930 | | BOOST_CXX14_CONSTEXPR U& emplace( A&& a ) |
931 | | { |
932 | | return *v_.template emplace<0>( &static_cast<U&>( a ) ); |
933 | | } |
934 | | |
935 | | // swap |
936 | | |
937 | | BOOST_CXX14_CONSTEXPR void swap( result& r ) |
938 | | noexcept( noexcept( v_.swap( r.v_ ) ) ) |
939 | | { |
940 | | v_.swap( r.v_ ); |
941 | | } |
942 | | |
943 | | friend BOOST_CXX14_CONSTEXPR void swap( result & r1, result & r2 ) |
944 | | noexcept( noexcept( r1.swap( r2 ) ) ) |
945 | | { |
946 | | r1.swap( r2 ); |
947 | | } |
948 | | |
949 | | // equality |
950 | | |
951 | | friend constexpr bool operator==( result const & r1, result const & r2 ) |
952 | | noexcept( noexcept( r1 && r2? r1.unsafe_value() == r2.unsafe_value(): r1.v_ == r2.v_ ) ) |
953 | | { |
954 | | return r1 && r2? r1.unsafe_value() == r2.unsafe_value(): r1.v_ == r2.v_; |
955 | | } |
956 | | |
957 | | friend constexpr bool operator!=( result const & r1, result const & r2 ) |
958 | | noexcept( noexcept( !( r1 == r2 ) ) ) |
959 | | { |
960 | | return !( r1 == r2 ); |
961 | | } |
962 | | }; |
963 | | |
964 | | #if defined(BOOST_NO_CXX17_INLINE_VARIABLES) |
965 | | |
966 | | template<class U, class E> constexpr in_place_value_t result<U&, E>::in_place_value; |
967 | | template<class U, class E> constexpr in_place_error_t result<U&, E>::in_place_error; |
968 | | |
969 | | #endif |
970 | | |
971 | | // operator| |
972 | | |
973 | | namespace detail |
974 | | { |
975 | | |
976 | | // is_value_convertible_to |
977 | | |
978 | | template<class T, class U> struct is_value_convertible_to: std::is_convertible<T, U> |
979 | | { |
980 | | }; |
981 | | |
982 | | template<class T, class U> struct is_value_convertible_to<T, U&>: |
983 | | std::integral_constant<bool, |
984 | | std::is_lvalue_reference<T>::value && |
985 | | std::is_convertible<typename std::remove_reference<T>::type*, U*>::value> |
986 | | { |
987 | | }; |
988 | | |
989 | | // is_result |
990 | | |
991 | | template<class T> struct is_result: std::false_type {}; |
992 | | template<class T, class E> struct is_result< result<T, E> >: std::true_type {}; |
993 | | |
994 | | } // namespace detail |
995 | | |
996 | | // result | value |
997 | | |
998 | | template<class T, class E, class U, |
999 | | class En = typename std::enable_if<std::is_convertible<U, typename std::decay<T>::type>::value>::type |
1000 | | > |
1001 | | typename std::decay<T>::type |
1002 | | operator|( result<T, E> const& r, U&& u ) |
1003 | | { |
1004 | | if( r ) |
1005 | | { |
1006 | | return r.unsafe_value(); |
1007 | | } |
1008 | | else |
1009 | | { |
1010 | | return std::forward<U>( u ); |
1011 | | } |
1012 | | } |
1013 | | |
1014 | | template<class T, class E, class U, |
1015 | | class En = typename std::enable_if<std::is_convertible<U, typename std::decay<T>::type>::value>::type |
1016 | | > |
1017 | | typename std::decay<T>::type |
1018 | | operator|( result<T, E>&& r, U&& u ) |
1019 | | { |
1020 | | if( r ) |
1021 | | { |
1022 | | return std::move( r ).unsafe_value(); |
1023 | | } |
1024 | | else |
1025 | | { |
1026 | | return std::forward<U>( u ); |
1027 | | } |
1028 | | } |
1029 | | |
1030 | | // result | nullary-returning-value |
1031 | | |
1032 | | template<class T, class E, class F, |
1033 | | class U = decltype( std::declval<F>()() ), |
1034 | | class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
1035 | | > |
1036 | | T operator|( result<T, E> const& r, F&& f ) |
1037 | | { |
1038 | | if( r ) |
1039 | | { |
1040 | | return r.unsafe_value(); |
1041 | | } |
1042 | | else |
1043 | | { |
1044 | | return std::forward<F>( f )(); |
1045 | | } |
1046 | | } |
1047 | | |
1048 | | template<class T, class E, class F, |
1049 | | class U = decltype( std::declval<F>()() ), |
1050 | | class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
1051 | | > |
1052 | | T operator|( result<T, E>&& r, F&& f ) |
1053 | | { |
1054 | | if( r ) |
1055 | | { |
1056 | | return std::move( r ).unsafe_value(); |
1057 | | } |
1058 | | else |
1059 | | { |
1060 | | return std::forward<F>( f )(); |
1061 | | } |
1062 | | } |
1063 | | |
1064 | | template<class T, class E, class F, |
1065 | | class U = decltype( std::declval<F>()() ), |
1066 | | class En = typename std::enable_if< |
1067 | | std::is_convertible<U, typename std::decay<T>::type>::value && |
1068 | | !detail::is_value_convertible_to<U, T&>::value |
1069 | | >::type |
1070 | | > |
1071 | | typename std::decay<T>::type |
1072 | | operator|( result<T&, E> const& r, F&& f ) |
1073 | | { |
1074 | | if( r ) |
1075 | | { |
1076 | | return r.unsafe_value(); |
1077 | | } |
1078 | | else |
1079 | | { |
1080 | | return std::forward<F>( f )(); |
1081 | | } |
1082 | | } |
1083 | | |
1084 | | // result | nullary-returning-result |
1085 | | |
1086 | | template<class T, class E, class F, |
1087 | | class U = decltype( std::declval<F>()() ), |
1088 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1089 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<T, typename U::value_type>::value>::type |
1090 | | > |
1091 | | U operator|( result<T, E> const& r, F&& f ) |
1092 | | { |
1093 | | if( r ) |
1094 | | { |
1095 | | return r.unsafe_value(); |
1096 | | } |
1097 | | else |
1098 | | { |
1099 | | return std::forward<F>( f )(); |
1100 | | } |
1101 | | } |
1102 | | |
1103 | | template<class T, class E, class F, |
1104 | | class U = decltype( std::declval<F>()() ), |
1105 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1106 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<T, typename U::value_type>::value>::type |
1107 | | > |
1108 | | U operator|( result<T, E>&& r, F&& f ) |
1109 | | { |
1110 | | if( r ) |
1111 | | { |
1112 | | return std::move( r ).unsafe_value(); |
1113 | | } |
1114 | | else |
1115 | | { |
1116 | | return std::forward<F>( f )(); |
1117 | | } |
1118 | | } |
1119 | | |
1120 | | template<class E, class F, |
1121 | | class U = decltype( std::declval<F>()() ), |
1122 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1123 | | class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type |
1124 | | > |
1125 | | U operator|( result<void, E> const& r, F&& f ) |
1126 | | { |
1127 | | if( r ) |
1128 | | { |
1129 | | return {}; |
1130 | | } |
1131 | | else |
1132 | | { |
1133 | | return std::forward<F>( f )(); |
1134 | | } |
1135 | | } |
1136 | | |
1137 | | template<class E, class F, |
1138 | | class U = decltype( std::declval<F>()() ), |
1139 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1140 | | class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type |
1141 | | > |
1142 | | U operator|( result<void, E>&& r, F&& f ) |
1143 | | { |
1144 | | if( r ) |
1145 | | { |
1146 | | return {}; |
1147 | | } |
1148 | | else |
1149 | | { |
1150 | | return std::forward<F>( f )(); |
1151 | | } |
1152 | | } |
1153 | | |
1154 | | // operator|= |
1155 | | |
1156 | | // result |= value |
1157 | | |
1158 | | template<class T, class E, class U, |
1159 | | class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
1160 | | > |
1161 | | result<T, E>& operator|=( result<T, E>& r, U&& u ) |
1162 | | { |
1163 | | if( !r ) |
1164 | | { |
1165 | | r = std::forward<U>( u ); |
1166 | | } |
1167 | | |
1168 | | return r; |
1169 | | } |
1170 | | |
1171 | | // result |= nullary-returning-value |
1172 | | |
1173 | | template<class T, class E, class F, |
1174 | | class U = decltype( std::declval<F>()() ), |
1175 | | class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
1176 | | > |
1177 | | result<T, E>& operator|=( result<T, E>& r, F&& f ) |
1178 | | { |
1179 | | if( !r ) |
1180 | | { |
1181 | | r = std::forward<F>( f )(); |
1182 | | } |
1183 | | |
1184 | | return r; |
1185 | | } |
1186 | | |
1187 | | // result |= nullary-returning-result |
1188 | | |
1189 | | template<class T, class E, class F, |
1190 | | class U = decltype( std::declval<F>()() ), |
1191 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1192 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<typename U::value_type, T>::value>::type, |
1193 | | class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type |
1194 | | > |
1195 | | result<T, E>& operator|=( result<T, E>& r, F&& f ) |
1196 | | { |
1197 | | if( !r ) |
1198 | | { |
1199 | | r = std::forward<F>( f )(); |
1200 | | } |
1201 | | |
1202 | | return r; |
1203 | | } |
1204 | | |
1205 | | // operator& |
1206 | | |
1207 | | // result & unary-returning-value |
1208 | | |
1209 | | template<class T, class E, class F, |
1210 | | class U = compat::invoke_result_t<F, T&>, |
1211 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1212 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1213 | | > |
1214 | | result<U, E> operator&( result<T, E>& r, F&& f ) |
1215 | | { |
1216 | | if( r.has_error() ) |
1217 | | { |
1218 | | return r.error(); |
1219 | | } |
1220 | | else |
1221 | | { |
1222 | | return compat::invoke( std::forward<F>( f ), r.unsafe_value() ); |
1223 | | } |
1224 | | } |
1225 | | |
1226 | | template<class T, class E, class F, |
1227 | | class U = compat::invoke_result_t<F, T const&>, |
1228 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1229 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1230 | | > |
1231 | | result<U, E> operator&( result<T, E> const& r, F&& f ) |
1232 | | { |
1233 | | if( r.has_error() ) |
1234 | | { |
1235 | | return r.error(); |
1236 | | } |
1237 | | else |
1238 | | { |
1239 | | return compat::invoke( std::forward<F>( f ), r.unsafe_value() ); |
1240 | | } |
1241 | | } |
1242 | | |
1243 | | template<class T, class E, class F, |
1244 | | class U = typename std::decay< compat::invoke_result_t<F, T> >::type, |
1245 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1246 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1247 | | > |
1248 | | result<U, E> operator&( result<T, E>&& r, F&& f ) |
1249 | | { |
1250 | | if( r.has_error() ) |
1251 | | { |
1252 | | return r.error(); |
1253 | | } |
1254 | | else |
1255 | | { |
1256 | | return compat::invoke( std::forward<F>( f ), std::move( r ).unsafe_value() ); |
1257 | | } |
1258 | | } |
1259 | | |
1260 | | template<class T, class E, class F, |
1261 | | class U = compat::invoke_result_t<F, T&>, |
1262 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1263 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1264 | | > |
1265 | | result<U, E> operator&( result<T&, E>&& r, F&& f ) |
1266 | | { |
1267 | | if( r.has_error() ) |
1268 | | { |
1269 | | return r.error(); |
1270 | | } |
1271 | | else |
1272 | | { |
1273 | | return compat::invoke( std::forward<F>( f ), std::move( r ).unsafe_value() ); |
1274 | | } |
1275 | | } |
1276 | | |
1277 | | template<class T, class E, class F, |
1278 | | class U = compat::invoke_result_t<F, T const&>, |
1279 | | class En = typename std::enable_if<std::is_void<U>::value>::type |
1280 | | > |
1281 | | result<U, E> operator&( result<T, E> const& r, F&& f ) |
1282 | | { |
1283 | | if( r.has_error() ) |
1284 | | { |
1285 | | return r.error(); |
1286 | | } |
1287 | | else |
1288 | | { |
1289 | | compat::invoke( std::forward<F>( f ), r.unsafe_value() ); |
1290 | | return {}; |
1291 | | } |
1292 | | } |
1293 | | |
1294 | | template<class T, class E, class F, |
1295 | | class U = compat::invoke_result_t<F, T>, |
1296 | | class En = typename std::enable_if<std::is_void<U>::value>::type |
1297 | | > |
1298 | | result<U, E> operator&( result<T, E>&& r, F&& f ) |
1299 | | { |
1300 | | if( r.has_error() ) |
1301 | | { |
1302 | | return r.error(); |
1303 | | } |
1304 | | else |
1305 | | { |
1306 | | compat::invoke( std::forward<F>( f ), std::move( r ).unsafe_value() ); |
1307 | | return {}; |
1308 | | } |
1309 | | } |
1310 | | |
1311 | | template<class E, class F, |
1312 | | class U = decltype( std::declval<F>()() ), |
1313 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1314 | | class En2 = typename std::enable_if<!std::is_void<U>::value>::type |
1315 | | > |
1316 | | result<U, E> operator&( result<void, E> const& r, F&& f ) |
1317 | | { |
1318 | | if( r.has_error() ) |
1319 | | { |
1320 | | return r.error(); |
1321 | | } |
1322 | | else |
1323 | | { |
1324 | | return std::forward<F>( f )(); |
1325 | | } |
1326 | | } |
1327 | | |
1328 | | template<class E, class F, |
1329 | | class U = decltype( std::declval<F>()() ), |
1330 | | class En = typename std::enable_if<std::is_void<U>::value>::type |
1331 | | > |
1332 | | result<U, E> operator&( result<void, E> const& r, F&& f ) |
1333 | | { |
1334 | | if( r.has_error() ) |
1335 | | { |
1336 | | return r.error(); |
1337 | | } |
1338 | | else |
1339 | | { |
1340 | | std::forward<F>( f )(); |
1341 | | return {}; |
1342 | | } |
1343 | | } |
1344 | | |
1345 | | // result & unary-returning-result |
1346 | | |
1347 | | template<class T, class E, class F, |
1348 | | class U = typename std::decay< compat::invoke_result_t<F, T&> >::type, |
1349 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1350 | | class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type |
1351 | | > |
1352 | | U operator&( result<T, E>& r, F&& f ) |
1353 | | { |
1354 | | if( r.has_error() ) |
1355 | | { |
1356 | | return r.error(); |
1357 | | } |
1358 | | else |
1359 | | { |
1360 | | return compat::invoke( std::forward<F>( f ), r.unsafe_value() ); |
1361 | | } |
1362 | | } |
1363 | | |
1364 | | template<class T, class E, class F, |
1365 | | class U = typename std::decay< compat::invoke_result_t<F, T const&> >::type, |
1366 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1367 | | class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type |
1368 | | > |
1369 | | U operator&( result<T, E> const& r, F&& f ) |
1370 | | { |
1371 | | if( r.has_error() ) |
1372 | | { |
1373 | | return r.error(); |
1374 | | } |
1375 | | else |
1376 | | { |
1377 | | return compat::invoke( std::forward<F>( f ), r.unsafe_value() ); |
1378 | | } |
1379 | | } |
1380 | | |
1381 | | template<class T, class E, class F, |
1382 | | class U = typename std::decay< compat::invoke_result_t<F, T> >::type, |
1383 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1384 | | class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type |
1385 | | > |
1386 | | U operator&( result<T, E>&& r, F&& f ) |
1387 | | { |
1388 | | if( r.has_error() ) |
1389 | | { |
1390 | | return r.error(); |
1391 | | } |
1392 | | else |
1393 | | { |
1394 | | return compat::invoke( std::forward<F>( f ), std::move( r ).unsafe_value() ); |
1395 | | } |
1396 | | } |
1397 | | |
1398 | | template<class E, class F, |
1399 | | class U = decltype( std::declval<F>()() ), |
1400 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1401 | | class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type |
1402 | | > |
1403 | | U operator&( result<void, E> const& r, F&& f ) |
1404 | | { |
1405 | | if( r.has_error() ) |
1406 | | { |
1407 | | return r.error(); |
1408 | | } |
1409 | | else |
1410 | | { |
1411 | | return std::forward<F>( f )(); |
1412 | | } |
1413 | | } |
1414 | | |
1415 | | // operator&= |
1416 | | |
1417 | | // result &= unary-returning-value |
1418 | | |
1419 | | template<class T, class E, class F, |
1420 | | class U = decltype( std::declval<F>()( std::declval<T>() ) ), |
1421 | | class En1 = typename std::enable_if<!detail::is_result<U>::value>::type, |
1422 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type |
1423 | | > |
1424 | | result<T, E>& operator&=( result<T, E>& r, F&& f ) |
1425 | | { |
1426 | | if( r ) |
1427 | | { |
1428 | | r = std::forward<F>( f )( std::move( r ).unsafe_value() ); |
1429 | | } |
1430 | | |
1431 | | return r; |
1432 | | } |
1433 | | |
1434 | | template<class E, class F, |
1435 | | class U = decltype( std::declval<F>()() ), |
1436 | | class En = typename std::enable_if<!detail::is_result<U>::value>::type |
1437 | | > |
1438 | | result<void, E>& operator&=( result<void, E>& r, F&& f ) |
1439 | | { |
1440 | | if( r ) |
1441 | | { |
1442 | | std::forward<F>( f )(); |
1443 | | } |
1444 | | |
1445 | | return r; |
1446 | | } |
1447 | | |
1448 | | // result &= unary-returning-result |
1449 | | |
1450 | | template<class T, class E, class F, |
1451 | | class U = decltype( std::declval<F>()( std::declval<T>() ) ), |
1452 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1453 | | class En2 = typename std::enable_if<detail::is_value_convertible_to<typename U::value_type, T>::value>::type, |
1454 | | class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type |
1455 | | > |
1456 | | result<T, E>& operator&=( result<T, E>& r, F&& f ) |
1457 | | { |
1458 | | if( r ) |
1459 | | { |
1460 | | r = std::forward<F>( f )( std::move( r ).unsafe_value() ); |
1461 | | } |
1462 | | |
1463 | | return r; |
1464 | | } |
1465 | | |
1466 | | template<class E, class F, |
1467 | | class U = decltype( std::declval<F>()() ), |
1468 | | class En1 = typename std::enable_if<detail::is_result<U>::value>::type, |
1469 | | class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type, |
1470 | | class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type |
1471 | | > |
1472 | | result<void, E>& operator&=( result<void, E>& r, F&& f ) |
1473 | | { |
1474 | | if( r ) |
1475 | | { |
1476 | | r = std::forward<F>( f )(); |
1477 | | } |
1478 | | |
1479 | | return r; |
1480 | | } |
1481 | | |
1482 | | } // namespace system |
1483 | | } // namespace boost |
1484 | | |
1485 | | #endif // #ifndef BOOST_SYSTEM_RESULT_HPP_INCLUDED |