Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / c++ / future @ 13

History | View | Annotate | Download (70.3 KB)

1
// -*- C++ -*-
2
//===--------------------------- future -----------------------------------===//
3
//
4
//                     The LLVM Compiler Infrastructure
5
//
6
// This file is dual licensed under the MIT and the University of Illinois Open
7
// Source Licenses. See LICENSE.TXT for details.
8
//
9
//===----------------------------------------------------------------------===//
10

    
11
#ifndef _LIBCPP_FUTURE
12
#define _LIBCPP_FUTURE
13

    
14
/*
15
    future synopsis
16

    
17
namespace std
18
{
19

    
20
enum class future_errc
21
{
22
    future_already_retrieved = 1,
23
    promise_already_satisfied,
24
    no_state,
25
    broken_promise
26
};
27

    
28
enum class launch
29
{
30
    async = 1,
31
    deferred = 2,
32
    any = async | deferred
33
};
34

    
35
enum class future_status
36
{
37
    ready,
38
    timeout,
39
    deferred
40
};
41

    
42
template <> struct is_error_code_enum<future_errc> : public true_type { };
43
error_code make_error_code(future_errc e) noexcept;
44
error_condition make_error_condition(future_errc e) noexcept;
45

    
46
const error_category& future_category() noexcept;
47

    
48
class future_error
49
    : public logic_error
50
{
51
public:
52
    future_error(error_code ec);  // exposition only
53

    
54
    const error_code& code() const noexcept;
55
    const char*       what() const noexcept;
56
};
57

    
58
template <class R>
59
class promise
60
{
61
public:
62
    promise();
63
    template <class Allocator>
64
        promise(allocator_arg_t, const Allocator& a);
65
    promise(promise&& rhs) noexcept;
66
    promise(const promise& rhs) = delete;
67
    ~promise();
68

    
69
    // assignment
70
    promise& operator=(promise&& rhs) noexcept;
71
    promise& operator=(const promise& rhs) = delete;
72
    void swap(promise& other) noexcept;
73

    
74
    // retrieving the result
75
    future<R> get_future();
76

    
77
    // setting the result
78
    void set_value(const R& r);
79
    void set_value(R&& r);
80
    void set_exception(exception_ptr p);
81

    
82
    // setting the result with deferred notification
83
    void set_value_at_thread_exit(const R& r);
84
    void set_value_at_thread_exit(R&& r);
85
    void set_exception_at_thread_exit(exception_ptr p);
86
};
87

    
88
template <class R>
89
class promise<R&>
90
{
91
public:
92
    promise();
93
    template <class Allocator>
94
        promise(allocator_arg_t, const Allocator& a);
95
    promise(promise&& rhs) noexcept;
96
    promise(const promise& rhs) = delete;
97
    ~promise();
98

    
99
    // assignment
100
    promise& operator=(promise&& rhs) noexcept;
101
    promise& operator=(const promise& rhs) = delete;
102
    void swap(promise& other) noexcept;
103

    
104
    // retrieving the result
105
    future<R&> get_future();
106

    
107
    // setting the result
108
    void set_value(R& r);
109
    void set_exception(exception_ptr p);
110

    
111
    // setting the result with deferred notification
112
    void set_value_at_thread_exit(R&);
113
    void set_exception_at_thread_exit(exception_ptr p);
114
};
115

    
116
template <>
117
class promise<void>
118
{
119
public:
120
    promise();
121
    template <class Allocator>
122
        promise(allocator_arg_t, const Allocator& a);
123
    promise(promise&& rhs) noexcept;
124
    promise(const promise& rhs) = delete;
125
    ~promise();
126

    
127
    // assignment
128
    promise& operator=(promise&& rhs) noexcept;
129
    promise& operator=(const promise& rhs) = delete;
130
    void swap(promise& other) noexcept;
131

    
132
    // retrieving the result
133
    future<void> get_future();
134

    
135
    // setting the result
136
    void set_value();
137
    void set_exception(exception_ptr p);
138

    
139
    // setting the result with deferred notification
140
    void set_value_at_thread_exit();
141
    void set_exception_at_thread_exit(exception_ptr p);
142
};
143

    
144
template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
145

    
146
template <class R, class Alloc>
147
    struct uses_allocator<promise<R>, Alloc> : public true_type {};
148

    
149
template <class R>
150
class future
151
{
152
public:
153
    future() noexcept;
154
    future(future&&) noexcept;
155
    future(const future& rhs) = delete;
156
    ~future();
157
    future& operator=(const future& rhs) = delete;
158
    future& operator=(future&&) noexcept;
159
    shared_future<R> share();
160

    
161
    // retrieving the value
162
    R get();
163

    
164
    // functions to check state
165
    bool valid() const noexcept;
166

    
167
    void wait() const;
168
    template <class Rep, class Period>
169
        future_status
170
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171
    template <class Clock, class Duration>
172
        future_status
173
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174
};
175

    
176
template <class R>
177
class future<R&>
178
{
179
public:
180
    future() noexcept;
181
    future(future&&) noexcept;
182
    future(const future& rhs) = delete;
183
    ~future();
184
    future& operator=(const future& rhs) = delete;
185
    future& operator=(future&&) noexcept;
186
    shared_future<R&> share();
187

    
188
    // retrieving the value
189
    R& get();
190

    
191
    // functions to check state
192
    bool valid() const noexcept;
193

    
194
    void wait() const;
195
    template <class Rep, class Period>
196
        future_status
197
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198
    template <class Clock, class Duration>
199
        future_status
200
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201
};
202

    
203
template <>
204
class future<void>
205
{
206
public:
207
    future() noexcept;
208
    future(future&&) noexcept;
209
    future(const future& rhs) = delete;
210
    ~future();
211
    future& operator=(const future& rhs) = delete;
212
    future& operator=(future&&) noexcept;
213
    shared_future<void> share();
214

    
215
    // retrieving the value
216
    void get();
217

    
218
    // functions to check state
219
    bool valid() const noexcept;
220

    
221
    void wait() const;
222
    template <class Rep, class Period>
223
        future_status
224
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225
    template <class Clock, class Duration>
226
        future_status
227
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228
};
229

    
230
template <class R>
231
class shared_future
232
{
233
public:
234
    shared_future() noexcept;
235
    shared_future(const shared_future& rhs);
236
    shared_future(future<R>&&) noexcept;
237
    shared_future(shared_future&& rhs) noexcept;
238
    ~shared_future();
239
    shared_future& operator=(const shared_future& rhs);
240
    shared_future& operator=(shared_future&& rhs) noexcept;
241

    
242
    // retrieving the value
243
    const R& get() const;
244

    
245
    // functions to check state
246
    bool valid() const noexcept;
247

    
248
    void wait() const;
249
    template <class Rep, class Period>
250
        future_status
251
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252
    template <class Clock, class Duration>
253
        future_status
254
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255
};
256

    
257
template <class R>
258
class shared_future<R&>
259
{
260
public:
261
    shared_future() noexcept;
262
    shared_future(const shared_future& rhs);
263
    shared_future(future<R&>&&) noexcept;
264
    shared_future(shared_future&& rhs) noexcept;
265
    ~shared_future();
266
    shared_future& operator=(const shared_future& rhs);
267
    shared_future& operator=(shared_future&& rhs) noexcept;
268

    
269
    // retrieving the value
270
    R& get() const;
271

    
272
    // functions to check state
273
    bool valid() const noexcept;
274

    
275
    void wait() const;
276
    template <class Rep, class Period>
277
        future_status
278
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279
    template <class Clock, class Duration>
280
        future_status
281
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282
};
283

    
284
template <>
285
class shared_future<void>
286
{
287
public:
288
    shared_future() noexcept;
289
    shared_future(const shared_future& rhs);
290
    shared_future(future<void>&&) noexcept;
291
    shared_future(shared_future&& rhs) noexcept;
292
    ~shared_future();
293
    shared_future& operator=(const shared_future& rhs);
294
    shared_future& operator=(shared_future&& rhs) noexcept;
295

    
296
    // retrieving the value
297
    void get() const;
298

    
299
    // functions to check state
300
    bool valid() const noexcept;
301

    
302
    void wait() const;
303
    template <class Rep, class Period>
304
        future_status
305
        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306
    template <class Clock, class Duration>
307
        future_status
308
        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309
};
310

    
311
template <class F, class... Args>
312
  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
313
  async(F&& f, Args&&... args);
314

    
315
template <class F, class... Args>
316
  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
317
  async(launch policy, F&& f, Args&&... args);
318

    
319
template <class> class packaged_task; // undefined
320

    
321
template <class R, class... ArgTypes>
322
class packaged_task<R(ArgTypes...)>
323
{
324
public:
325
    typedef R result_type;
326

    
327
    // construction and destruction
328
    packaged_task() noexcept;
329
    template <class F>
330
        explicit packaged_task(F&& f);
331
    template <class F, class Allocator>
332
        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333
    ~packaged_task();
334

    
335
    // no copy
336
    packaged_task(const packaged_task&) = delete;
337
    packaged_task& operator=(const packaged_task&) = delete;
338

    
339
    // move support
340
    packaged_task(packaged_task&& other) noexcept;
341
    packaged_task& operator=(packaged_task&& other) noexcept;
342
    void swap(packaged_task& other) noexcept;
343

    
344
    bool valid() const noexcept;
345

    
346
    // result retrieval
347
    future<R> get_future();
348

    
349
    // execution
350
    void operator()(ArgTypes... );
351
    void make_ready_at_thread_exit(ArgTypes...);
352

    
353
    void reset();
354
};
355

    
356
template <class R>
357
  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
358

    
359
template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360

    
361
}  // std
362

    
363
*/
364

    
365
#include <__config>
366
#include <system_error>
367
#include <memory>
368
#include <chrono>
369
#include <exception>
370
#include <mutex>
371
#include <thread>
372

    
373
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
374
#pragma GCC system_header
375
#endif
376

    
377
#ifdef _LIBCPP_HAS_NO_THREADS
378
#error <future> is not supported on this single threaded system
379
#else // !_LIBCPP_HAS_NO_THREADS
380

    
381
_LIBCPP_BEGIN_NAMESPACE_STD
382

    
383
//enum class future_errc
384
_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
385
{
386
    future_already_retrieved = 1,
387
    promise_already_satisfied,
388
    no_state,
389
    broken_promise
390
};
391
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
392

    
393
template <>
394
struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
395

    
396
#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397
template <>
398
struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
399
#endif
400

    
401
//enum class launch
402
_LIBCPP_DECLARE_STRONG_ENUM(launch)
403
{
404
    async = 1,
405
    deferred = 2,
406
    any = async | deferred
407
};
408
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
409

    
410
#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
411

    
412
#ifdef _LIBCXX_UNDERLYING_TYPE
413
typedef underlying_type<launch>::type __launch_underlying_type;
414
#else
415
typedef int __launch_underlying_type;
416
#endif
417

    
418
inline _LIBCPP_INLINE_VISIBILITY
419
_LIBCPP_CONSTEXPR
420
launch
421
operator&(launch __x, launch __y)
422
{
423
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
424
                               static_cast<__launch_underlying_type>(__y));
