Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/libcxx/include/future
Line
Count
Source (jump to first uncovered line)
1
// -*- C++ -*-
2
//===--------------------------- future -----------------------------------===//
3
//
4
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5
// See https://llvm.org/LICENSE.txt for license information.
6
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7
//
8
//===----------------------------------------------------------------------===//
9
10
#ifndef _LIBCPP_FUTURE
11
#define _LIBCPP_FUTURE
12
13
/*
14
    future synopsis
15
16
namespace std
17
{
18
19
enum class future_errc
20
{
21
    future_already_retrieved = 1,
22
    promise_already_satisfied,
23
    no_state,
24
    broken_promise
25
};
26
27
enum class launch
28
{
29
    async = 1,
30
    deferred = 2,
31
    any = async | deferred
32
};
33
34
enum class future_status
35
{
36
    ready,
37
    timeout,
38
    deferred
39
};
40
41
template <> struct is_error_code_enum<future_errc> : public true_type { };
42
error_code make_error_code(future_errc e) noexcept;
43
error_condition make_error_condition(future_errc e) noexcept;
44
45
const error_category& future_category() noexcept;
46
47
class future_error
48
    : public logic_error
49
{
50
public:
51
    future_error(error_code ec);  // exposition only
52
    explicit future_error(future_errc); // C++17
53
    const error_code& code() const noexcept;
54
    const char*       what() const noexcept;
55
};
56
57
template <class R>
58
class promise
59
{
60
public:
61
    promise();
62
    template <class Allocator>
63
        promise(allocator_arg_t, const Allocator& a);
64
    promise(promise&& rhs) noexcept;
65
    promise(const promise& rhs) = delete;
66
    ~promise();
67
68
    // assignment
69
    promise& operator=(promise&& rhs) noexcept;
70
    promise& operator=(const promise& rhs) = delete;
71
    void swap(promise& other) noexcept;
72
73
    // retrieving the result
74
    future<R> get_future();
75
76
    // setting the result
77
    void set_value(const R& r);
78
    void set_value(R&& r);
79
    void set_exception(exception_ptr p);
80
81
    // setting the result with deferred notification
82
    void set_value_at_thread_exit(const R& r);
83
    void set_value_at_thread_exit(R&& r);
84
    void set_exception_at_thread_exit(exception_ptr p);
85
};
86
87
template <class R>
88
class promise<R&>
89
{
90
public:
91
    promise();
92
    template <class Allocator>
93
        promise(allocator_arg_t, const Allocator& a);
94
    promise(promise&& rhs) noexcept;
95
    promise(const promise& rhs) = delete;
96
    ~promise();
97
98
    // assignment
99
    promise& operator=(promise&& rhs) noexcept;
100
    promise& operator=(const promise& rhs) = delete;
101
    void swap(promise& other) noexcept;
102
103
    // retrieving the result
104
    future<R&> get_future();
105
106
    // setting the result
107
    void set_value(R& r);
108
    void set_exception(exception_ptr p);
109
110
    // setting the result with deferred notification
111
    void set_value_at_thread_exit(R&);
112
    void set_exception_at_thread_exit(exception_ptr p);
113
};
114
115
template <>
116
class promise<void>
117
{
118
public:
119
    promise();
120
    template <class Allocator>
121
        promise(allocator_arg_t, const Allocator& a);
122
    promise(promise&& rhs) noexcept;
123
    promise(const promise& rhs) = delete;
124
    ~promise();
125
126
    // assignment
127
    promise& operator=(promise&& rhs) noexcept;
128
    promise& operator=(const promise& rhs) = delete;
129
    void swap(promise& other) noexcept;
130
131
    // retrieving the result
132
    future<void> get_future();
133
134
    // setting the result
135
    void set_value();
136
    void set_exception(exception_ptr p);
137
138
    // setting the result with deferred notification
139
    void set_value_at_thread_exit();
140
    void set_exception_at_thread_exit(exception_ptr p);
141
};
142
143
template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
144
145
template <class R, class Alloc>
146
    struct uses_allocator<promise<R>, Alloc> : public true_type {};
147
148
template <class R>
149
class future
150
{
151
public:
152
    future() noexcept;
153
    future(future&&) noexcept;
154
    future(const future& rhs) = delete;
155
    ~future();
156
    future& operator=(const future& rhs) = delete;
157
    future& operator=(future&&) noexcept;
158
    shared_future<R> share() noexcept;
159
160
    // retrieving the value
161
    R get();
162
163
    // functions to check state
164
    bool valid() const noexcept;
165
166
    void wait() const;
167
    template <class Rep, class Period>
168
        future_status
169
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
170
    template <class Clock, class Duration>
171
        future_status
172
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
173
};
174
175
template <class R>
176
class future<R&>
177
{
178
public:
179
    future() noexcept;
180
    future(future&&) noexcept;
181
    future(const future& rhs) = delete;
182
    ~future();
183
    future& operator=(const future& rhs) = delete;
184
    future& operator=(future&&) noexcept;
185
    shared_future<R&> share() noexcept;
186
187
    // retrieving the value
188
    R& get();
189
190
    // functions to check state
191
    bool valid() const noexcept;
192
193
    void wait() const;
194
    template <class Rep, class Period>
195
        future_status
196
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
197
    template <class Clock, class Duration>
198
        future_status
199
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
200
};
201
202
template <>
203
class future<void>
204
{
205
public:
206
    future() noexcept;
207
    future(future&&) noexcept;
208
    future(const future& rhs) = delete;
209
    ~future();
210
    future& operator=(const future& rhs) = delete;
211
    future& operator=(future&&) noexcept;
212
    shared_future<void> share() noexcept;
213
214
    // retrieving the value
215
    void get();
216
217
    // functions to check state
218
    bool valid() const noexcept;
219
220
    void wait() const;
221
    template <class Rep, class Period>
222
        future_status
223
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
224
    template <class Clock, class Duration>
225
        future_status
226
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
227
};
228
229
template <class R>
230
class shared_future
231
{
232
public:
233
    shared_future() noexcept;
234
    shared_future(const shared_future& rhs);
235
    shared_future(future<R>&&) noexcept;
236
    shared_future(shared_future&& rhs) noexcept;
237
    ~shared_future();
238
    shared_future& operator=(const shared_future& rhs);
239
    shared_future& operator=(shared_future&& rhs) noexcept;
240
241
    // retrieving the value
242
    const R& get() const;
243
244
    // functions to check state
245
    bool valid() const noexcept;
246
247
    void wait() const;
248
    template <class Rep, class Period>
249
        future_status
250
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
251
    template <class Clock, class Duration>
252
        future_status
253
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
254
};
255
256
template <class R>
257
class shared_future<R&>
258
{
259
public:
260
    shared_future() noexcept;
261
    shared_future(const shared_future& rhs);
262
    shared_future(future<R&>&&) noexcept;
263
    shared_future(shared_future&& rhs) noexcept;
264
    ~shared_future();
265
    shared_future& operator=(const shared_future& rhs);
266
    shared_future& operator=(shared_future&& rhs) noexcept;
267
268
    // retrieving the value
269
    R& get() const;
270
271
    // functions to check state
272
    bool valid() const noexcept;
273
274
    void wait() const;
275
    template <class Rep, class Period>
276
        future_status
277
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
278
    template <class Clock, class Duration>
279
        future_status
280
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
281
};
282
283
template <>
284
class shared_future<void>
285
{
286
public:
287
    shared_future() noexcept;
288
    shared_future(const shared_future& rhs);
289
    shared_future(future<void>&&) noexcept;
290
    shared_future(shared_future&& rhs) noexcept;
291
    ~shared_future();
292
    shared_future& operator=(const shared_future& rhs);
293
    shared_future& operator=(shared_future&& rhs) noexcept;
294
295
    // retrieving the value
296
    void get() const;
297
298
    // functions to check state
299
    bool valid() const noexcept;
300
301
    void wait() const;
302
    template <class Rep, class Period>
303
        future_status
304
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
305
    template <class Clock, class Duration>
306
        future_status
307
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
308
};
309
310
template <class F, class... Args>
311
  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
312
  async(F&& f, Args&&... args);
313
314
template <class F, class... Args>
315
  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
316
  async(launch policy, F&& f, Args&&... args);
317
318
template <class> class packaged_task; // undefined
319
320
template <class R, class... ArgTypes>
321
class packaged_task<R(ArgTypes...)>
322
{
323
public:
324
    typedef R result_type; // extension
325
326
    // construction and destruction
327
    packaged_task() noexcept;
328
    template <class F>
329
        explicit packaged_task(F&& f);
330
    template <class F, class Allocator>
331
        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
332
    ~packaged_task();
333
334
    // no copy
335
    packaged_task(const packaged_task&) = delete;
336
    packaged_task& operator=(const packaged_task&) = delete;
337
338
    // move support
339
    packaged_task(packaged_task&& other) noexcept;
340
    packaged_task& operator=(packaged_task&& other) noexcept;
341
    void swap(packaged_task& other) noexcept;
342
343
    bool valid() const noexcept;
344
345
    // result retrieval
346
    future<R> get_future();
347
348
    // execution
349
    void operator()(ArgTypes... );
350
    void make_ready_at_thread_exit(ArgTypes...);
351
352
    void reset();
353
};
354
355
template <class R>
356
  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
357
358
template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
359
360
}  // std
361
362
*/
363
364
#include <__config>
365
#include <system_error>
366
#include <memory>
367
#include <chrono>
368
#include <exception>
369
#include <mutex>
370
#include <thread>
371
372
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
373
#pragma GCC system_header
374
#endif
375
376
#ifdef _LIBCPP_HAS_NO_THREADS
377
#error <future> is not supported on this single threaded system
378
#else // !_LIBCPP_HAS_NO_THREADS
379
380
_LIBCPP_BEGIN_NAMESPACE_STD
381
382
//enum class future_errc
383
_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
384
{
385
    future_already_retrieved = 1,
386
    promise_already_satisfied,
387
    no_state,
388
    broken_promise
389
};
390
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
391
392
template <>
393
struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
394
395
#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
396
template <>
397
struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
398
#endif
399
400
//enum class launch
401
_LIBCPP_DECLARE_STRONG_ENUM(launch)
402
{
403
    async = 1,
404
    deferred = 2,
405
    any = async | deferred
406
};
407
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
408
409
#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
410
411
typedef underlying_type<launch>::type __launch_underlying_type;
412
413
inline _LIBCPP_INLINE_VISIBILITY
414
_LIBCPP_CONSTEXPR
415
launch
416
operator&(launch __x, launch __y)
417
0
{
418
0
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
419
0
                               static_cast<__launch_underlying_type>(__y));
