Coverage Report

Created: 2026-01-25 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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