425
}
426

    
427
inline _LIBCPP_INLINE_VISIBILITY
428
_LIBCPP_CONSTEXPR
429
launch
430
operator|(launch __x, launch __y)
431
{
432
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
433
                               static_cast<__launch_underlying_type>(__y));
434
}
435

    
436
inline _LIBCPP_INLINE_VISIBILITY
437
_LIBCPP_CONSTEXPR
438
launch
439
operator^(launch __x, launch __y)
440
{
441
    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
442
                               static_cast<__launch_underlying_type>(__y));
443
}
444

    
445
inline _LIBCPP_INLINE_VISIBILITY
446
_LIBCPP_CONSTEXPR
447
launch
448
operator~(launch __x)
449
{
450
    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
451
}
452

    
453
inline _LIBCPP_INLINE_VISIBILITY
454
launch&
455
operator&=(launch& __x, launch __y)
456
{
457
    __x = __x & __y; return __x;
458
}
459

    
460
inline _LIBCPP_INLINE_VISIBILITY
461
launch&
462
operator|=(launch& __x, launch __y)
463
{
464
    __x = __x | __y; return __x;
465
}
466

    
467
inline _LIBCPP_INLINE_VISIBILITY
468
launch&
469
operator^=(launch& __x, launch __y)
470
{
471
    __x = __x ^ __y; return __x;
472
}
473

    
474
#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
475

    
476
//enum class future_status
477
_LIBCPP_DECLARE_STRONG_ENUM(future_status)
478
{
479
    ready,
480
    timeout,
481
    deferred
482
};
483
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
484

    
485
_LIBCPP_FUNC_VIS
486
const error_category& future_category() _NOEXCEPT;
487

    
488
inline _LIBCPP_INLINE_VISIBILITY
489
error_code
490
make_error_code(future_errc __e) _NOEXCEPT
491
{
492
    return error_code(static_cast<int>(__e), future_category());
493
}
494

    
495
inline _LIBCPP_INLINE_VISIBILITY
496
error_condition
497
make_error_condition(future_errc __e) _NOEXCEPT
498
{
499
    return error_condition(static_cast<int>(__e), future_category());
500
}
501

    
502
class _LIBCPP_EXCEPTION_ABI future_error
503
    : public logic_error
504
{
505
    error_code __ec_;
506
public:
507
    future_error(error_code __ec);
508

    
509
    _LIBCPP_INLINE_VISIBILITY
510
    const error_code& code() const _NOEXCEPT {return __ec_;}
511

    
512
    virtual ~future_error() _NOEXCEPT;
513
};
514

    
515
class _LIBCPP_TYPE_VIS __assoc_sub_state
516
    : public __shared_count
517
{
518
protected:
519
    exception_ptr __exception_;
520
    mutable mutex __mut_;
521
    mutable condition_variable __cv_;
522
    unsigned __state_;
523

    
524
    virtual void __on_zero_shared() _NOEXCEPT;
525
    void __sub_wait(unique_lock<mutex>& __lk);
526
public:
527
    enum
528
    {
529
        __constructed = 1,
530
        __future_attached = 2,
531
        ready = 4,
532
        deferred = 8
533
    };
534

    
535
    _LIBCPP_INLINE_VISIBILITY
536
    __assoc_sub_state() : __state_(0) {}
537

    
538
    _LIBCPP_INLINE_VISIBILITY
539
    bool __has_value() const
540
        {return (__state_ & __constructed) || (__exception_ != nullptr);}
541

    
542
    _LIBCPP_INLINE_VISIBILITY
543
    void __set_future_attached()
544
    {
545
        lock_guard<mutex> __lk(__mut_);
546
        __state_ |= __future_attached;
547
    }
548
    _LIBCPP_INLINE_VISIBILITY
549
    bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
550

    
551
    _LIBCPP_INLINE_VISIBILITY
552
    void __set_deferred() {__state_ |= deferred;}
553

    
554
    void __make_ready();
555
    _LIBCPP_INLINE_VISIBILITY
556
    bool __is_ready() const {return (__state_ & ready) != 0;}
557

    
558
    void set_value();
559
    void set_value_at_thread_exit();
560

    
561
    void set_exception(exception_ptr __p);
562
    void set_exception_at_thread_exit(exception_ptr __p);
563

    
564
    void copy();
565

    
566
    void wait();
567
    template <class _Rep, class _Period>
568
        future_status
569
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
570
    template <class _Clock, class _Duration>
571
        future_status
572
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
573

    
574
    virtual void __execute();
575
};
576

    
577
template <class _Clock, class _Duration>
578
future_status
579
__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
580
{
581
    unique_lock<mutex> __lk(__mut_);
582
    if (__state_ & deferred)
583
        return future_status::deferred;
584
    while (!(__state_ & ready) && _Clock::now() < __abs_time)
585
        __cv_.wait_until(__lk, __abs_time);
586
    if (__state_ & ready)
587
        return future_status::ready;
588
    return future_status::timeout;
589
}
590

    
591
template <class _Rep, class _Period>
592
inline _LIBCPP_INLINE_VISIBILITY
593
future_status
594
__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
595
{
596
    return wait_until(chrono::steady_clock::now() + __rel_time);
597
}
598

    
599
template <class _Rp>
600
class __assoc_state
601
    : public __assoc_sub_state
602
{
603
    typedef __assoc_sub_state base;
604
    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
605
protected:
606
    _Up __value_;
607

    
608
    virtual void __on_zero_shared() _NOEXCEPT;
609
public:
610

    
611
    template <class _Arg>
612
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
613
        void set_value(_Arg&& __arg);
614
#else
615
        void set_value(_Arg& __arg);
616
#endif
617

    
618
    template <class _Arg>
619
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
620
        void set_value_at_thread_exit(_Arg&& __arg);
621
#else
622
        void set_value_at_thread_exit(_Arg& __arg);
623
#endif
624

    
625
    _Rp move();
626
    typename add_lvalue_reference<_Rp>::type copy();
627
};
628

    
629
template <class _Rp>
630
void
631
__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
632
{
633
    if (this->__state_ & base::__constructed)
634
        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
635
    delete this;
636
}
637

    
638
template <class _Rp>
639
template <class _Arg>
640
void
641
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
642
__assoc_state<_Rp>::set_value(_Arg&& __arg)
643
#else
644
__assoc_state<_Rp>::set_value(_Arg& __arg)
645
#endif
646
{
647
    unique_lock<mutex> __lk(this->__mut_);
648
#ifndef _LIBCPP_NO_EXCEPTIONS
649
    if (this->__has_value())
650
        throw future_error(make_error_code(future_errc::promise_already_satisfied));
651
#endif
652
    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
653
    this->__state_ |= base::__constructed | base::ready;
654
    __cv_.notify_all();
655
}
656

    
657
template <class _Rp>
658
template <class _Arg>
659
void
660
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
661
__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
662
#else
663
__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
664
#endif
665
{
666
    unique_lock<mutex> __lk(this->__mut_);
667
#ifndef _LIBCPP_NO_EXCEPTIONS
668
    if (this->__has_value())
669
        throw future_error(make_error_code(future_errc::promise_already_satisfied));
670
#endif
671
    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
672
    this->__state_ |= base::__constructed;
673
    __thread_local_data()->__make_ready_at_thread_exit(this);
674
}
675

    
676
template <class _Rp>
677
_Rp
678
__assoc_state<_Rp>::move()
679
{
680
    unique_lock<mutex> __lk(this->__mut_);
681
    this->__sub_wait(__lk);
682
    if (this->__exception_ != nullptr)
683
        rethrow_exception(this->__exception_);
684
    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
685
}
686

    
687
template <class _Rp>
688
typename add_lvalue_reference<_Rp>::type
689
__assoc_state<_Rp>::copy()
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 *reinterpret_cast<_Rp*>(&__value_);
696
}
697

    
698
template <class _Rp>
699
class __assoc_state<_Rp&>
700
    : public __assoc_sub_state