420
0
}
421
422
inline _LIBCPP_INLINE_VISIBILITY
423
_LIBCPP_CONSTEXPR
424
launch
425
operator|(launch __x, launch __y)
426
0
{
427
0
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
428
0
                               static_cast<__launch_underlying_type>(__y));
429
0
}
430
431
inline _LIBCPP_INLINE_VISIBILITY
432
_LIBCPP_CONSTEXPR
433
launch
434
operator^(launch __x, launch __y)
435
0
{
436
0
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
437
0
                               static_cast<__launch_underlying_type>(__y));
438
0
}
439
440
inline _LIBCPP_INLINE_VISIBILITY
441
_LIBCPP_CONSTEXPR
442
launch
443
operator~(launch __x)
444
0
{
445
0
    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
446
0
}
447
448
inline _LIBCPP_INLINE_VISIBILITY
449
launch&
450
operator&=(launch& __x, launch __y)
451
0
{
452
0
    __x = __x & __y; return __x;
453
0
}
454
455
inline _LIBCPP_INLINE_VISIBILITY
456
launch&
457
operator|=(launch& __x, launch __y)
458
0
{
459
0
    __x = __x | __y; return __x;
460
0
}
461
462
inline _LIBCPP_INLINE_VISIBILITY
463
launch&
464
operator^=(launch& __x, launch __y)
465
0
{
466
0
    __x = __x ^ __y; return __x;
467
0
}
468
469
#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
470
471
//enum class future_status
472
_LIBCPP_DECLARE_STRONG_ENUM(future_status)
473
{
474
    ready,
475
    timeout,
476
    deferred
477
};
478
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
479
480
_LIBCPP_FUNC_VIS
481
const error_category& future_category() _NOEXCEPT;
482
483
inline _LIBCPP_INLINE_VISIBILITY
484
error_code
485
make_error_code(future_errc __e) _NOEXCEPT
486
0
{
487
0
    return error_code(static_cast<int>(__e), future_category());
488
0
}
489
490
inline _LIBCPP_INLINE_VISIBILITY
491
error_condition
492
make_error_condition(future_errc __e) _NOEXCEPT
493
0
{
494
0
    return error_condition(static_cast<int>(__e), future_category());
495
0
}
496
497
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
498
    : public logic_error
499
{
500
    error_code __ec_;
501
public:
502
    future_error(error_code __ec);
503
#if _LIBCPP_STD_VERS > 14
504
    explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
505
#endif
506
    _LIBCPP_INLINE_VISIBILITY
507
0
    const error_code& code() const _NOEXCEPT {return __ec_;}
508
509
    virtual ~future_error() _NOEXCEPT;
510
};
511
512
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
513
#ifndef _LIBCPP_NO_EXCEPTIONS
514
_LIBCPP_AVAILABILITY_FUTURE_ERROR
515
#endif
516
void __throw_future_error(future_errc _Ev)
517
0
{
518
0
#ifndef _LIBCPP_NO_EXCEPTIONS
519
0
    throw future_error(make_error_code(_Ev));
520
#else
521
    ((void)_Ev);
522
    _VSTD::abort();
523
#endif
524
}
525
526
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
527
    : public __shared_count
528
{
529
protected:
530
    exception_ptr __exception_;
531
    mutable mutex __mut_;
532
    mutable condition_variable __cv_;
533
    unsigned __state_;
534
535
    virtual void __on_zero_shared() _NOEXCEPT;
536
    void __sub_wait(unique_lock<mutex>& __lk);
537
public:
538
    enum
539
    {
540
        __constructed = 1,
541
        __future_attached = 2,
542
        ready = 4,
543
        deferred = 8
544
    };
545
546
    _LIBCPP_INLINE_VISIBILITY
547
3.32k
    __assoc_sub_state() : __state_(0) {}
548
549
    _LIBCPP_INLINE_VISIBILITY
550
    bool __has_value() const
551
42.2k
        {return (__state_ & __constructed) || 
(__exception_ != nullptr)39.0k
;}
552
553
    _LIBCPP_INLINE_VISIBILITY
554
3.32k
    void __attach_future() {
555
3.32k
        lock_guard<mutex> __lk(__mut_);
556
3.32k
        bool __has_future_attached = (__state_ & __future_attached) != 0;
557
3.32k
        if (__has_future_attached)
558
0
            __throw_future_error(future_errc::future_already_retrieved);
559
3.32k
        this->__add_shared();
560
3.32k
        __state_ |= __future_attached;
561
3.32k
    }
562
563
    _LIBCPP_INLINE_VISIBILITY
564
0
    void __set_deferred() {__state_ |= deferred;}
565
566
    void __make_ready();
567
    _LIBCPP_INLINE_VISIBILITY
568
0
    bool __is_ready() const {return (__state_ & ready) != 0;}
569
570
    void set_value();
571
    void set_value_at_thread_exit();
572
573
    void set_exception(exception_ptr __p);
574
    void set_exception_at_thread_exit(exception_ptr __p);
575
576
    void copy();
577
578
    void wait();
579
    template <class _Rep, class _Period>
580
        future_status
581
        _LIBCPP_INLINE_VISIBILITY
582
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
583
    template <class _Clock, class _Duration>
584
        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
585
        future_status
586
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
587
588
    virtual void __execute();
589
};
590
591
template <class _Clock, class _Duration>
592
future_status
593
__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
594
{
595
    unique_lock<mutex> __lk(__mut_);
596
    if (__state_ & deferred)
597
        return future_status::deferred;
598
    while (!(__state_ & ready) && _Clock::now() < __abs_time)
599
        __cv_.wait_until(__lk, __abs_time);
600
    if (__state_ & ready)
601
        return future_status::ready;
602
    return future_status::timeout;
603
}
604
605
template <class _Rep, class _Period>
606
inline
607
future_status
608
__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
609
{
610
    return wait_until(chrono::steady_clock::now() + __rel_time);
611
}
612
613
template <class _Rp>
614
class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
615
    : public __assoc_sub_state
616
{
617
    typedef __assoc_sub_state base;
618
    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
619
protected:
620
    _Up __value_;
621
622
    virtual void __on_zero_shared() _NOEXCEPT;
623
public:
624
625
    template <class _Arg>
626
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
627
        void set_value(_Arg&& __arg);
628
#else
629
        void set_value(_Arg& __arg);
630
#endif
631
632
    template <class _Arg>
633
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
634
        void set_value_at_thread_exit(_Arg&& __arg);
635
#else
636
        void set_value_at_thread_exit(_Arg& __arg);
637
#endif
638
639
    _Rp move();
640
    typename add_lvalue_reference<_Rp>::type copy();
641
};
642
643
template <class _Rp>
644
void
645
__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
646
{
647
    if (this->__state_ & base::__constructed)
648
        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
649
    delete this;
650
}
651
652
template <class _Rp>
653
template <class _Arg>
654
_LIBCPP_AVAILABILITY_FUTURE
655
void
656
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
657
__assoc_state<_Rp>::set_value(_Arg&& __arg)
658
#else
659
__assoc_state<_Rp>::set_value(_Arg& __arg)
660
#endif
661
{
662
    unique_lock<mutex> __lk(this->__mut_);
663
    if (this->__has_value())
664
        __throw_future_error(future_errc::promise_already_satisfied);
665
    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
666
    this->__state_ |= base::__constructed | base::ready;
667
    __cv_.notify_all();
668
}
669
670
template <class _Rp>
671
template <class _Arg>
672
void
673
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
674
__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
675
#else
676
__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
677
#endif
678
{
679
    unique_lock<mutex> __lk(this->__mut_);
680
    if (this->__has_value())
681
        __throw_future_error(future_errc::promise_already_satisfied);
682
    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
683
    this->__state_ |= base::__constructed;
684
    __thread_local_data()->__make_ready_at_thread_exit(this);
685
}
686
687
template <class _Rp>
688
_Rp
689
__assoc_state<_Rp>::move()
690
{
691
    unique_lock<mutex> __lk(this->__mut_);
692
    this->__sub_wait(__lk);
693
    if (this->__exception_ != nullptr)
694
        rethrow_exception(this->__exception_);
695
    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
696
}
697
698
template <class _Rp>
699
typename add_lvalue_reference<_Rp>::type
700
__assoc_state<_Rp>::copy()
701
{
702
    unique_lock<mutex> __lk(this->__mut_);
703
    this->__sub_wait(__lk);
704
    if (this->__exception_ != nullptr)
705
        rethrow_exception(this->__exception_);
706
    return *reinterpret_cast<_Rp*>(&__value_);
707
}
708
709
template <class _Rp>
710
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
711
    : public __assoc_sub_state
