~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to system/include/libcxx/future

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

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