701
{
702
    typedef __assoc_sub_state base;
703
    typedef _Rp* _Up;
704
protected:
705
    _Up __value_;
706

    
707
    virtual void __on_zero_shared() _NOEXCEPT;
708
public:
709

    
710
    void set_value(_Rp& __arg);
711
    void set_value_at_thread_exit(_Rp& __arg);
712

    
713
    _Rp& copy();
714
};
715

    
716
template <class _Rp>
717
void
718
__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
719
{
720
    delete this;
721
}
722

    
723
template <class _Rp>
724
void
725
__assoc_state<_Rp&>::set_value(_Rp& __arg)
726
{
727
    unique_lock<mutex> __lk(this->__mut_);
728
#ifndef _LIBCPP_NO_EXCEPTIONS
729
    if (this->__has_value())
730
        throw future_error(make_error_code(future_errc::promise_already_satisfied));
731
#endif
732
    __value_ = _VSTD::addressof(__arg);
733
    this->__state_ |= base::__constructed | base::ready;
734
    __cv_.notify_all();
735
}
736

    
737
template <class _Rp>
738
void
739
__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
740
{
741
    unique_lock<mutex> __lk(this->__mut_);
742
#ifndef _LIBCPP_NO_EXCEPTIONS
743
    if (this->__has_value())
744
        throw future_error(make_error_code(future_errc::promise_already_satisfied));
745
#endif
746
    __value_ = _VSTD::addressof(__arg);
747
    this->__state_ |= base::__constructed;
748
    __thread_local_data()->__make_ready_at_thread_exit(this);
749
}
750

    
751
template <class _Rp>
752
_Rp&
753
__assoc_state<_Rp&>::copy()
754
{
755
    unique_lock<mutex> __lk(this->__mut_);
756
    this->__sub_wait(__lk);
757
    if (this->__exception_ != nullptr)
758
        rethrow_exception(this->__exception_);
759
    return *__value_;
760
}
761

    
762
template <class _Rp, class _Alloc>
763
class __assoc_state_alloc
764
    : public __assoc_state<_Rp>
765
{
766
    typedef __assoc_state<_Rp> base;
767
    _Alloc __alloc_;
768

    
769
    virtual void __on_zero_shared() _NOEXCEPT;
770
public:
771
    _LIBCPP_INLINE_VISIBILITY
772
    explicit __assoc_state_alloc(const _Alloc& __a)
773
        : __alloc_(__a) {}
774
};
775

    
776
template <class _Rp, class _Alloc>
777
void
778
__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
779
{
780
    if (this->__state_ & base::__constructed)
781
        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
782
    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
783
    typedef allocator_traits<_Al> _ATraits;
784
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
785
    _Al __a(__alloc_);
786
    this->~__assoc_state_alloc();
787
    __a.deallocate(_PTraits::pointer_to(*this), 1);
788
}
789

    
790
template <class _Rp, class _Alloc>
791
class __assoc_state_alloc<_Rp&, _Alloc>
792
    : public __assoc_state<_Rp&>
793
{
794
    typedef __assoc_state<_Rp&> base;
795
    _Alloc __alloc_;
796

    
797
    virtual void __on_zero_shared() _NOEXCEPT;
798
public:
799
    _LIBCPP_INLINE_VISIBILITY
800
    explicit __assoc_state_alloc(const _Alloc& __a)
801
        : __alloc_(__a) {}
802
};
803

    
804
template <class _Rp, class _Alloc>
805
void
806
__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
807
{
808
    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
809
    typedef allocator_traits<_Al> _ATraits;
810
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
811
    _Al __a(__alloc_);
812
    this->~__assoc_state_alloc();
813
    __a.deallocate(_PTraits::pointer_to(*this), 1);
814
}
815

    
816
template <class _Alloc>
817
class __assoc_sub_state_alloc
818
    : public __assoc_sub_state
819
{
820
    typedef __assoc_sub_state base;
821
    _Alloc __alloc_;
822

    
823
    virtual void __on_zero_shared() _NOEXCEPT;
824
public:
825
    _LIBCPP_INLINE_VISIBILITY
826
    explicit __assoc_sub_state_alloc(const _Alloc& __a)
827
        : __alloc_(__a) {}
828
};
829

    
830
template <class _Alloc>
831
void
832
__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
833
{
834
    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
835
    typedef allocator_traits<_Al> _ATraits;
836
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
837
    _Al __a(__alloc_);
838
    this->~__assoc_sub_state_alloc();
839
    __a.deallocate(_PTraits::pointer_to(*this), 1);
840
}
841

    
842
template <class _Rp, class _Fp>
843
class __deferred_assoc_state
844
    : public __assoc_state<_Rp>
845
{
846
    typedef __assoc_state<_Rp> base;
847

    
848
    _Fp __func_;
849

    
850
public:
851
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
852
    explicit __deferred_assoc_state(_Fp&& __f);
853
#endif
854

    
855
    virtual void __execute();
856
};
857

    
858
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
859

    
860
template <class _Rp, class _Fp>
861
inline _LIBCPP_INLINE_VISIBILITY
862
__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
863
    : __func_(_VSTD::forward<_Fp>(__f))
864
{
865
    this->__set_deferred();
866
}
867

    
868
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
869

    
870
template <class _Rp, class _Fp>
871
void
872
__deferred_assoc_state<_Rp, _Fp>::__execute()
873
{
874
#ifndef _LIBCPP_NO_EXCEPTIONS
875
    try
876
    {
877
#endif  // _LIBCPP_NO_EXCEPTIONS
878
        this->set_value(__func_());
879
#ifndef _LIBCPP_NO_EXCEPTIONS
880
    }
881
    catch (...)
882
    {
883
        this->set_exception(current_exception());
884
    }
885
#endif  // _LIBCPP_NO_EXCEPTIONS
886
}
887

    
888
template <class _Fp>
889
class __deferred_assoc_state<void, _Fp>
890
    : public __assoc_sub_state
891
{
892
    typedef __assoc_sub_state base;
893

    
894
    _Fp __func_;
895

    
896
public:
897
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
898
    explicit __deferred_assoc_state(_Fp&& __f);
899
#endif
900

    
901
    virtual void __execute();
902
};
903

    
904
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
905

    
906
template <class _Fp>
907
inline _LIBCPP_INLINE_VISIBILITY
908
__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
909
    : __func_(_VSTD::forward<_Fp>(__f))
910
{
911
    this->__set_deferred();
912
}
913

    
914
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
915

    
916
template <class _Fp>
917
void
918
__deferred_assoc_state<void, _Fp>::__execute()
919
{
920
#ifndef _LIBCPP_NO_EXCEPTIONS
921
    try
922
    {
923
#endif  // _LIBCPP_NO_EXCEPTIONS
924
        __func_();
925
        this->set_value();
926
#ifndef _LIBCPP_NO_EXCEPTIONS
927
    }
928
    catch (...)
929
    {
930
        this->set_exception(current_exception());
931
    }
932
#endif  // _LIBCPP_NO_EXCEPTIONS
933
}
934

    
935
template <class _Rp, class _Fp>
936
class __async_assoc_state
937
    : public __assoc_state<_Rp>
938
{
939
    typedef __assoc_state<_Rp> base;
940

    
941
    _Fp __func_;
942

    
943
    virtual void __on_zero_shared() _NOEXCEPT;
944
public:
945
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
946
    explicit __async_assoc_state(_Fp&& __f);
947
#endif
948

    
949
    virtual void __execute();
950
};
951

    
952
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
953

    
954
template <class _Rp, class _Fp>
955
inline _LIBCPP_INLINE_VISIBILITY
956
__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
957
    : __func_(_VSTD::forward<_Fp>(__f))
958
{
959
}
960

    
961
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
962

    
963
template <class _Rp, class _Fp>
964
void
965
__async_assoc_state<_Rp, _Fp>::__execute()
966
{
967
#ifndef _LIBCPP_NO_EXCEPTIONS
968
    try
969
    {
970
#endif  // _LIBCPP_NO_EXCEPTIONS
971
        this->set_value(__func_());
972
#ifndef _LIBCPP_NO_EXCEPTIONS
973
    }
974
    catch (...)
975
    {
976
        this->set_exception(current_exception());
977
    }
978
#endif  // _LIBCPP_NO_EXCEPTIONS
979
}
980

    
981
template <class _Rp, class _Fp>
982
void
983
__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
984
{
985
    this->wait();
986
    base::__on_zero_shared();
987
}
988

    
989
template <class _Fp>
990
class __async_assoc_state<void, _Fp>
991
    : public __assoc_sub_state
992
{
993
    typedef __assoc_sub_state base;
994

    
995
    _Fp __func_;
996

    
997
    virtual void __on_zero_shared() _NOEXCEPT;
998
public:
999
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1000
    explicit __async_assoc_state(_Fp&& __f);
1001
#endif
1002

    
1003
    virtual void __execute();
1004
};
1005

    
1006
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1007

    
1008
template <class _Fp>
1009
inline _LIBCPP_INLINE_VISIBILITY
1010
__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1011
    : __func_(_VSTD::forward<_Fp>(__f))