712
{
713
    typedef __assoc_sub_state base;
714
    typedef _Rp* _Up;
715
protected:
716
    _Up __value_;
717
718
    virtual void __on_zero_shared() _NOEXCEPT;
719
public:
720
721
    void set_value(_Rp& __arg);
722
    void set_value_at_thread_exit(_Rp& __arg);
723
724
    _Rp& copy();
725
};
726
727
template <class _Rp>
728
void
729
__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
730
{
731
    delete this;
732
}
733
734
template <class _Rp>
735
void
736
__assoc_state<_Rp&>::set_value(_Rp& __arg)
737
{
738
    unique_lock<mutex> __lk(this->__mut_);
739
    if (this->__has_value())
740
        __throw_future_error(future_errc::promise_already_satisfied);
741
    __value_ = _VSTD::addressof(__arg);
742
    this->__state_ |= base::__constructed | base::ready;
743
    __cv_.notify_all();
744
}
745
746
template <class _Rp>
747
void
748
__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
749
{
750
    unique_lock<mutex> __lk(this->__mut_);
751
    if (this->__has_value())
752
        __throw_future_error(future_errc::promise_already_satisfied);
753
    __value_ = _VSTD::addressof(__arg);
754
    this->__state_ |= base::__constructed;
755
    __thread_local_data()->__make_ready_at_thread_exit(this);
756
}
757
758
template <class _Rp>
759
_Rp&
760
__assoc_state<_Rp&>::copy()
761
{
762
    unique_lock<mutex> __lk(this->__mut_);
763
    this->__sub_wait(__lk);
764
    if (this->__exception_ != nullptr)
765
        rethrow_exception(this->__exception_);
766
    return *__value_;
767
}
768
769
template <class _Rp, class _Alloc>
770
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
771
    : public __assoc_state<_Rp>
772
{
773
    typedef __assoc_state<_Rp> base;
774
    _Alloc __alloc_;
775
776
    virtual void __on_zero_shared() _NOEXCEPT;
777
public:
778
    _LIBCPP_INLINE_VISIBILITY
779
    explicit __assoc_state_alloc(const _Alloc& __a)
780
        : __alloc_(__a) {}
781
};
782
783
template <class _Rp, class _Alloc>
784
void
785
__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
786
{
787
    if (this->__state_ & base::__constructed)
788
        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
789
    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
790
    typedef allocator_traits<_Al> _ATraits;
791
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
792
    _Al __a(__alloc_);
793
    this->~__assoc_state_alloc();
794
    __a.deallocate(_PTraits::pointer_to(*this), 1);
795
}
796
797
template <class _Rp, class _Alloc>
798
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
799
    : public __assoc_state<_Rp&>
800
{
801
    typedef __assoc_state<_Rp&> base;
802
    _Alloc __alloc_;
803
804
    virtual void __on_zero_shared() _NOEXCEPT;
805
public:
806
    _LIBCPP_INLINE_VISIBILITY
807
    explicit __assoc_state_alloc(const _Alloc& __a)
808
        : __alloc_(__a) {}
809
};
810
811
template <class _Rp, class _Alloc>
812
void
813
__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
814
{
815
    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
816
    typedef allocator_traits<_Al> _ATraits;
817
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
818
    _Al __a(__alloc_);
819
    this->~__assoc_state_alloc();
820
    __a.deallocate(_PTraits::pointer_to(*this), 1);
821
}
822
823
template <class _Alloc>
824
class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
825
    : public __assoc_sub_state
826
{
827
    typedef __assoc_sub_state base;
828
    _Alloc __alloc_;
829
830
    virtual void __on_zero_shared() _NOEXCEPT;
831
public:
832
    _LIBCPP_INLINE_VISIBILITY
833
    explicit __assoc_sub_state_alloc(const _Alloc& __a)
834
        : __alloc_(__a) {}
835
};
836
837
template <class _Alloc>
838
void
839
__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
840
{
841
    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
842
    typedef allocator_traits<_Al> _ATraits;
843
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
844
    _Al __a(__alloc_);
845
    this->~__assoc_sub_state_alloc();
846
    __a.deallocate(_PTraits::pointer_to(*this), 1);
847
}
848
849
template <class _Rp, class _Fp>
850
class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
851
    : public __assoc_state<_Rp>
852
{
853
    typedef __assoc_state<_Rp> base;
854
855
    _Fp __func_;
856
857
public:
858
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
859
    _LIBCPP_INLINE_VISIBILITY
860
    explicit __deferred_assoc_state(_Fp&& __f);
861
#endif
862
863
    virtual void __execute();
864
};
865
866
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
867
868
template <class _Rp, class _Fp>
869
inline
870
__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
871
    : __func_(_VSTD::forward<_Fp>(__f))
872
{
873
    this->__set_deferred();
874
}
875
876
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
877
878
template <class _Rp, class _Fp>
879
void
880
__deferred_assoc_state<_Rp, _Fp>::__execute()
881
{
882
#ifndef _LIBCPP_NO_EXCEPTIONS
883
    try
884
    {
885
#endif  // _LIBCPP_NO_EXCEPTIONS
886
        this->set_value(__func_());
887
#ifndef _LIBCPP_NO_EXCEPTIONS
888
    }
889
    catch (...)
890
    {
891
        this->set_exception(current_exception());
892
    }
893
#endif  // _LIBCPP_NO_EXCEPTIONS
894
}
895
896
template <class _Fp>
897
class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
898
    : public __assoc_sub_state
899
{
900
    typedef __assoc_sub_state base;
901
902
    _Fp __func_;
903
904
public:
905
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
906
    _LIBCPP_INLINE_VISIBILITY
907
    explicit __deferred_assoc_state(_Fp&& __f);
908
#endif
909
910
    virtual void __execute();
911
};
912
913
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
914
915
template <class _Fp>
916
inline
917
__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
918
    : __func_(_VSTD::forward<_Fp>(__f))
919
{
920
    this->__set_deferred();
921
}
922
923
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
924
925
template <class _Fp>
926
void
927
__deferred_assoc_state<void, _Fp>::__execute()
928
{
929
#ifndef _LIBCPP_NO_EXCEPTIONS
930
    try
931
    {
932
#endif  // _LIBCPP_NO_EXCEPTIONS
933
        __func_();
934
        this->set_value();
935
#ifndef _LIBCPP_NO_EXCEPTIONS
936
    }
937
    catch (...)
938
    {
939
        this->set_exception(current_exception());
940
    }
941
#endif  // _LIBCPP_NO_EXCEPTIONS
942
}
943
944
template <class _Rp, class _Fp>
945
class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
946
    : public __assoc_state<_Rp>
947
{
948
    typedef __assoc_state<_Rp> base;
949
950
    _Fp __func_;
951
952
    virtual void __on_zero_shared() _NOEXCEPT;
953
public:
954
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
955
    _LIBCPP_INLINE_VISIBILITY
956
    explicit __async_assoc_state(_Fp&& __f);
957
#endif
958
959
    virtual void __execute();
960
};
961
962
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
963
964
template <class _Rp, class _Fp>
965
inline
966
__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
967
    : __func_(_VSTD::forward<_Fp>(__f))
968
{
969
}
970
971
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
972
973
template <class _Rp, class _Fp>
974
void
975
__async_assoc_state<_Rp, _Fp>::__execute()
976
{
977
#ifndef _LIBCPP_NO_EXCEPTIONS
978
    try
979
    {
980
#endif  // _LIBCPP_NO_EXCEPTIONS
981
        this->set_value(__func_());
982
#ifndef _LIBCPP_NO_EXCEPTIONS
983
    }
984
    catch (...)
985
    {
986
        this->set_exception(current_exception());
987
    }
988
#endif  // _LIBCPP_NO_EXCEPTIONS
989
}
990
991
template <class _Rp, class _Fp>
992
void
993
__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
994
{
995
    this->wait();
996
    base::__on_zero_shared();
997
}
998
999
template <class _Fp>
1000
class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
1001
    : public __assoc_sub_state
1002
{
1003
    typedef __assoc_sub_state base;
1004
1005
    _Fp __func_;
1006
1007
    virtual void __on_zero_shared() _NOEXCEPT;
1008
public:
1009
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1010
    _LIBCPP_INLINE_VISIBILITY
1011
    explicit __async_assoc_state(_Fp&& __f);
1012
#endif
1013
1014
    virtual void __execute();
1015
};
1016
1017
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1018
1019
template <class _Fp>
1020
inline
1021
__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1022
    : __func_(_VSTD::forward<_Fp>(__f))
1023
{
1024
}
1025
1026
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1027
1028
template <class _Fp>
1029
void
1030
__async_assoc_state<void, _Fp>::__execute()
1031
{
1032
#ifndef _LIBCPP_NO_EXCEPTIONS
1033
    try
1034
    {
1035
#endif  // _LIBCPP_NO_EXCEPTIONS
1036
        __func_();
1037
        this->set_value();
1038
#ifndef _LIBCPP_NO_EXCEPTIONS
1039
    }
1040
    catch (...)
1041
    {
1042
        this->set_exception(current_exception());
1043
    }
1044
#endif  // _LIBCPP_NO_EXCEPTIONS
1045
}
1046
1047
template <class _Fp>
1048
void
1049
__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
1050
{
1051
    this->wait();
1052
    base::__on_zero_shared();
1053
}
1054
1055
template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1056
template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
1057
1058
// future
1059
1060
template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
1061
1062
template <class _Rp, class _Fp>
1063
_LIBCPP_INLINE_VISIBILITY future<_Rp>
1064
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1065
__make_deferred_assoc_state(_Fp&& __f);
1066
#else
1067
__make_deferred_assoc_state(_Fp __f);
1068
#endif
1069
1070
template <class _Rp, class _Fp>
1071
_LIBCPP_INLINE_VISIBILITY future<_Rp>
1072
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1073
__make_async_assoc_state(_Fp&& __f);
1074
#else
1075
__make_async_assoc_state(_Fp __f);
1076
#endif
1077
1078
template <class _Rp>
1079
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
1080
{
1081
    __assoc_state<_Rp>* __state_;
1082
1083
    explicit future(__assoc_state<_Rp>* __state);
1084
1085
    template <class> friend class promise;
1086
    template <class> friend class shared_future;
1087
1088
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1089
    template <class _R1, class _Fp>
1090
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1091
    template <class _R1, class _Fp>
1092
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1093
#else
1094
    template <class _R1, class _Fp>
1095
        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1096
    template <class _R1, class _Fp>
1097
        friend future<_R1> __make_async_assoc_state(_Fp __f);
1098
#endif
1099
1100
public:
1101
    _LIBCPP_INLINE_VISIBILITY
1102
    future() _NOEXCEPT : __state_(nullptr) {}
1103
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1104
    _LIBCPP_INLINE_VISIBILITY
1105
    future(future&& __rhs) _NOEXCEPT
1106
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1107
    future(const future&) = delete;
1108
    future& operator=(const future&) = delete;
1109
    _LIBCPP_INLINE_VISIBILITY
1110
    future& operator=(future&& __rhs) _NOEXCEPT
1111
        {
1112
            future(std::move(__rhs)).swap(*this);
1113
            return *this;
1114
        }
1115
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1116
private:
1117
    future(const future&);
1118
    future& operator=(const future&);
1119
public:
1120
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1121
    ~future();
1122
    _LIBCPP_INLINE_VISIBILITY
1123
    shared_future<_Rp> share() _NOEXCEPT;
1124
1125
    // retrieving the value
1126
    _Rp get();
1127
1128
    _LIBCPP_INLINE_VISIBILITY
1129
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1130
1131
    // functions to check state
1132
    _LIBCPP_INLINE_VISIBILITY
1133
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1134
1135
    _LIBCPP_INLINE_VISIBILITY
1136
    void wait() const {__state_->wait();}
1137
    template <class _Rep, class _Period>
1138
        _LIBCPP_INLINE_VISIBILITY
1139
        future_status
1140
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1141
            {return __state_->wait_for(__rel_time);}
1142
    template <class _Clock, class _Duration>
1143
        _LIBCPP_INLINE_VISIBILITY
1144
        future_status
1145
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1146
            {return __state_->wait_until(__abs_time);}
1147
};
1148
1149
template <class _Rp>
1150
future<_Rp>::future(__assoc_state<_Rp>* __state)
1151
    : __state_(__state)
1152
{
1153
    __state_->__attach_future();
1154
}
1155
1156
struct __release_shared_count
1157
{
1158
3.31k
    void operator()(__shared_count* p) {p->__release_shared();}
1159
};
1160
1161
template <class _Rp>
1162
future<_Rp>::~future()
1163
{
1164
    if (__state_)
1165
        __state_->__release_shared();
1166
}
1167
1168
template <class _Rp>
1169
_Rp
1170
future<_Rp>::get()
1171
{
1172
    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1173
    __assoc_state<_Rp>* __s = __state_;
1174
    __state_ = nullptr;
1175
    return __s->move();
1176
}
1177
1178
template <class _Rp>
1179
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
1180
{
1181
    __assoc_state<_Rp&>* __state_;
1182
1183
    explicit future(__assoc_state<_Rp&>* __state);
1184
1185
    template <class> friend class promise;
1186
    template <class> friend class shared_future;
1187
1188
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1189
    template <class _R1, class _Fp>
1190
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1191
    template <class _R1, class _Fp>
1192
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1193
#else
1194
    template <class _R1, class _Fp>
1195
        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1196
    template <class _R1, class _Fp>
1197
        friend future<_R1> __make_async_assoc_state(_Fp __f);
1198
#endif
1199
1200
public:
1201
    _LIBCPP_INLINE_VISIBILITY
1202
    future() _NOEXCEPT : __state_(nullptr) {}
1203
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1204
    _LIBCPP_INLINE_VISIBILITY
1205
    future(future&& __rhs) _NOEXCEPT
1206
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1207
    future(const future&) = delete;
1208
    future& operator=(const future&) = delete;
1209
    _LIBCPP_INLINE_VISIBILITY
1210
    future& operator=(future&& __rhs) _NOEXCEPT
1211
        {
1212
            future(std::move(__rhs)).swap(*this);
1213
            return *this;
1214
        }
1215
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1216
private:
1217
    future(const future&);
1218
    future& operator=(const future&);
1219
public:
1220
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1221
    ~future();
1222
    _LIBCPP_INLINE_VISIBILITY
1223
    shared_future<_Rp&> share() _NOEXCEPT;
1224
1225
    // retrieving the value
1226
    _Rp& get();
1227
1228
    _LIBCPP_INLINE_VISIBILITY
1229
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1230
1231
    // functions to check state
1232
    _LIBCPP_INLINE_VISIBILITY
1233
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1234
1235
    _LIBCPP_INLINE_VISIBILITY
1236
    void wait() const {__state_->wait();}
1237
    template <class _Rep, class _Period>
1238
        _LIBCPP_INLINE_VISIBILITY
1239
        future_status
1240
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1241
            {return __state_->wait_for(__rel_time);}
1242
    template <class _Clock, class _Duration>
1243
        _LIBCPP_INLINE_VISIBILITY
1244
        future_status
1245
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1246
            {return __state_->wait_until(__abs_time);}
1247
};
1248
1249
template <class _Rp>
1250
future<_Rp&>::future(__assoc_state<_Rp&>* __state)
1251
    : __state_(__state)
1252
{
1253
    __state_->__attach_future();
1254
}
1255
1256
template <class _Rp>
1257
future<_Rp&>::~future()
1258
{
1259
    if (__state_)
1260
        __state_->__release_shared();
1261
}
1262
1263
template <class _Rp>
1264
_Rp&
1265
future<_Rp&>::get()
1266
{
1267
    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1268
    __assoc_state<_Rp&>* __s = __state_;
1269
    __state_ = nullptr;
1270
    return __s->copy();
1271
}
1272
1273
template <>
1274
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
1275
{
1276
    __assoc_sub_state* __state_;
1277
1278
    explicit future(__assoc_sub_state* __state);
1279
1280
    template <class> friend class promise;
1281
    template <class> friend class shared_future;
1282
1283
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1284
    template <class _R1, class _Fp>
1285
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1286
    template <class _R1, class _Fp>
1287
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1288
#else
1289
    template <class _R1, class _Fp>
1290
        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1291
    template <class _R1, class _Fp>
1292
        friend future<_R1> __make_async_assoc_state(_Fp __f);
1293
#endif
1294
1295
public:
1296
    _LIBCPP_INLINE_VISIBILITY
1297
0
    future() _NOEXCEPT : __state_(nullptr) {}
1298
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1299
    _LIBCPP_INLINE_VISIBILITY
1300
    future(future&& __rhs) _NOEXCEPT
1301
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1302
    future(const future&) = delete;
1303
    future& operator=(const future&) = delete;
1304
    _LIBCPP_INLINE_VISIBILITY
1305
    future& operator=(future&& __rhs) _NOEXCEPT
1306
        {
1307
            future(std::move(__rhs)).swap(*this);
1308
            return *this;
1309
        }
1310
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1311
private:
1312
    future(const future&);
1313
    future& operator=(const future&);
1314
public:
1315
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1316
    ~future();
1317
    _LIBCPP_INLINE_VISIBILITY
1318
    shared_future<void> share() _NOEXCEPT;
1319
1320
    // retrieving the value
1321
    void get();
1322
1323
    _LIBCPP_INLINE_VISIBILITY
1324
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1325
1326
    // functions to check state
1327
    _LIBCPP_INLINE_VISIBILITY
1328
0
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1329
1330
    _LIBCPP_INLINE_VISIBILITY
1331
    void wait() const {__state_->wait();}
1332
    template <class _Rep, class _Period>
1333
        _LIBCPP_INLINE_VISIBILITY
1334
        future_status
1335
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1336
            {return __state_->wait_for(__rel_time);}
1337
    template <class _Clock, class _Duration>
1338
        _LIBCPP_INLINE_VISIBILITY
1339
        future_status
1340
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1341
            {return __state_->wait_until(__abs_time);}
1342
};
1343
1344
template <class _Rp>
1345
inline _LIBCPP_INLINE_VISIBILITY
1346
void
1347
swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1348
{
1349
    __x.swap(__y);
1350
}
1351
1352
// promise<R>
1353
1354
template <class _Callable> class packaged_task;
1355
1356
template <class _Rp>
1357
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
1358
{
1359
    __assoc_state<_Rp>* __state_;
1360
1361
    _LIBCPP_INLINE_VISIBILITY
1362
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1363
1364
    template <class> friend class packaged_task;
1365
public:
1366
    promise();
1367
    template <class _Alloc>
1368
        promise(allocator_arg_t, const _Alloc& __a);
1369
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1370
    _LIBCPP_INLINE_VISIBILITY
1371
    promise(promise&& __rhs) _NOEXCEPT
1372
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1373
    promise(const promise& __rhs) = delete;
1374
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1375
private:
1376
    promise(const promise& __rhs);
1377
public:
1378
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1379
    ~promise();
1380
1381
    // assignment
1382
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1383
    _LIBCPP_INLINE_VISIBILITY
1384
    promise& operator=(promise&& __rhs) _NOEXCEPT
1385
        {
1386
            promise(std::move(__rhs)).swap(*this);
1387
            return *this;
1388
        }
1389
    promise& operator=(const promise& __rhs) = delete;
1390
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1391
private:
1392
    promise& operator=(const promise& __rhs);
1393
public:
1394
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1395
    _LIBCPP_INLINE_VISIBILITY
1396
    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1397
1398
    // retrieving the result
1399
    future<_Rp> get_future();
1400
1401
    // setting the result
1402
    void set_value(const _Rp& __r);
1403
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1404
    void set_value(_Rp&& __r);
1405
#endif
1406
    void set_exception(exception_ptr __p);
1407
1408
    // setting the result with deferred notification
1409
    void set_value_at_thread_exit(const _Rp& __r);
1410
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1411
    void set_value_at_thread_exit(_Rp&& __r);
1412
#endif
1413
    void set_exception_at_thread_exit(exception_ptr __p);
1414
};
1415
1416
template <class _Rp>
1417
promise<_Rp>::promise()
1418
    : __state_(new __assoc_state<_Rp>)