1012
{
1013
}
1014

    
1015
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1016

    
1017
template <class _Fp>
1018
void
1019
__async_assoc_state<void, _Fp>::__execute()
1020
{
1021
#ifndef _LIBCPP_NO_EXCEPTIONS
1022
    try
1023
    {
1024
#endif  // _LIBCPP_NO_EXCEPTIONS
1025
        __func_();
1026
        this->set_value();
1027
#ifndef _LIBCPP_NO_EXCEPTIONS
1028
    }
1029
    catch (...)
1030
    {
1031
        this->set_exception(current_exception());
1032
    }
1033
#endif  // _LIBCPP_NO_EXCEPTIONS
1034
}
1035

    
1036
template <class _Fp>
1037
void
1038
__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
1039
{
1040
    this->wait();
1041
    base::__on_zero_shared();
1042
}
1043

    
1044
template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1045
template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
1046

    
1047
// future
1048

    
1049
template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
1050

    
1051
template <class _Rp, class _Fp>
1052
future<_Rp>
1053
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1054
__make_deferred_assoc_state(_Fp&& __f);
1055
#else
1056
__make_deferred_assoc_state(_Fp __f);
1057
#endif
1058

    
1059
template <class _Rp, class _Fp>
1060
future<_Rp>
1061
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1062
__make_async_assoc_state(_Fp&& __f);
1063
#else
1064
__make_async_assoc_state(_Fp __f);
1065
#endif
1066

    
1067
template <class _Rp>
1068
class _LIBCPP_TYPE_VIS_ONLY future
1069
{
1070
    __assoc_state<_Rp>* __state_;
1071

    
1072
    explicit future(__assoc_state<_Rp>* __state);
1073

    
1074
    template <class> friend class promise;
1075
    template <class> friend class shared_future;
1076

    
1077
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1078
    template <class _R1, class _Fp>
1079
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1080
    template <class _R1, class _Fp>
1081
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1082
#else
1083
    template <class _R1, class _Fp>
1084
        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1085
    template <class _R1, class _Fp>
1086
        friend future<_R1> __make_async_assoc_state(_Fp __f);
1087
#endif
1088

    
1089
public:
1090
    _LIBCPP_INLINE_VISIBILITY
1091
    future() _NOEXCEPT : __state_(nullptr) {}
1092
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1093
    _LIBCPP_INLINE_VISIBILITY
1094
    future(future&& __rhs) _NOEXCEPT
1095
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1096
    future(const future&) = delete;
1097
    future& operator=(const future&) = delete;
1098
    _LIBCPP_INLINE_VISIBILITY
1099
    future& operator=(future&& __rhs) _NOEXCEPT
1100
        {
1101
            future(std::move(__rhs)).swap(*this);
1102
            return *this;
1103
        }
1104
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1105
private:
1106
    future(const future&);
1107
    future& operator=(const future&);
1108
public:
1109
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1110
    ~future();
1111
    shared_future<_Rp> share();
1112

    
1113
    // retrieving the value
1114
    _Rp get();
1115

    
1116
    _LIBCPP_INLINE_VISIBILITY
1117
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1118

    
1119
    // functions to check state
1120
    _LIBCPP_INLINE_VISIBILITY
1121
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1122

    
1123
    _LIBCPP_INLINE_VISIBILITY
1124
    void wait() const {__state_->wait();}
1125
    template <class _Rep, class _Period>
1126
        _LIBCPP_INLINE_VISIBILITY
1127
        future_status
1128
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1129
            {return __state_->wait_for(__rel_time);}
1130
    template <class _Clock, class _Duration>
1131
        _LIBCPP_INLINE_VISIBILITY
1132
        future_status
1133
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1134
            {return __state_->wait_until(__abs_time);}
1135
};
1136

    
1137
template <class _Rp>
1138
future<_Rp>::future(__assoc_state<_Rp>* __state)
1139
    : __state_(__state)
1140
{
1141
#ifndef _LIBCPP_NO_EXCEPTIONS
1142
    if (__state_->__has_future_attached())
1143
        throw future_error(make_error_code(future_errc::future_already_retrieved));
1144
#endif
1145
    __state_->__add_shared();
1146
    __state_->__set_future_attached();
1147
}
1148

    
1149
struct __release_shared_count
1150
{
1151
    void operator()(__shared_count* p) {p->__release_shared();}
1152
};
1153

    
1154
template <class _Rp>
1155
future<_Rp>::~future()
1156
{
1157
    if (__state_)
1158
        __state_->__release_shared();
1159
}
1160

    
1161
template <class _Rp>
1162
_Rp
1163
future<_Rp>::get()
1164
{
1165
    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1166
    __assoc_state<_Rp>* __s = __state_;
1167
    __state_ = nullptr;
1168
    return __s->move();
1169
}
1170

    
1171
template <class _Rp>
1172
class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
1173
{
1174
    __assoc_state<_Rp&>* __state_;
1175

    
1176
    explicit future(__assoc_state<_Rp&>* __state);
1177

    
1178
    template <class> friend class promise;
1179
    template <class> friend class shared_future;
1180

    
1181
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1182
    template <class _R1, class _Fp>
1183
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1184
    template <class _R1, class _Fp>
1185
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1186
#else
1187
    template <class _R1, class _Fp>
1188
        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1189
    template <class _R1, class _Fp>
1190
        friend future<_R1> __make_async_assoc_state(_Fp __f);
1191
#endif
1192

    
1193
public:
1194
    _LIBCPP_INLINE_VISIBILITY
1195
    future() _NOEXCEPT : __state_(nullptr) {}
1196
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1197
    _LIBCPP_INLINE_VISIBILITY
1198
    future(future&& __rhs) _NOEXCEPT
1199
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1200
    future(const future&) = delete;
1201
    future& operator=(const future&) = delete;
1202
    _LIBCPP_INLINE_VISIBILITY
1203
    future& operator=(future&& __rhs) _NOEXCEPT
1204
        {
1205
            future(std::move(__rhs)).swap(*this);
1206
            return *this;
1207
        }
1208
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1209
private:
1210
    future(const future&);
1211
    future& operator=(const future&);
1212
public:
1213
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1214
    ~future();
1215
    shared_future<_Rp&> share();
1216

    
1217
    // retrieving the value
1218
    _Rp& get();
1219

    
1220
    _LIBCPP_INLINE_VISIBILITY
1221
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1222

    
1223
    // functions to check state
1224
    _LIBCPP_INLINE_VISIBILITY
1225
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1226

    
1227
    _LIBCPP_INLINE_VISIBILITY
1228
    void wait() const {__state_->wait();}
1229
    template <class _Rep, class _Period>
1230
        _LIBCPP_INLINE_VISIBILITY
1231
        future_status
1232
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1233
            {return __state_->wait_for(__rel_time);}
1234
    template <class _Clock, class _Duration>
1235
        _LIBCPP_INLINE_VISIBILITY
1236
        future_status
1237
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1238
            {return __state_->wait_until(__abs_time);}
1239
};
1240

    
1241
template <class _Rp>
1242
future<_Rp&>::future(__assoc_state<_Rp&>* __state)
1243
    : __state_(__state)
1244
{
1245
#ifndef _LIBCPP_NO_EXCEPTIONS
1246
    if (__state_->__has_future_attached())
1247
        throw future_error(make_error_code(future_errc::future_already_retrieved));
1248
#endif
1249
    __state_->__add_shared();
1250
    __state_->__set_future_attached();
1251
}
1252

    
1253
template <class _Rp>
1254
future<_Rp&>::~future()
1255
{
1256
    if (__state_)
1257
        __state_->__release_shared();
1258
}
1259

    
1260
template <class _Rp>
1261
_Rp&
1262
future<_Rp&>::get()
1263
{
1264
    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1265
    __assoc_state<_Rp&>* __s = __state_;
1266
    __state_ = nullptr;
1267
    return __s->copy();
1268
}
1269

    
1270
template <>
1271
class _LIBCPP_TYPE_VIS future<void>
1272
{
1273
    __assoc_sub_state* __state_;
1274

    
1275
    explicit future(__assoc_sub_state* __state);
1276

    
1277
    template <class> friend class promise;
1278
    template <class> friend class shared_future;
1279

    
1280
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1281
    template <class _R1, class _Fp>
1282
        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1283
    template <class _R1, class _Fp>
1284
        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1285
#else
1286
    template <class _R1, class _Fp>
1287
        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1288
    template <class _R1, class _Fp>
1289
        friend future<_R1> __make_async_assoc_state(_Fp __f);
1290
#endif
1291

    
1292
public:
1293
    _LIBCPP_INLINE_VISIBILITY
1294
    future() _NOEXCEPT : __state_(nullptr) {}
1295
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1296
    _LIBCPP_INLINE_VISIBILITY
1297
    future(future&& __rhs) _NOEXCEPT
1298
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1299
    future(const future&) = delete;
1300
    future& operator=(const future&) = delete;
1301
    _LIBCPP_INLINE_VISIBILITY
1302
    future& operator=(future&& __rhs) _NOEXCEPT
1303
        {
1304
            future(std::move(__rhs)).swap(*this);
1305
            return *this;
1306
        }
1307
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1308
private:
1309
    future(const future&);
1310
    future& operator=(const future&);
1311
public:
1312
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1313
    ~future();
1314
    shared_future<void> share();
1315

    
1316
    // retrieving the value
1317
    void get();
1318

    
1319
    _LIBCPP_INLINE_VISIBILITY
1320
    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1321

    
1322
    // functions to check state
1323
    _LIBCPP_INLINE_VISIBILITY
1324
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1325

    
1326
    _LIBCPP_INLINE_VISIBILITY
1327
    void wait() const {__state_->wait();}
1328
    template <class _Rep, class _Period>
1329
        _LIBCPP_INLINE_VISIBILITY
1330
        future_status
1331
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1332
            {return __state_->wait_for(__rel_time);}
1333
    template <class _Clock, class _Duration>
1334
        _LIBCPP_INLINE_VISIBILITY
1335
        future_status
1336
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1337
            {return __state_->wait_until(__abs_time);}
1338
};
1339

    
1340
template <class _Rp>
1341
inline _LIBCPP_INLINE_VISIBILITY
1342
void
1343
swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1344
{
1345
    __x.swap(__y);
1346
}
1347

    
1348
// promise<R>
1349

    
1350
template <class _Callable> class packaged_task;
1351

    
1352
template <class _Rp>
1353
class _LIBCPP_TYPE_VIS_ONLY promise
1354
{
1355
    __assoc_state<_Rp>* __state_;
1356

    
1357
    _LIBCPP_INLINE_VISIBILITY
1358
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1359

    
1360
    template <class> friend class packaged_task;
1361
public:
1362
    promise();
1363
    template <class _Alloc>
1364
        promise(allocator_arg_t, const _Alloc& __a);
1365
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1366
    _LIBCPP_INLINE_VISIBILITY
1367
    promise(promise&& __rhs) _NOEXCEPT
1368
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1369
    promise(const promise& __rhs) = delete;
1370
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1371
private:
1372
    promise(const promise& __rhs);
1373
public:
1374
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1375
    ~promise();
1376

    
1377
    // assignment
1378
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1379
    _LIBCPP_INLINE_VISIBILITY
1380
    promise& operator=(promise&& __rhs) _NOEXCEPT
1381
        {
1382
            promise(std::move(__rhs)).swap(*this);
1383
            return *this;
1384
        }
1385
    promise& operator=(const promise& __rhs) = delete;
1386
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1387
private:
1388
    promise& operator=(const promise& __rhs);
1389
public:
1390
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1391
    _LIBCPP_INLINE_VISIBILITY
1392
    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1393

    
1394
    // retrieving the result
1395
    future<_Rp> get_future();
1396

    
1397
    // setting the result
1398
    void set_value(const _Rp& __r);
1399
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1400
    void set_value(_Rp&& __r);
1401
#endif
1402
    void set_exception(exception_ptr __p);
1403

    
1404
    // setting the result with deferred notification
1405
    void set_value_at_thread_exit(const _Rp& __r);
1406
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1407
    void set_value_at_thread_exit(_Rp&& __r);
1408
#endif
1409
    void set_exception_at_thread_exit(exception_ptr __p);
1410
};
1411

    
1412
template <class _Rp>
1413
promise<_Rp>::promise()
1414
    : __state_(new __assoc_state<_Rp>)
1415
{
1416
}
1417

    
1418
template <class _Rp>
1419
template <class _Alloc>
1420
promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1421
{
1422
    typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1423
    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1424
    typedef __allocator_destructor<_A2> _D2;
1425
    _A2 __a(__a0);
1426
    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1427
    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1428
    __state_ = _VSTD::addressof(*__hold.release());
1429
}
1430

    
1431
template <class _Rp>
1432
promise<_Rp>::~promise()
1433
{
1434
    if (__state_)
1435
    {
1436
        if (!__state_->__has_value() && __state_->use_count() > 1)
1437
            __state_->set_exception(make_exception_ptr(
1438
                      future_error(make_error_code(future_errc::broken_promise))
1439
                                                      ));
1440
        __state_->__release_shared();
1441
    }
1442
}
1443

    
1444
template <class _Rp>
1445
future<_Rp>
1446
promise<_Rp>::get_future()
1447
{
1448
#ifndef _LIBCPP_NO_EXCEPTIONS
1449
    if (__state_ == nullptr)
1450
        throw future_error(make_error_code(future_errc::no_state));
1451
#endif
1452
    return future<_Rp>(__state_);
1453
}
1454

    
1455
template <class _Rp>
1456
void
1457
promise<_Rp>::set_value(const _Rp& __r)
1458
{
1459
#ifndef _LIBCPP_NO_EXCEPTIONS
1460
    if (__state_ == nullptr)
1461
        throw future_error(make_error_code(future_errc::no_state));
1462
#endif
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
#ifndef _LIBCPP_NO_EXCEPTIONS
1473
    if (__state_ == nullptr)
1474
        throw future_error(make_error_code(future_errc::no_state));
1475
#endif
1476
    __state_->set_value(_VSTD::move(__r));
1477
}
1478

    
1479
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1480

    
1481
template <class _Rp>
1482
void
1483
promise<_Rp>::set_exception(exception_ptr __p)
1484
{
1485
#ifndef _LIBCPP_NO_EXCEPTIONS
1486
    if (__state_ == nullptr)
1487
        throw future_error(make_error_code(future_errc::no_state));
1488
#endif
1489
    __state_->set_exception(__p);
1490
}
1491

    
1492
template <class _Rp>
1493
void
1494
promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1495
{
1496
#ifndef _LIBCPP_NO_EXCEPTIONS
1497
    if (__state_ == nullptr)
1498
        throw future_error(make_error_code(future_errc::no_state));
1499
#endif
1500
    __state_->set_value_at_thread_exit(__r);
1501
}
1502

    
1503
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1504

    
1505
template <class _Rp>
1506
void
1507
promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1508
{
1509
#ifndef _LIBCPP_NO_EXCEPTIONS
1510
    if (__state_ == nullptr)
1511
        throw future_error(make_error_code(future_errc::no_state));
1512
#endif
1513
    __state_->set_value_at_thread_exit(_VSTD::move(__r));
1514
}
1515

    
1516
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1517

    
1518
template <class _Rp>
1519
void
1520
promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1521
{
1522
#ifndef _LIBCPP_NO_EXCEPTIONS
1523
    if (__state_ == nullptr)
1524
        throw future_error(make_error_code(future_errc::no_state));
1525
#endif
1526
    __state_->set_exception_at_thread_exit(__p);
1527
}
1528

    
1529
// promise<R&>
1530

    
1531
template <class _Rp>
1532
class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
1533
{
1534
    __assoc_state<_Rp&>* __state_;
1535

    
1536
    _LIBCPP_INLINE_VISIBILITY
1537
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1538

    
1539
    template <class> friend class packaged_task;
1540

    
1541
public:
1542
    promise();
1543
    template <class _Allocator>
1544
        promise(allocator_arg_t, const _Allocator& __a);
1545
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1546
    _LIBCPP_INLINE_VISIBILITY
1547
    promise(promise&& __rhs) _NOEXCEPT
1548
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1549
    promise(const promise& __rhs) = delete;
1550
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1551
private:
1552
    promise(const promise& __rhs);
1553
public:
1554
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1555
    ~promise();
1556

    
1557
    // assignment
1558
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1559
    _LIBCPP_INLINE_VISIBILITY
1560
    promise& operator=(promise&& __rhs) _NOEXCEPT
1561
        {
1562
            promise(std::move(__rhs)).swap(*this);
1563
            return *this;
1564
        }
1565
    promise& operator=(const promise& __rhs) = delete;
1566
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1567
private:
1568
    promise& operator=(const promise& __rhs);
1569
public:
1570
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1571
    _LIBCPP_INLINE_VISIBILITY
1572
    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1573

    
1574
    // retrieving the result
1575
    future<_Rp&> get_future();
1576

    
1577
    // setting the result
1578
    void set_value(_Rp& __r);
1579
    void set_exception(exception_ptr __p);
1580

    
1581
    // setting the result with deferred notification
1582
    void set_value_at_thread_exit(_Rp&);
1583
    void set_exception_at_thread_exit(exception_ptr __p);
1584
};
1585

    
1586
template <class _Rp>
1587
promise<_Rp&>::promise()
1588
    : __state_(new __assoc_state<_Rp&>)
1589
{
1590
}
1591

    
1592
template <class _Rp>
1593
template <class _Alloc>
1594
promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1595
{
1596
    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1597
    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1598
    typedef __allocator_destructor<_A2> _D2;
1599
    _A2 __a(__a0);
1600
    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1601
    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1602
    __state_ = _VSTD::addressof(*__hold.release());
1603
}
1604

    
1605
template <class _Rp>
1606
promise<_Rp&>::~promise()
1607
{
1608
    if (__state_)
1609
    {
1610
        if (!__state_->__has_value() && __state_->use_count() > 1)
1611
            __state_->set_exception(make_exception_ptr(
1612
                      future_error(make_error_code(future_errc::broken_promise))
1613
                                                      ));
1614
        __state_->__release_shared();
1615
    }
1616
}
1617

    
1618
template <class _Rp>
1619
future<_Rp&>
1620
promise<_Rp&>::get_future()
1621
{
1622
#ifndef _LIBCPP_NO_EXCEPTIONS
1623
    if (__state_ == nullptr)
1624
        throw future_error(make_error_code(future_errc::no_state));
1625
#endif
1626
    return future<_Rp&>(__state_);
1627
}
1628

    
1629
template <class _Rp>
1630
void
1631
promise<_Rp&>::set_value(_Rp& __r)
1632
{
1633
#ifndef _LIBCPP_NO_EXCEPTIONS
1634
    if (__state_ == nullptr)
1635
        throw future_error(make_error_code(future_errc::no_state));
1636
#endif
1637
    __state_->set_value(__r);
1638
}
1639

    
1640
template <class _Rp>
1641
void
1642
promise<_Rp&>::set_exception(exception_ptr __p)
1643
{
1644
#ifndef _LIBCPP_NO_EXCEPTIONS
1645
    if (__state_ == nullptr)
1646
        throw future_error(make_error_code(future_errc::no_state));
1647
#endif
1648
    __state_->set_exception(__p);
1649
}
1650

    
1651
template <class _Rp>
1652
void
1653
promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1654
{
1655
#ifndef _LIBCPP_NO_EXCEPTIONS
1656
    if (__state_ == nullptr)
1657
        throw future_error(make_error_code(future_errc::no_state));
1658
#endif
1659
    __state_->set_value_at_thread_exit(__r);
1660
}
1661

    
1662
template <class _Rp>
1663
void
1664
promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1665
{
1666
#ifndef _LIBCPP_NO_EXCEPTIONS
1667
    if (__state_ == nullptr)
1668
        throw future_error(make_error_code(future_errc::no_state));
1669
#endif
1670
    __state_->set_exception_at_thread_exit(__p);
1671
}
1672

    
1673
// promise<void>
1674

    
1675
template <>
1676
class _LIBCPP_TYPE_VIS promise<void>
1677
{
1678
    __assoc_sub_state* __state_;
1679

    
1680
    _LIBCPP_INLINE_VISIBILITY
1681
    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1682

    
1683
    template <class> friend class packaged_task;
1684

    
1685
public:
1686
    promise();
1687
    template <class _Allocator>
1688
        promise(allocator_arg_t, const _Allocator& __a);
1689
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1690
    _LIBCPP_INLINE_VISIBILITY
1691
    promise(promise&& __rhs) _NOEXCEPT
1692
        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1693
    promise(const promise& __rhs) = delete;
1694
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1695
private:
1696
    promise(const promise& __rhs);
1697
public:
1698
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1699
    ~promise();
1700

    
1701
    // assignment
1702
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1703
    _LIBCPP_INLINE_VISIBILITY
1704
    promise& operator=(promise&& __rhs) _NOEXCEPT
1705
        {
1706
            promise(std::move(__rhs)).swap(*this);
1707
            return *this;
1708
        }
1709
    promise& operator=(const promise& __rhs) = delete;
1710
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1711
private:
1712
    promise& operator=(const promise& __rhs);
1713
public:
1714
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1715
    _LIBCPP_INLINE_VISIBILITY
1716
    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1717

    
1718
    // retrieving the result
1719
    future<void> get_future();
1720

    
1721
    // setting the result
1722
    void set_value();
1723
    void set_exception(exception_ptr __p);
1724

    
1725
    // setting the result with deferred notification
1726
    void set_value_at_thread_exit();
1727
    void set_exception_at_thread_exit(exception_ptr __p);
1728
};
1729

    
1730
template <class _Alloc>
1731
promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1732
{
1733
    typedef __assoc_sub_state_alloc<_Alloc> _State;
1734
    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1735
    typedef __allocator_destructor<_A2> _D2;
1736
    _A2 __a(__a0);
1737
    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1738
    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1739
    __state_ = _VSTD::addressof(*__hold.release());
1740
}
1741

    
1742
template <class _Rp>
1743
inline _LIBCPP_INLINE_VISIBILITY
1744
void
1745
swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1746
{
1747
    __x.swap(__y);
1748
}
1749

    
1750
template <class _Rp, class _Alloc>
1751
    struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