1419
{
1420
}
1421
1422
template <class _Rp>
1423
template <class _Alloc>
1424
promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1425
{
1426
    typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1427
    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1428
    typedef __allocator_destructor<_A2> _D2;
1429
    _A2 __a(__a0);
1430
    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1431
    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1432
    __state_ = _VSTD::addressof(*__hold.release());
1433
}
1434
1435
template <class _Rp>
1436
promise<_Rp>::~promise()
1437
{
1438
    if (__state_)
1439
    {
1440
        if (!__state_->__has_value() && __state_->use_count() > 1)
1441
            __state_->set_exception(make_exception_ptr(
1442
                      future_error(make_error_code(future_errc::broken_promise))
1443
                                                      ));
1444
        __state_->__release_shared();
1445
    }
1446
}
1447
1448
template <class _Rp>
1449
future<_Rp>
1450
promise<_Rp>::get_future()
1451
{
1452
    if (__state_ == nullptr)
1453
        __throw_future_error(future_errc::no_state);
1454
    return future<_Rp>(__state_);
1455
}
1456
1457
template <class _Rp>
1458
void
1459
promise<_Rp>::set_value(const _Rp& __r)
1460
{
1461
    if (__state_ == nullptr)
1462
        __throw_future_error(future_errc::no_state);
1463
    __state_->set_value(__r);
1464
}
1465
1466
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1467
1468
template <class _Rp>
1469
void
1470
promise<_Rp>::set_value(_Rp&& __r)
1471
{
1472
    if (__state_ == nullptr)
1473
        __throw_future_error(future_errc::no_state);
1474
    __state_->set_value(_VSTD::move(__r));
1475
}
1476
1477
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1478
1479
template <class _Rp>
1480
void
1481
promise<_Rp>::set_exception(exception_ptr __p)
1482
{
1483
    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
1484
    if (__state_ == nullptr)
1485
        __throw_future_error(future_errc::no_state);
1486
    __state_->set_exception(__p);
1487
}
1488
1489
template <class _Rp>
1490
void
1491
promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1492
{
1493
    if (__state_ == nullptr)
1494
        __throw_future_error(future_errc::no_state);
1495
    __state_->set_value_at_thread_exit(__r);
1496
}
1497
1498
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1499
1500
template <class _Rp>
1501
void
1502
promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1503
{
1504
    if (__state_ == nullptr)
1505
        __throw_future_error(future_errc::no_state);
1506
    __state_->set_value_at_thread_exit(_VSTD::move(__r));
1507
}
1508
1509
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1510
1511
template <class _Rp>
1512
void
1513
promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1514
{
1515
    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
1516
    if (__state_ == nullptr)
1517
        __throw_future_error(future_errc::no_state);
1518
    __state_->set_exception_at_thread_exit(__p);
1519
}
1520
1521
// promise<R&>
1522
1523
template <class _Rp>
1524
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
1525
{
1526
    __assoc_state<_Rp&>* __state_;
1527
1528
    _LIBCPP_INLINE_VISIBILITY
1529
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1530
1531
    template <class> friend class packaged_task;
1532
1533
public:
1534
    promise();
1535
    template <class _Allocator>
1536
        promise(allocator_arg_t, const _Allocator& __a);
1537
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1538
    _LIBCPP_INLINE_VISIBILITY
1539
    promise(promise&& __rhs) _NOEXCEPT
1540
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1541
    promise(const promise& __rhs) = delete;
1542
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1543
private:
1544
    promise(const promise& __rhs);
1545
public:
1546
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1547
    ~promise();
1548
1549
    // assignment
1550
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1551
    _LIBCPP_INLINE_VISIBILITY
1552
    promise& operator=(promise&& __rhs) _NOEXCEPT
1553
        {
1554
            promise(std::move(__rhs)).swap(*this);
1555
            return *this;
1556
        }
1557
    promise& operator=(const promise& __rhs) = delete;
1558
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1559
private:
1560
    promise& operator=(const promise& __rhs);
1561
public:
1562
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1563
    _LIBCPP_INLINE_VISIBILITY
1564
    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1565
1566
    // retrieving the result
1567
    future<_Rp&> get_future();
1568
1569
    // setting the result
1570
    void set_value(_Rp& __r);
1571
    void set_exception(exception_ptr __p);
1572
1573
    // setting the result with deferred notification
1574
    void set_value_at_thread_exit(_Rp&);
1575
    void set_exception_at_thread_exit(exception_ptr __p);
1576
};
1577
1578
template <class _Rp>
1579
promise<_Rp&>::promise()
1580
    : __state_(new __assoc_state<_Rp&>)
1581
{
1582
}
1583
1584
template <class _Rp>
1585
template <class _Alloc>
1586
promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1587
{
1588
    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1589
    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1590
    typedef __allocator_destructor<_A2> _D2;
1591
    _A2 __a(__a0);
1592
    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1593
    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1594
    __state_ = _VSTD::addressof(*__hold.release());
1595
}
1596
1597
template <class _Rp>
1598
promise<_Rp&>::~promise()
1599
{
1600
    if (__state_)
1601
    {
1602
        if (!__state_->__has_value() && __state_->use_count() > 1)
1603
            __state_->set_exception(make_exception_ptr(
1604
                      future_error(make_error_code(future_errc::broken_promise))
1605
                                                      ));
1606
        __state_->__release_shared();
1607
    }
1608
}
1609
1610
template <class _Rp>
1611
future<_Rp&>
1612
promise<_Rp&>::get_future()
1613
{
1614
    if (__state_ == nullptr)
1615
        __throw_future_error(future_errc::no_state);
1616
    return future<_Rp&>(__state_);
1617
}
1618
1619
template <class _Rp>
1620
void
1621
promise<_Rp&>::set_value(_Rp& __r)
1622
{
1623
    if (__state_ == nullptr)
1624
        __throw_future_error(future_errc::no_state);
1625
    __state_->set_value(__r);
1626
}
1627
1628
template <class _Rp>
1629
void
1630
promise<_Rp&>::set_exception(exception_ptr __p)
1631
{
1632
    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
1633
    if (__state_ == nullptr)
1634
        __throw_future_error(future_errc::no_state);
1635
    __state_->set_exception(__p);
1636
}
1637
1638
template <class _Rp>
1639
void
1640
promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1641
{
1642
    if (__state_ == nullptr)
1643
        __throw_future_error(future_errc::no_state);
1644
    __state_->set_value_at_thread_exit(__r);
1645
}
1646
1647
template <class _Rp>
1648
void
1649
promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1650
{
1651
    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
1652
    if (__state_ == nullptr)
1653
        __throw_future_error(future_errc::no_state);
1654
    __state_->set_exception_at_thread_exit(__p);
1655
}
1656
1657
// promise<void>
1658
1659
template <>
1660
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
1661
{
1662
    __assoc_sub_state* __state_;
1663
1664
    _LIBCPP_INLINE_VISIBILITY
1665
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1666
1667
    template <class> friend class packaged_task;
1668
1669
public:
1670
    promise();
1671
    template <class _Allocator>
1672
        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1673
        promise(allocator_arg_t, const _Allocator& __a);
1674
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1675
    _LIBCPP_INLINE_VISIBILITY
1676
    promise(promise&& __rhs) _NOEXCEPT
1677
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1678
    promise(const promise& __rhs) = delete;
1679
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1680
private:
1681
    promise(const promise& __rhs);
1682
public:
1683
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1684
    ~promise();
1685
1686
    // assignment
1687
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1688
    _LIBCPP_INLINE_VISIBILITY
1689
    promise& operator=(promise&& __rhs) _NOEXCEPT
1690
        {
1691
            promise(std::move(__rhs)).swap(*this);
1692
            return *this;
1693
        }
1694
    promise& operator=(const promise& __rhs) = delete;
1695
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1696
private:
1697
    promise& operator=(const promise& __rhs);
1698
public:
1699
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1700
    _LIBCPP_INLINE_VISIBILITY
1701
    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1702
1703
    // retrieving the result
1704
    future<void> get_future();
1705
1706
    // setting the result
1707
    void set_value();
1708
    void set_exception(exception_ptr __p);
1709
1710
    // setting the result with deferred notification
1711
    void set_value_at_thread_exit();
1712
    void set_exception_at_thread_exit(exception_ptr __p);
1713
};
1714
1715
template <class _Alloc>
1716
promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1717
{
1718
    typedef __assoc_sub_state_alloc<_Alloc> _State;
1719
    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1720
    typedef __allocator_destructor<_A2> _D2;
1721
    _A2 __a(__a0);
1722
    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1723
    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1724
    __state_ = _VSTD::addressof(*__hold.release());
1725
}
1726
1727
template <class _Rp>
1728
inline _LIBCPP_INLINE_VISIBILITY
1729
void
1730
swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1731
{
1732
    __x.swap(__y);
1733
}
1734
1735
template <class _Rp, class _Alloc>
1736
    struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