1752
        : public true_type {};
1753

    
1754
#ifndef _LIBCPP_HAS_NO_VARIADICS
1755

    
1756
// packaged_task
1757

    
1758
template<class _Fp> class __packaged_task_base;
1759

    
1760
template<class _Rp, class ..._ArgTypes>
1761
class __packaged_task_base<_Rp(_ArgTypes...)>
1762
{
1763
    __packaged_task_base(const __packaged_task_base&);
1764
    __packaged_task_base& operator=(const __packaged_task_base&);
1765
public:
1766
    _LIBCPP_INLINE_VISIBILITY
1767
    __packaged_task_base() {}
1768
    _LIBCPP_INLINE_VISIBILITY
1769
    virtual ~__packaged_task_base() {}
1770
    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1771
    virtual void destroy() = 0;
1772
    virtual void destroy_deallocate() = 0;
1773
    virtual _Rp operator()(_ArgTypes&& ...) = 0;
1774
};
1775

    
1776
template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1777

    
1778
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1779
class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1780
    : public  __packaged_task_base<_Rp(_ArgTypes...)>
1781
{
1782
    __compressed_pair<_Fp, _Alloc> __f_;
1783
public:
1784
    _LIBCPP_INLINE_VISIBILITY
1785
    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
1786
    _LIBCPP_INLINE_VISIBILITY
1787
    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
1788
    _LIBCPP_INLINE_VISIBILITY
1789
    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1790
        : __f_(__f, __a) {}
1791
    _LIBCPP_INLINE_VISIBILITY
1792
    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1793
        : __f_(_VSTD::move(__f), __a) {}
1794
    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1795
    virtual void destroy();
1796
    virtual void destroy_deallocate();
1797
    virtual _Rp operator()(_ArgTypes&& ... __args);
1798
};
1799

    
1800
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1801
void
1802
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1803
                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1804
{
1805
    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1806
}
1807

    
1808
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1809
void
1810
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1811
{
1812
    __f_.~__compressed_pair<_Fp, _Alloc>();
1813
}
1814

    
1815
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1816
void
1817
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1818
{
1819
    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1820
    typedef allocator_traits<_Ap> _ATraits;
1821
    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
1822
    _Ap __a(__f_.second());
1823
    __f_.~__compressed_pair<_Fp, _Alloc>();
1824
    __a.deallocate(_PTraits::pointer_to(*this), 1);
1825
}
1826

    
1827
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1828
_Rp
1829
__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1830
{
1831
    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1832
}
1833

    
1834
template <class _Callable> class __packaged_task_function;
1835

    
1836
template<class _Rp, class ..._ArgTypes>
1837
class __packaged_task_function<_Rp(_ArgTypes...)>
1838
{
1839
    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1840
    typename aligned_storage<3*sizeof(void*)>::type __buf_;
1841
    __base* __f_;
1842

    
1843
public:
1844
    typedef _Rp result_type;
1845

    
1846
    // construct/copy/destroy:
1847
    _LIBCPP_INLINE_VISIBILITY
1848
    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1849
    template<class _Fp>
1850
      __packaged_task_function(_Fp&& __f);
1851
    template<class _Fp, class _Alloc>
1852
      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1853

    
1854
    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1855
    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1856

    
1857
    __packaged_task_function(const __packaged_task_function&) =  delete;
1858
    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
1859

    
1860
    ~__packaged_task_function();
1861

    
1862
    void swap(__packaged_task_function&) _NOEXCEPT;
1863

    
1864
    _Rp operator()(_ArgTypes...) const;
1865
};
1866

    
1867
template<class _Rp, class ..._ArgTypes>
1868
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1869
{
1870
    if (__f.__f_ == nullptr)
1871
        __f_ = nullptr;
1872
    else if (__f.__f_ == (__base*)&__f.__buf_)
1873
    {
1874
        __f_ = (__base*)&__buf_;
1875
        __f.__f_->__move_to(__f_);
1876
    }
1877
    else
1878
    {
1879
        __f_ = __f.__f_;
1880
        __f.__f_ = nullptr;
1881
    }
1882
}
1883

    
1884
template<class _Rp, class ..._ArgTypes>
1885
template <class _Fp>
1886
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1887
    : __f_(nullptr)
1888
{
1889
    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1890
    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1891
    if (sizeof(_FF) <= sizeof(__buf_))
1892
    {
1893
        __f_ = (__base*)&__buf_;
1894
        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1895
    }
1896
    else
1897
    {
1898
        typedef allocator<_FF> _Ap;
1899
        _Ap __a;
1900
        typedef __allocator_destructor<_Ap> _Dp;
1901
        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1902
        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1903
        __f_ = __hold.release();
1904
    }
1905
}
1906

    
1907
template<class _Rp, class ..._ArgTypes>
1908
template <class _Fp, class _Alloc>
1909
__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1910
                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1911
    : __f_(nullptr)
1912
{
1913
    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1914
    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1915
    if (sizeof(_FF) <= sizeof(__buf_))
1916
    {
1917
        __f_ = (__base*)&__buf_;
1918
        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1919
    }
1920
    else
1921
    {
1922
        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
1923
        _Ap __a(__a0);
1924
        typedef __allocator_destructor<_Ap> _Dp;
1925
        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1926
        ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1927
            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1928
        __f_ = _VSTD::addressof(*__hold.release());
1929
    }
1930
}
1931

    
1932
template<class _Rp, class ..._ArgTypes>
1933
__packaged_task_function<_Rp(_ArgTypes...)>&
1934
__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1935
{
1936
    if (__f_ == (__base*)&__buf_)
1937
        __f_->destroy();
1938
    else if (__f_)
1939
        __f_->destroy_deallocate();
1940
    __f_ = nullptr;
1941
    if (__f.__f_ == nullptr)
1942
        __f_ = nullptr;
1943
    else if (__f.__f_ == (__base*)&__f.__buf_)
1944
    {
1945
        __f_ = (__base*)&__buf_;
1946
        __f.__f_->__move_to(__f_);
1947
    }
1948
    else
1949
    {
1950
        __f_ = __f.__f_;
1951
        __f.__f_ = nullptr;
1952
    }
1953
    return *this;
1954
}
1955

    
1956
template<class _Rp, class ..._ArgTypes>
1957
__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1958
{
1959
    if (__f_ == (__base*)&__buf_)
1960
        __f_->destroy();
1961
    else if (__f_)
1962
        __f_->destroy_deallocate();
1963
}
1964

    
1965
template<class _Rp, class ..._ArgTypes>
1966
void
1967
__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1968
{
1969
    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1970
    {
1971
        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1972
        __base* __t = (__base*)&__tempbuf;
1973
        __f_->__move_to(__t);
1974
        __f_->destroy();
1975
        __f_ = nullptr;
1976
        __f.__f_->__move_to((__base*)&__buf_);
1977
        __f.__f_->destroy();
1978
        __f.__f_ = nullptr;
1979
        __f_ = (__base*)&__buf_;
1980
        __t->__move_to((__base*)&__f.__buf_);
1981
        __t->destroy();
1982
        __f.__f_ = (__base*)&__f.__buf_;
1983
    }
1984
    else if (__f_ == (__base*)&__buf_)
1985
    {
1986
        __f_->__move_to((__base*)&__f.__buf_);
1987
        __f_->destroy();
1988
        __f_ = __f.__f_;
1989
        __f.__f_ = (__base*)&__f.__buf_;
1990
    }
1991
    else if (__f.__f_ == (__base*)&__f.__buf_)
1992
    {
1993
        __f.__f_->__move_to((__base*)&__buf_);
1994
        __f.__f_->destroy();
1995
        __f.__f_ = __f_;
1996
        __f_ = (__base*)&__buf_;
1997
    }
1998
    else
1999
        _VSTD::swap(__f_, __f.__f_);
2000
}
2001

    
2002
template<class _Rp, class ..._ArgTypes>
2003
inline _LIBCPP_INLINE_VISIBILITY
2004
_Rp
2005
__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
2006
{
2007
    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
2008
}
2009

    
2010
template<class _Rp, class ..._ArgTypes>
2011
class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
2012
{
2013
public:
2014
    typedef _Rp result_type;
2015

    
2016
private:
2017
    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2018
    promise<result_type>                                __p_;
2019

    
2020
public:
2021
    // construction and destruction
2022
    _LIBCPP_INLINE_VISIBILITY
2023
    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2024
    template <class _Fp,
2025
              class = typename enable_if
2026
              <
2027
                  !is_same<
2028
                      typename decay<_Fp>::type, 
2029
                      packaged_task
2030
                      >::value
2031
                  >::type
2032
             >
2033
        _LIBCPP_INLINE_VISIBILITY
2034
        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2035
    template <class _Fp, class _Allocator,
2036
              class = typename enable_if
2037
              <
2038
                  !is_same<
2039
                      typename decay<_Fp>::type, 
2040
                      packaged_task
2041
                      >::value
2042
                  >::type
2043
              >
2044
        _LIBCPP_INLINE_VISIBILITY
2045
        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2046
             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2047
               __p_(allocator_arg, __a) {}
2048
    // ~packaged_task() = default;
2049

    
2050
    // no copy
2051
    packaged_task(const packaged_task&) = delete;
2052
    packaged_task& operator=(const packaged_task&) = delete;
2053

    
2054
    // move support
2055
    _LIBCPP_INLINE_VISIBILITY
2056
    packaged_task(packaged_task&& __other) _NOEXCEPT
2057
        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2058
    _LIBCPP_INLINE_VISIBILITY
2059
    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2060
    {
2061
        __f_ = _VSTD::move(__other.__f_);
2062
        __p_ = _VSTD::move(__other.__p_);
2063
        return *this;
2064
    }
2065
    _LIBCPP_INLINE_VISIBILITY
2066
    void swap(packaged_task& __other) _NOEXCEPT
2067
    {
2068
        __f_.swap(__other.__f_);
2069
        __p_.swap(__other.__p_);
2070
    }
2071

    
2072
    _LIBCPP_INLINE_VISIBILITY
2073
    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2074

    
2075
    // result retrieval
2076
    _LIBCPP_INLINE_VISIBILITY
2077
    future<result_type> get_future() {return __p_.get_future();}
2078

    
2079
    // execution
2080
    void operator()(_ArgTypes... __args);
2081
    void make_ready_at_thread_exit(_ArgTypes... __args);
2082

    
2083
    void reset();
2084
};
2085

    
2086
template<class _Rp, class ..._ArgTypes>
2087
void
2088
packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
2089
{
2090
#ifndef _LIBCPP_NO_EXCEPTIONS
2091
    if (__p_.__state_ == nullptr)
2092
        throw future_error(make_error_code(future_errc::no_state));
2093
    if (__p_.__state_->__has_value())
2094
        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2095
    try
2096
    {
2097
#endif  // _LIBCPP_NO_EXCEPTIONS
2098
        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2099
#ifndef _LIBCPP_NO_EXCEPTIONS
2100
    }
2101
    catch (...)
2102
    {
2103
        __p_.set_exception(current_exception());
2104
    }
2105
#endif  // _LIBCPP_NO_EXCEPTIONS
2106
}
2107

    
2108
template<class _Rp, class ..._ArgTypes>
2109
void
2110
packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2111
{
2112
#ifndef _LIBCPP_NO_EXCEPTIONS
2113
    if (__p_.__state_ == nullptr)
2114
        throw future_error(make_error_code(future_errc::no_state));
2115
    if (__p_.__state_->__has_value())
2116
        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2117
    try
2118
    {
2119
#endif  // _LIBCPP_NO_EXCEPTIONS
2120
        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2121
#ifndef _LIBCPP_NO_EXCEPTIONS
2122
    }
2123
    catch (...)
2124
    {
2125
        __p_.set_exception_at_thread_exit(current_exception());
2126
    }
2127
#endif  // _LIBCPP_NO_EXCEPTIONS
2128
}
2129

    
2130
template<class _Rp, class ..._ArgTypes>
2131
void
2132
packaged_task<_Rp(_ArgTypes...)>::reset()
2133
{
2134
#ifndef _LIBCPP_NO_EXCEPTIONS
2135
    if (!valid())
2136
        throw future_error(make_error_code(future_errc::no_state));
2137
#endif  // _LIBCPP_NO_EXCEPTIONS
2138
    __p_ = promise<result_type>();
2139
}
2140

    
2141
template<class ..._ArgTypes>
2142
class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
2143
{
2144
public:
2145
    typedef void result_type;
2146

    
2147
private:
2148
    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2149
    promise<result_type>                                __p_;
2150

    
2151
public:
2152
    // construction and destruction
2153
    _LIBCPP_INLINE_VISIBILITY
2154
    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2155
    template <class _Fp,
2156
              class = typename enable_if
2157
              <
2158
                  !is_same<
2159
                      typename decay<_Fp>::type, 
2160
                      packaged_task
2161
                      >::value
2162
                  >::type
2163
              >
2164
        _LIBCPP_INLINE_VISIBILITY
2165
        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2166
    template <class _Fp, class _Allocator,
2167
              class = typename enable_if
2168
              <
2169
                  !is_same<
2170
                      typename decay<_Fp>::type, 
2171
                      packaged_task
2172
                      >::value
2173
                  >::type
2174
              >    
2175
        _LIBCPP_INLINE_VISIBILITY
2176
        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2177
             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2178
               __p_(allocator_arg, __a) {}
2179
    // ~packaged_task() = default;
2180

    
2181
    // no copy
2182
    packaged_task(const packaged_task&) = delete;
2183
    packaged_task& operator=(const packaged_task&) = delete;
2184

    
2185
    // move support
2186
    _LIBCPP_INLINE_VISIBILITY
2187
    packaged_task(packaged_task&& __other) _NOEXCEPT
2188
        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2189
    _LIBCPP_INLINE_VISIBILITY
2190
    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2191
    {
2192
        __f_ = _VSTD::move(__other.__f_);
2193
        __p_ = _VSTD::move(__other.__p_);
2194
        return *this;
2195
    }
2196
    _LIBCPP_INLINE_VISIBILITY
2197
    void swap(packaged_task& __other) _NOEXCEPT
2198
    {
2199
        __f_.swap(__other.__f_);
2200
        __p_.swap(__other.__p_);
2201
    }
2202

    
2203
    _LIBCPP_INLINE_VISIBILITY
2204
    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2205

    
2206
    // result retrieval
2207
    _LIBCPP_INLINE_VISIBILITY
2208
    future<result_type> get_future() {return __p_.get_future();}
2209

    
2210
    // execution
2211
    void operator()(_ArgTypes... __args);
2212
    void make_ready_at_thread_exit(_ArgTypes... __args);
2213

    
2214
    void reset();
2215
};
2216

    
2217
template<class ..._ArgTypes>
2218
void
2219
packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2220
{
2221
#ifndef _LIBCPP_NO_EXCEPTIONS
2222
    if (__p_.__state_ == nullptr)
2223
        throw future_error(make_error_code(future_errc::no_state));
2224
    if (__p_.__state_->__has_value())
2225
        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2226
    try
2227
    {
2228
#endif  // _LIBCPP_NO_EXCEPTIONS
2229
        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2230
        __p_.set_value();
2231
#ifndef _LIBCPP_NO_EXCEPTIONS
2232
    }
2233
    catch (...)
2234
    {
2235
        __p_.set_exception(current_exception());
2236
    }
2237
#endif  // _LIBCPP_NO_EXCEPTIONS
2238
}
2239

    
2240
template<class ..._ArgTypes>
2241
void
2242
packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2243
{
2244
#ifndef _LIBCPP_NO_EXCEPTIONS
2245
    if (__p_.__state_ == nullptr)
2246
        throw future_error(make_error_code(future_errc::no_state));
2247
    if (__p_.__state_->__has_value())
2248
        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2249
    try
2250
    {
2251
#endif  // _LIBCPP_NO_EXCEPTIONS
2252
        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2253
        __p_.set_value_at_thread_exit();
2254
#ifndef _LIBCPP_NO_EXCEPTIONS
2255
    }
2256
    catch (...)
2257
    {
2258
        __p_.set_exception_at_thread_exit(current_exception());
2259
    }
2260
#endif  // _LIBCPP_NO_EXCEPTIONS
2261
}
2262

    
2263
template<class ..._ArgTypes>
2264
void
2265
packaged_task<void(_ArgTypes...)>::reset()
2266
{
2267
#ifndef _LIBCPP_NO_EXCEPTIONS
2268
    if (!valid())
2269
        throw future_error(make_error_code(future_errc::no_state));
2270
#endif  // _LIBCPP_NO_EXCEPTIONS
2271
    __p_ = promise<result_type>();
2272
}
2273

    
2274
template <class _Callable>
2275
inline _LIBCPP_INLINE_VISIBILITY
2276
void
2277
swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2278
{
2279
    __x.swap(__y);
2280
}
2281

    
2282
template <class _Callable, class _Alloc>
2283
struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
2284
    : public true_type {};