1737
        : public true_type {};
1738
1739
#ifndef _LIBCPP_HAS_NO_VARIADICS
1740
1741
// packaged_task
1742
1743
template<class _Fp> class __packaged_task_base;
1744
1745
template<class _Rp, class ..._ArgTypes>
1746
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
1747
{
1748
    __packaged_task_base(const __packaged_task_base&);
1749
    __packaged_task_base& operator=(const __packaged_task_base&);
1750
public:
1751
    _LIBCPP_INLINE_VISIBILITY
1752
    __packaged_task_base() {}
1753
    _LIBCPP_INLINE_VISIBILITY
1754
    virtual ~__packaged_task_base() {}
1755
    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1756
    virtual void destroy() = 0;
1757
    virtual void destroy_deallocate() = 0;
1758
    virtual _Rp operator()(_ArgTypes&& ...) = 0;
1759
};
1760
1761
template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1762
1763
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1764
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1765
    : public  __packaged_task_base<_Rp(_ArgTypes...)>
1766
{
1767
    __compressed_pair<_Fp, _Alloc> __f_;
1768
public:
1769
    _LIBCPP_INLINE_VISIBILITY
1770
    explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
1771
    _LIBCPP_INLINE_VISIBILITY
1772
    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
1773
    _LIBCPP_INLINE_VISIBILITY
1774
    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1775
        : __f_(__f, __a) {}
1776
    _LIBCPP_INLINE_VISIBILITY
1777
    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1778
        : __f_(_VSTD::move(__f), __a) {}
1779
    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1780
    virtual void destroy();
1781
    virtual void destroy_deallocate();
1782
    virtual _Rp operator()(_ArgTypes&& ... __args);
1783
};
1784
1785
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1786
void
1787
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1788
                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1789
{
1790
    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1791
}
1792
1793
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1794
void
1795
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1796
{
1797
    __f_.~__compressed_pair<_Fp, _Alloc>();
1798
}
1799
1800
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1801
void
1802
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1803
{
1804
    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1805
    typedef allocator_traits<_Ap> _ATraits;
1806
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
1807
    _Ap __a(__f_.second());
1808
    __f_.~__compressed_pair<_Fp, _Alloc>();
1809
    __a.deallocate(_PTraits::pointer_to(*this), 1);
1810
}
1811
1812
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1813
_Rp
1814
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1815
{
1816
    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1817
}
1818
1819
template <class _Callable> class __packaged_task_function;
1820
1821
template<class _Rp, class ..._ArgTypes>
1822
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
1823
{
1824
    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1825
    typename aligned_storage<3*sizeof(void*)>::type __buf_;
1826
    __base* __f_;
1827
1828
public:
1829
    typedef _Rp result_type;
1830
1831
    // construct/copy/destroy:
1832
    _LIBCPP_INLINE_VISIBILITY
1833
    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1834
    template<class _Fp>
1835
      __packaged_task_function(_Fp&& __f);
1836
    template<class _Fp, class _Alloc>
1837
      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1838
1839
    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1840
    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1841
1842
    __packaged_task_function(const __packaged_task_function&) =  delete;
1843
    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
1844
1845
    ~__packaged_task_function();
1846
1847
    void swap(__packaged_task_function&) _NOEXCEPT;
1848
1849
    _LIBCPP_INLINE_VISIBILITY
1850
    _Rp operator()(_ArgTypes...) const;
1851
};
1852
1853
template<class _Rp, class ..._ArgTypes>
1854
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1855
{
1856
    if (__f.__f_ == nullptr)
1857
        __f_ = nullptr;
1858
    else if (__f.__f_ == (__base*)&__f.__buf_)
1859
    {
1860
        __f_ = (__base*)&__buf_;
1861
        __f.__f_->__move_to(__f_);
1862
    }
1863
    else
1864
    {
1865
        __f_ = __f.__f_;
1866
        __f.__f_ = nullptr;
1867
    }
1868
}
1869
1870
template<class _Rp, class ..._ArgTypes>
1871
template <class _Fp>
1872
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1873
    : __f_(nullptr)
1874
{
1875
    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1876
    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1877
    if (sizeof(_FF) <= sizeof(__buf_))
1878
    {
1879
        __f_ = (__base*)&__buf_;
1880
        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1881
    }
1882
    else
1883
    {
1884
        typedef allocator<_FF> _Ap;
1885
        _Ap __a;
1886
        typedef __allocator_destructor<_Ap> _Dp;
1887
        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1888
        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1889
        __f_ = __hold.release();
1890
    }
1891
}
1892
1893
template<class _Rp, class ..._ArgTypes>
1894
template <class _Fp, class _Alloc>
1895
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1896
                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1897
    : __f_(nullptr)