2285

    
2286
template <class _Rp, class _Fp>
2287
future<_Rp>
2288
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2289
__make_deferred_assoc_state(_Fp&& __f)
2290
#else
2291
__make_deferred_assoc_state(_Fp __f)
2292
#endif
2293
{
2294
    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2295
        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2296
    return future<_Rp>(__h.get());
2297
}
2298

    
2299
template <class _Rp, class _Fp>
2300
future<_Rp>
2301
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2302
__make_async_assoc_state(_Fp&& __f)
2303
#else
2304
__make_async_assoc_state(_Fp __f)
2305
#endif
2306
{
2307
    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2308
        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2309
    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2310
    return future<_Rp>(__h.get());
2311
}
2312

    
2313
template <class _Fp, class... _Args>
2314
class __async_func
2315
{
2316
    tuple<_Fp, _Args...> __f_;
2317

    
2318
public:
2319
    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2320

    
2321
    _LIBCPP_INLINE_VISIBILITY
2322
    explicit __async_func(_Fp&& __f, _Args&&... __args)
2323
        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2324

    
2325
    _LIBCPP_INLINE_VISIBILITY
2326
    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2327

    
2328
    _Rp operator()()
2329
    {
2330
        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2331
        return __execute(_Index());
2332
    }
2333
private:
2334
    template <size_t ..._Indices>
2335
    _Rp
2336
    __execute(__tuple_indices<_Indices...>)
2337
    {
2338
        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2339
    }
2340
};
2341

    
2342
inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
2343
{ return (int(__policy) & int(__value)) != 0; }
2344

    
2345
template <class _Fp, class... _Args>
2346
future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2347
async(launch __policy, _Fp&& __f, _Args&&... __args)
2348
{
2349
    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2350
    typedef typename _BF::_Rp _Rp;
2351

    
2352
#ifndef _LIBCPP_NO_EXCEPTIONS
2353
    try
2354
    {
2355
#endif
2356
        if (__does_policy_contain(__policy, launch::async))
2357
        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2358
                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
2359
#ifndef _LIBCPP_NO_EXCEPTIONS
2360
    }
2361
    catch ( ... ) { if (__policy == launch::async) throw ; }
2362
#endif
2363

    
2364
    if (__does_policy_contain(__policy, launch::deferred))
2365
        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2366
                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
2367
    return future<_Rp>{};
2368
}
2369

    
2370
template <class _Fp, class... _Args>
2371
inline _LIBCPP_INLINE_VISIBILITY
2372
future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2373
async(_Fp&& __f, _Args&&... __args)
2374
{
2375
    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2376
                                    _VSTD::forward<_Args>(__args)...);
2377
}
2378

    
2379
#endif  // _LIBCPP_HAS_NO_VARIADICS
2380

    
2381
// shared_future
2382

    
2383
template <class _Rp>
2384
class _LIBCPP_TYPE_VIS_ONLY shared_future
2385
{
2386
    __assoc_state<_Rp>* __state_;
2387

    
2388
public:
2389
    _LIBCPP_INLINE_VISIBILITY
2390
    shared_future() _NOEXCEPT : __state_(nullptr) {}
2391
    _LIBCPP_INLINE_VISIBILITY
2392
    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2393
        {if (__state_) __state_->__add_shared();}
2394
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2395
    _LIBCPP_INLINE_VISIBILITY
2396
    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2397
        {__f.__state_ = nullptr;}
2398
    _LIBCPP_INLINE_VISIBILITY
2399
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2400
        {__rhs.__state_ = nullptr;}
2401
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2402
    ~shared_future();
2403
    shared_future& operator=(const shared_future& __rhs);
2404
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2405
    _LIBCPP_INLINE_VISIBILITY
2406
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2407
        {
2408
            shared_future(std::move(__rhs)).swap(*this);
2409
            return *this;
2410
        }
2411
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2412

    
2413
    // retrieving the value
2414
    _LIBCPP_INLINE_VISIBILITY
2415
    const _Rp& get() const {return __state_->copy();}
2416

    
2417
    _LIBCPP_INLINE_VISIBILITY
2418
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2419

    
2420
    // functions to check state
2421
    _LIBCPP_INLINE_VISIBILITY
2422
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2423

    
2424
    _LIBCPP_INLINE_VISIBILITY
2425
    void wait() const {__state_->wait();}
2426
    template <class _Rep, class _Period>
2427
        _LIBCPP_INLINE_VISIBILITY
2428
        future_status
2429
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2430
            {return __state_->wait_for(__rel_time);}
2431
    template <class _Clock, class _Duration>
2432
        _LIBCPP_INLINE_VISIBILITY
2433
        future_status
2434
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2435
            {return __state_->wait_until(__abs_time);}
2436
};
2437

    
2438
template <class _Rp>
2439
shared_future<_Rp>::~shared_future()
2440
{
2441
    if (__state_)
2442
        __state_->__release_shared();
2443
}
2444

    
2445
template <class _Rp>
2446
shared_future<_Rp>&
2447
shared_future<_Rp>::operator=(const shared_future& __rhs)
2448
{
2449
    if (__rhs.__state_)
2450
        __rhs.__state_->__add_shared();
2451
    if (__state_)
2452
        __state_->__release_shared();
2453
    __state_ = __rhs.__state_;
2454
    return *this;
2455
}
2456

    
2457
template <class _Rp>
2458
class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
2459
{
2460
    __assoc_state<_Rp&>* __state_;
2461

    
2462
public:
2463
    _LIBCPP_INLINE_VISIBILITY
2464
    shared_future() _NOEXCEPT : __state_(nullptr) {}
2465
    _LIBCPP_INLINE_VISIBILITY
2466
    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2467
        {if (__state_) __state_->__add_shared();}
2468
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2469
    _LIBCPP_INLINE_VISIBILITY
2470
    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2471
        {__f.__state_ = nullptr;}
2472
    _LIBCPP_INLINE_VISIBILITY
2473
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2474
        {__rhs.__state_ = nullptr;}
2475
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2476
    ~shared_future();
2477
    shared_future& operator=(const shared_future& __rhs);
2478
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2479
    _LIBCPP_INLINE_VISIBILITY
2480
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2481
        {
2482
            shared_future(std::move(__rhs)).swap(*this);
2483
            return *this;
2484
        }
2485
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2486

    
2487
    // retrieving the value
2488
    _LIBCPP_INLINE_VISIBILITY
2489
    _Rp& get() const {return __state_->copy();}
2490

    
2491
    _LIBCPP_INLINE_VISIBILITY
2492
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2493

    
2494
    // functions to check state
2495
    _LIBCPP_INLINE_VISIBILITY
2496
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2497

    
2498
    _LIBCPP_INLINE_VISIBILITY
2499
    void wait() const {__state_->wait();}
2500
    template <class _Rep, class _Period>
2501
        _LIBCPP_INLINE_VISIBILITY
2502
        future_status
2503
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2504
            {return __state_->wait_for(__rel_time);}
2505
    template <class _Clock, class _Duration>
2506
        _LIBCPP_INLINE_VISIBILITY
2507
        future_status
2508
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2509
            {return __state_->wait_until(__abs_time);}
2510
};
2511

    
2512
template <class _Rp>
2513
shared_future<_Rp&>::~shared_future()
2514
{
2515
    if (__state_)
2516
        __state_->__release_shared();
2517
}
2518

    
2519
template <class _Rp>
2520
shared_future<_Rp&>&
2521
shared_future<_Rp&>::operator=(const shared_future& __rhs)
2522
{
2523
    if (__rhs.__state_)
2524
        __rhs.__state_->__add_shared();
2525
    if (__state_)
2526
        __state_->__release_shared();
2527
    __state_ = __rhs.__state_;
2528
    return *this;
2529
}
2530

    
2531
template <>
2532
class _LIBCPP_TYPE_VIS shared_future<void>
2533
{
2534
    __assoc_sub_state* __state_;
2535

    
2536
public:
2537
    _LIBCPP_INLINE_VISIBILITY
2538
    shared_future() _NOEXCEPT : __state_(nullptr) {}
2539
    _LIBCPP_INLINE_VISIBILITY
2540
    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2541
        {if (__state_) __state_->__add_shared();}
2542
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2543
    _LIBCPP_INLINE_VISIBILITY
2544
    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2545
        {__f.__state_ = nullptr;}
2546
    _LIBCPP_INLINE_VISIBILITY
2547
    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2548
        {__rhs.__state_ = nullptr;}
2549
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2550
    ~shared_future();
2551
    shared_future& operator=(const shared_future& __rhs);
2552
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2553
    _LIBCPP_INLINE_VISIBILITY
2554
    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2555
        {
2556
            shared_future(std::move(__rhs)).swap(*this);
2557
            return *this;
2558
        }
2559
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2560

    
2561
    // retrieving the value
2562
    _LIBCPP_INLINE_VISIBILITY
2563
    void get() const {__state_->copy();}
2564

    
2565
    _LIBCPP_INLINE_VISIBILITY
2566
    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2567

    
2568
    // functions to check state
2569
    _LIBCPP_INLINE_VISIBILITY
2570
    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2571

    
2572
    _LIBCPP_INLINE_VISIBILITY
2573
    void wait() const {__state_->wait();}
2574
    template <class _Rep, class _Period>
2575
        _LIBCPP_INLINE_VISIBILITY
2576
        future_status
2577
        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2578
            {return __state_->wait_for(__rel_time);}
2579
    template <class _Clock, class _Duration>
2580
        _LIBCPP_INLINE_VISIBILITY
2581
        future_status
2582
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2583
            {return __state_->wait_until(__abs_time);}
2584
};
2585

    
2586
template <class _Rp>
2587
inline _LIBCPP_INLINE_VISIBILITY
2588
void
2589
swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2590
{
2591
    __x.swap(__y);
2592
}
2593

    
2594
template <class _Rp>
2595
inline _LIBCPP_INLINE_VISIBILITY
2596
shared_future<_Rp>
2597
future<_Rp>::share()
2598
{
2599
    return shared_future<_Rp>(_VSTD::move(*this));
2600
}
2601

    
2602
template <class _Rp>
2603
inline _LIBCPP_INLINE_VISIBILITY
2604
shared_future<_Rp&>
2605
future<_Rp&>::share()
2606
{
2607
    return shared_future<_Rp&>(_VSTD::move(*this));
2608
}
2609

    
2610
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2611

    
2612
inline _LIBCPP_INLINE_VISIBILITY
2613
shared_future<void>
2614
future<void>::share()
2615
{
2616
    return shared_future<void>(_VSTD::move(*this));
2617
}
2618

    
2619
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2620

    
2621
_LIBCPP_END_NAMESPACE_STD
2622

    
2623
#endif // !_LIBCPP_HAS_NO_THREADS
2624

    
2625
#endif  // _LIBCPP_FUTURE