1898
{
1899
    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1900
    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1901
    if (sizeof(_FF) <= sizeof(__buf_))
1902
    {
1903
        __f_ = (__base*)&__buf_;
1904
        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1905
    }
1906
    else
1907
    {
1908
        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
1909
        _Ap __a(__a0);
1910
        typedef __allocator_destructor<_Ap> _Dp;
1911
        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1912
        ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1913
            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1914
        __f_ = _VSTD::addressof(*__hold.release());
1915
    }
1916
}
1917
1918
template<class _Rp, class ..._ArgTypes>
1919
__packaged_task_function<_Rp(_ArgTypes...)>&
1920
__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1921
{
1922
    if (__f_ == (__base*)&__buf_)
1923
        __f_->destroy();
1924
    else if (__f_)
1925
        __f_->destroy_deallocate();
1926
    __f_ = nullptr;
1927
    if (__f.__f_ == nullptr)
1928
        __f_ = nullptr;
1929
    else if (__f.__f_ == (__base*)&__f.__buf_)
1930
    {
1931
        __f_ = (__base*)&__buf_;
1932
        __f.__f_->__move_to(__f_);
1933
    }
1934
    else
1935
    {
1936
        __f_ = __f.__f_;
1937
        __f.__f_ = nullptr;
1938
    }
1939
    return *this;
1940
}
1941
1942
template<class _Rp, class ..._ArgTypes>
1943
__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1944
{
1945
    if (__f_ == (__base*)&__buf_)
1946
        __f_->destroy();
1947
    else if (__f_)
1948
        __f_->destroy_deallocate();
1949
}
1950
1951
template<class _Rp, class ..._ArgTypes>
1952
void
1953
__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1954
{
1955
    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1956
    {
1957
        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1958
        __base* __t = (__base*)&__tempbuf;
1959
        __f_->__move_to(__t);
1960
        __f_->destroy();
1961
        __f_ = nullptr;
1962
        __f.__f_->__move_to((__base*)&__buf_);
1963
        __f.__f_->destroy();
1964
        __f.__f_ = nullptr;
1965
        __f_ = (__base*)&__buf_;
1966
        __t->__move_to((__base*)&__f.__buf_);
1967
        __t->destroy();
1968
        __f.__f_ = (__base*)&__f.__buf_;
1969
    }
1970
    else if (__f_ == (__base*)&__buf_)
1971
    {
1972
        __f_->__move_to((__base*)&__f.__buf_);
1973
        __f_->destroy();
1974
        __f_ = __f.__f_;
1975
        __f.__f_ = (__base*)&__f.__buf_;
1976
    }
1977
    else if (__f.__f_ == (__base*)&__f.__buf_)
1978
    {
1979
        __f.__f_->__move_to((__base*)&__buf_);
1980
        __f.__f_->destroy();
1981
        __f.__f_ = __f_;
1982
        __f_ = (__base*)&__buf_;
1983
    }
1984
    else
1985
        _VSTD::swap(__f_, __f.__f_);
1986
}
1987
1988
template<class _Rp, class ..._ArgTypes>
1989
inline
1990
_Rp
1991
__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1992
{
1993
    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
1994
}
1995
1996
template<class _Rp, class ..._ArgTypes>
1997
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
1998
{
1999
public:
2000
    typedef _Rp result_type; // extension
2001
2002
private:
2003
    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2004
    promise<result_type>                                __p_;
2005
2006
public:
2007
    // construction and destruction
2008
    _LIBCPP_INLINE_VISIBILITY
2009
    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2010
    template <class _Fp,
2011
              class = typename enable_if
2012
              <
2013
                  !is_same<
2014
                      typename __uncvref<_Fp>::type,
2015
                      packaged_task
2016
                      >::value
2017
                  >::type
2018
             >
2019
        _LIBCPP_INLINE_VISIBILITY
2020
        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2021
    template <class _Fp, class _Allocator,
2022
              class = typename enable_if
2023
              <
2024
                  !is_same<
2025
                      typename __uncvref<_Fp>::type,
2026
                      packaged_task
2027
                      >::value
2028
                  >::type
2029
              >
2030
        _LIBCPP_INLINE_VISIBILITY
2031
        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2032
             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2033
               __p_(allocator_arg, __a) {}
2034
    // ~packaged_task() = default;
2035
2036
    // no copy
2037
    packaged_task(const packaged_task&) = delete;
2038
    packaged_task& operator=(const packaged_task&) = delete;
2039
2040
    // move support
2041
    _LIBCPP_INLINE_VISIBILITY
2042
    packaged_task(packaged_task&& __other) _NOEXCEPT
2043
        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2044
    _LIBCPP_INLINE_VISIBILITY
2045
    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2046
    {
2047
        __f_ = _VSTD::move(__other.__f_);
2048
        __p_ = _VSTD::move(__other.__p_);
2049
        return *this;
2050
    }
2051
    _LIBCPP_INLINE_VISIBILITY
2052
    void swap(packaged_task& __other) _NOEXCEPT
2053
    {
2054
        __f_.swap(__other.__f_);
2055
        __p_.swap(__other.__p_);
2056
    }
2057
2058
    _LIBCPP_INLINE_VISIBILITY
2059
    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2060
2061
    // result retrieval
2062
    _LIBCPP_INLINE_VISIBILITY
2063
    future<result_type> get_future() {return __p_.get_future();}
2064
2065
    // execution
2066
    void operator()(_ArgTypes... __args);
2067
    void make_ready_at_thread_exit(_ArgTypes... __args);
2068
2069
    void reset();
2070
};
2071
2072
template<class _Rp, class ..._ArgTypes>
2073
void
2074
packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
2075
{
2076
    if (__p_.__state_ == nullptr)
2077
        __throw_future_error(future_errc::no_state);
2078
    if (__p_.__state_->__has_value())
2079
        __throw_future_error(future_errc::promise_already_satisfied);
2080
#ifndef _LIBCPP_NO_EXCEPTIONS
2081
    try
2082
    {
2083
#endif  // _LIBCPP_NO_EXCEPTIONS
2084
        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2085
#ifndef _LIBCPP_NO_EXCEPTIONS
2086
    }
2087
    catch (...)
2088
    {
2089
        __p_.set_exception(current_exception());
2090
    }
2091
#endif  // _LIBCPP_NO_EXCEPTIONS
2092
}
2093
2094
template<class _Rp, class ..._ArgTypes>
2095
void
2096
packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2097
{
2098
    if (__p_.__state_ == nullptr)
2099
        __throw_future_error(future_errc::no_state);
2100
    if (__p_.__state_->__has_value())
2101
        __throw_future_error(future_errc::promise_already_satisfied);
2102
#ifndef _LIBCPP_NO_EXCEPTIONS
2103
    try
2104
    {
2105
#endif  // _LIBCPP_NO_EXCEPTIONS
2106
        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2107
#ifndef _LIBCPP_NO_EXCEPTIONS
2108
    }
2109
    catch (...)
2110
    {
2111
        __p_.set_exception_at_thread_exit(current_exception());
2112
    }
2113
#endif  // _LIBCPP_NO_EXCEPTIONS
2114
}
2115
2116
template<class _Rp, class ..._ArgTypes>
2117
void
2118
packaged_task<_Rp(_ArgTypes...)>::reset()
2119
{
2120
    if (!valid())
2121
        __throw_future_error(future_errc::no_state);
2122
    __p_ = promise<result_type>();
2123
}
2124
2125
template<class ..._ArgTypes>
2126
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
2127
{
2128
public:
2129
    typedef void result_type; // extension
2130
2131
private:
2132
    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2133
    promise<result_type>                                __p_;
2134
2135
public:
2136
    // construction and destruction
2137
    _LIBCPP_INLINE_VISIBILITY
2138
    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2139
    template <class _Fp,
2140
              class = typename enable_if
2141
              <
2142
                  !is_same<
2143
                      typename __uncvref<_Fp>::type,
2144
                      packaged_task
2145
                      >::value
2146
                  >::type
2147
              >
2148
        _LIBCPP_INLINE_VISIBILITY
2149
        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2150
    template <class _Fp, class _Allocator,
2151
              class = typename enable_if
2152
              <
2153
                  !is_same<
2154
                      typename __uncvref<_Fp>::type,
2155
                      packaged_task
2156
                      >::value
2157
                  >::type
2158
              >
2159
        _LIBCPP_INLINE_VISIBILITY
2160
        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2161
             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2162
               __p_(allocator_arg, __a) {}
2163
    // ~packaged_task() = default;
2164
2165
    // no copy
2166
    packaged_task(const packaged_task&) = delete;
2167
    packaged_task& operator=(const packaged_task&) = delete;
2168
2169
    // move support
2170
    _LIBCPP_INLINE_VISIBILITY
2171
    packaged_task(packaged_task&& __other) _NOEXCEPT
2172
        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2173
    _LIBCPP_INLINE_VISIBILITY
2174
    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2175
    {
2176
        __f_ = _VSTD::move(__other.__f_);
2177
        __p_ = _VSTD::move(__other.__p_);
2178
        return *this;
2179
    }
2180
    _LIBCPP_INLINE_VISIBILITY
2181
    void swap(packaged_task& __other) _NOEXCEPT
2182
    {
2183
        __f_.swap(__other.__f_);
2184
        __p_.swap(__other.__p_);
2185
    }
2186
2187
    _LIBCPP_INLINE_VISIBILITY
2188
    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2189
2190
    // result retrieval
2191
    _LIBCPP_INLINE_VISIBILITY
2192
    future<result_type> get_future() {return __p_.get_future();}
2193
2194
    // execution
2195
    void operator()(_ArgTypes... __args);
2196
    void make_ready_at_thread_exit(_ArgTypes... __args);
2197
2198
    void reset();
2199
};
2200
2201
template<class ..._ArgTypes>
2202
void
2203
packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2204
{
2205
    if (__p_.__state_ == nullptr)
2206
        __throw_future_error(future_errc::no_state);
2207
    if (__p_.__state_->__has_value())
2208
        __throw_future_error(future_errc::promise_already_satisfied);
2209
#ifndef _LIBCPP_NO_EXCEPTIONS
2210
    try
2211
    {
2212
#endif  // _LIBCPP_NO_EXCEPTIONS
2213
        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2214
        __p_.set_value();
2215
#ifndef _LIBCPP_NO_EXCEPTIONS
2216
    }
2217
    catch (...)
2218
    {
2219
        __p_.set_exception(current_exception());
2220
    }
2221
#endif  // _LIBCPP_NO_EXCEPTIONS
2222
}
2223
2224
template<class ..._ArgTypes>
2225
void
2226
packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2227
{
2228
    if (__p_.__state_ == nullptr)
2229
        __throw_future_error(future_errc::no_state);
2230
    if (__p_.__state_->__has_value())
2231
        __throw_future_error(future_errc::promise_already_satisfied);
2232
#ifndef _LIBCPP_NO_EXCEPTIONS
2233
    try
2234
    {
2235
#endif  // _LIBCPP_NO_EXCEPTIONS
2236
        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2237
        __p_.set_value_at_thread_exit();
2238
#ifndef _LIBCPP_NO_EXCEPTIONS
2239
    }
2240
    catch (...)
2241
    {
2242
        __p_.set_exception_at_thread_exit(current_exception());
2243
    }
2244
#endif  // _LIBCPP_NO_EXCEPTIONS
2245
}
2246
2247
template<class ..._ArgTypes>
2248
void
2249
packaged_task<void(_ArgTypes...)>::reset()
2250
{
2251
    if (!valid())
2252
        __throw_future_error(future_errc::no_state);
2253
    __p_ = promise<result_type>();
2254
}
2255
2256
template <class _Callable>
2257
inline _LIBCPP_INLINE_VISIBILITY
2258
void
2259
swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2260
{
2261
    __x.swap(__y);
2262
}
2263
2264
template <class _Callable, class _Alloc>
2265
struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2266
    : public true_type {};
2267
2268
template <class _Rp, class _Fp>
2269
_LIBCPP_INLINE_VISIBILITY future<_Rp>
2270
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2271
__make_deferred_assoc_state(_Fp&& __f)
2272
#else
2273
__make_deferred_assoc_state(_Fp __f)
2274
#endif
2275
{
2276
    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2277
        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2278
    return future<_Rp>(__h.get());
2279
}
2280
2281
template <class _Rp, class _Fp>
2282
_LIBCPP_INLINE_VISIBILITY future<_Rp>
2283
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2284
__make_async_assoc_state(_Fp&& __f)
2285
#else
2286
__make_async_assoc_state(_Fp __f)
2287
#endif
2288
{
2289
    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2290
        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2291
    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2292
    return future<_Rp>(__h.get());
2293
}
2294
2295
template <class _Fp, class... _Args>
2296
class _LIBCPP_HIDDEN __async_func
2297
{
2298
    tuple<_Fp, _Args...> __f_;
2299
2300
public:
2301
    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2302
2303
    _LIBCPP_INLINE_VISIBILITY
2304
    explicit __async_func(_Fp&& __f, _Args&&... __args)
2305
        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2306
2307
    _LIBCPP_INLINE_VISIBILITY
2308
    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2309
2310
    _Rp operator()()
2311
    {
2312
        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2313
        return __execute(_Index());
2314
    }
2315
private:
2316
    template <size_t ..._Indices>
2317
    _Rp
2318
    __execute(__tuple_indices<_Indices...>)
2319
    {
2320
        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2321
    }
2322
};
2323
2324
inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
2325
{ return (int(__policy) & int(__value)) != 0; }
2326
2327
template <class _Fp, class... _Args>
2328
_LIBCPP_NODISCARD_AFTER_CXX17
2329
future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2330
async(launch __policy, _Fp&& __f, _Args&&... __args)
2331
{
2332
    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2333
    typedef typename _BF::_Rp _Rp;
2334
2335
#ifndef _LIBCPP_NO_EXCEPTIONS
2336
    try
2337
    {
2338
#endif
2339
        if (__does_policy_contain(__policy, launch::async))
2340
        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2341
                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
2342
#ifndef _LIBCPP_NO_EXCEPTIONS
2343
    }
2344
    catch ( ... ) { if (__policy == launch::async) throw ; }
2345
#endif
2346
2347
    if (__does_policy_contain(__policy, launch::deferred))
2348
        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2349
                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
2350
    return future<_Rp>{};
2351
}
2352
2353
template <class _Fp, class... _Args>
2354
_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
2355
future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2356
async(_Fp&& __f, _Args&&... __args)
2357
{
2358
    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2359
                                    _VSTD::forward<_Args>(__args)...);
2360
}
2361
2362
#endif  // _LIBCPP_HAS_NO_VARIADICS
2363
2364
// shared_future
2365
2366
template <class _Rp>
2367
class _LIBCPP_TEMPLATE_VIS shared_future
2368
{
2369
    __assoc_state<_Rp>* __state_;
2370
2371
public:
2372
    _LIBCPP_INLINE_VISIBILITY
2373
    shared_future() _NOEXCEPT : __state_(nullptr) {}
2374
    _LIBCPP_INLINE_VISIBILITY
2375
    shared_future(const shared_future& __rhs)  _NOEXCEPT : __state_(__rhs.__state_)
2376
        {if (__state_) __state_->__add_shared();}
2377
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2378
    _LIBCPP_INLINE_VISIBILITY
2379
    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2380
        {__f.__state_ = nullptr;}
2381
    _LIBCPP_INLINE_VISIBILITY
2382
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2383
        {__rhs.__state_ = nullptr;}
2384
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2385
    ~shared_future();
2386
    shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
2387
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2388
    _LIBCPP_INLINE_VISIBILITY
2389
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2390
        {
2391
            shared_future(std::move(__rhs)).swap(*this);
2392
            return *this;
2393
        }
2394
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2395
2396
    // retrieving the value
2397
    _LIBCPP_INLINE_VISIBILITY
2398
    const _Rp& get() const {return __state_->copy();}
2399
2400
    _LIBCPP_INLINE_VISIBILITY
2401
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2402
2403
    // functions to check state
2404
    _LIBCPP_INLINE_VISIBILITY
2405
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2406
2407
    _LIBCPP_INLINE_VISIBILITY
2408
    void wait() const {__state_->wait();}
2409
    template <class _Rep, class _Period>
2410
        _LIBCPP_INLINE_VISIBILITY
2411
        future_status
2412
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2413
            {return __state_->wait_for(__rel_time);}
2414
    template <class _Clock, class _Duration>
2415
        _LIBCPP_INLINE_VISIBILITY
2416
        future_status
2417
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2418
            {return __state_->wait_until(__abs_time);}
2419
};
2420
2421
template <class _Rp>
2422
shared_future<_Rp>::~shared_future()
2423
{
2424
    if (__state_)
2425
        __state_->__release_shared();
2426
}
2427
2428
template <class _Rp>
2429
shared_future<_Rp>&
2430
shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
2431
{
2432
    if (__rhs.__state_)
2433
        __rhs.__state_->__add_shared();
2434
    if (__state_)
2435
        __state_->__release_shared();
2436
    __state_ = __rhs.__state_;
2437
    return *this;
2438
}
2439
2440
template <class _Rp>
2441
class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
2442
{
2443
    __assoc_state<_Rp&>* __state_;
2444
2445
public:
2446
    _LIBCPP_INLINE_VISIBILITY
2447
    shared_future() _NOEXCEPT : __state_(nullptr) {}
2448
    _LIBCPP_INLINE_VISIBILITY
2449
    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2450
        {if (__state_) __state_->__add_shared();}
2451
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2452
    _LIBCPP_INLINE_VISIBILITY
2453
    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2454
        {__f.__state_ = nullptr;}
2455
    _LIBCPP_INLINE_VISIBILITY
2456
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2457
        {__rhs.__state_ = nullptr;}
2458
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2459
    ~shared_future();
2460
    shared_future& operator=(const shared_future& __rhs);
2461
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2462
    _LIBCPP_INLINE_VISIBILITY
2463
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2464
        {
2465
            shared_future(std::move(__rhs)).swap(*this);
2466
            return *this;
2467
        }
2468
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2469
2470
    // retrieving the value
2471
    _LIBCPP_INLINE_VISIBILITY
2472
    _Rp& get() const {return __state_->copy();}
2473
2474
    _LIBCPP_INLINE_VISIBILITY
2475
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2476
2477
    // functions to check state
2478
    _LIBCPP_INLINE_VISIBILITY
2479
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2480
2481
    _LIBCPP_INLINE_VISIBILITY
2482
    void wait() const {__state_->wait();}
2483
    template <class _Rep, class _Period>
2484
        _LIBCPP_INLINE_VISIBILITY
2485
        future_status
2486
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2487
            {return __state_->wait_for(__rel_time);}
2488
    template <class _Clock, class _Duration>
2489
        _LIBCPP_INLINE_VISIBILITY
2490
        future_status
2491
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2492
            {return __state_->wait_until(__abs_time);}
2493
};
2494
2495
template <class _Rp>
2496
shared_future<_Rp&>::~shared_future()
2497
{
2498
    if (__state_)
2499
        __state_->__release_shared();
2500
}
2501
2502
template <class _Rp>
2503
shared_future<_Rp&>&
2504
shared_future<_Rp&>::operator=(const shared_future& __rhs)
2505
{
2506
    if (__rhs.__state_)
2507
        __rhs.__state_->__add_shared();
2508
    if (__state_)
2509
        __state_->__release_shared();
2510
    __state_ = __rhs.__state_;
2511
    return *this;
2512
}
2513
2514
template <>
2515
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
2516
{
2517
    __assoc_sub_state* __state_;
2518
2519
public:
2520
    _LIBCPP_INLINE_VISIBILITY
2521
0
    shared_future() _NOEXCEPT : __state_(nullptr) {}
2522
    _LIBCPP_INLINE_VISIBILITY
2523
    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2524
0
        {if (__state_) __state_->__add_shared();}
2525
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2526
    _LIBCPP_INLINE_VISIBILITY
2527
    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2528
        {__f.__state_ = nullptr;}
2529
    _LIBCPP_INLINE_VISIBILITY
2530
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2531
0
        {__rhs.__state_ = nullptr;}
2532
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2533
    ~shared_future();
2534
    shared_future& operator=(const shared_future& __rhs);
2535
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2536
    _LIBCPP_INLINE_VISIBILITY
2537
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2538
0
        {
2539
0
            shared_future(std::move(__rhs)).swap(*this);
2540
0
            return *this;
2541
0
        }
2542
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2543
2544
    // retrieving the value
2545
    _LIBCPP_INLINE_VISIBILITY
2546
    void get() const {__state_->copy();}
2547
2548
    _LIBCPP_INLINE_VISIBILITY
2549
0
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2550
2551
    // functions to check state
2552
    _LIBCPP_INLINE_VISIBILITY
2553
0
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2554
2555
    _LIBCPP_INLINE_VISIBILITY
2556
0
    void wait() const {__state_->wait();}
2557
    template <class _Rep, class _Period>
2558
        _LIBCPP_INLINE_VISIBILITY
2559
        future_status
2560
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2561
            {return __state_->wait_for(__rel_time);}
2562
    template <class _Clock, class _Duration>
2563
        _LIBCPP_INLINE_VISIBILITY
2564
        future_status
2565
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2566
            {return __state_->wait_until(__abs_time);}
2567
};
2568
2569
template <class _Rp>
2570
inline _LIBCPP_INLINE_VISIBILITY
2571
void
2572
swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2573
{
2574
    __x.swap(__y);
2575
}
2576
2577
template <class _Rp>
2578
inline
2579
shared_future<_Rp>
2580
future<_Rp>::share() _NOEXCEPT
2581
{
2582
    return shared_future<_Rp>(_VSTD::move(*this));
2583
}
2584
2585
template <class _Rp>
2586
inline
2587
shared_future<_Rp&>
2588
future<_Rp&>::share() _NOEXCEPT
2589
{
2590
    return shared_future<_Rp&>(_VSTD::move(*this));
2591
}
2592
2593
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2594
2595
inline
2596
shared_future<void>
2597
future<void>::share() _NOEXCEPT
2598
{
2599
    return shared_future<void>(_VSTD::move(*this));
2600
}
2601
2602
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2603
2604
_LIBCPP_END_NAMESPACE_STD
2605
2606
#endif // !_LIBCPP_HAS_NO_THREADS
2607
2608
#endif  // _LIBCPP_FUTURE