OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [future] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
//  -*- C++ -*-
2
 
3
// Copyright (C) 2009-2012 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 3, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// .
24
 
25
/** @file include/future
26
 *  This is a Standard C++ Library header.
27
 */
28
 
29
#ifndef _GLIBCXX_FUTURE
30
#define _GLIBCXX_FUTURE 1
31
 
32
#pragma GCC system_header
33
 
34
#if __cplusplus < 201103L
35
# include 
36
#else
37
 
38
#include 
39
#include 
40
#include 
41
#include 
42
#include 
43
#include 
44
#include 
45
#include 
46
#include 
47
#include 
48
#include 
49
 
50
namespace std _GLIBCXX_VISIBILITY(default)
51
{
52
_GLIBCXX_BEGIN_NAMESPACE_VERSION
53
 
54
  /**
55
   * @defgroup futures Futures
56
   * @ingroup concurrency
57
   *
58
   * Classes for futures support.
59
   * @{
60
   */
61
 
62
  /// Error code for futures
63
  enum class future_errc
64
  {
65
    future_already_retrieved = 1,
66
    promise_already_satisfied,
67
    no_state,
68
    broken_promise
69
  };
70
 
71
  /// Specialization.
72
  template<>
73
    struct is_error_code_enum : public true_type { };
74
 
75
  /// Points to a statically-allocated object derived from error_category.
76
  const error_category&
77
  future_category() noexcept;
78
 
79
  /// Overload for make_error_code.
80
  inline error_code
81
  make_error_code(future_errc __errc) noexcept
82
  { return error_code(static_cast(__errc), future_category()); }
83
 
84
  /// Overload for make_error_condition.
85
  inline error_condition
86
  make_error_condition(future_errc __errc) noexcept
87
  { return error_condition(static_cast(__errc), future_category()); }
88
 
89
  /**
90
   *  @brief Exception type thrown by futures.
91
   *  @ingroup exceptions
92
   */
93
  class future_error : public logic_error
94
  {
95
    error_code                  _M_code;
96
 
97
  public:
98
    explicit future_error(error_code __ec)
99
    : logic_error("std::future_error"), _M_code(__ec)
100
    { }
101
 
102
    virtual ~future_error() noexcept;
103
 
104
    virtual const char*
105
    what() const noexcept;
106
 
107
    const error_code&
108
    code() const noexcept { return _M_code; }
109
  };
110
 
111
  // Forward declarations.
112
  template
113
    class future;
114
 
115
  template
116
    class shared_future;
117
 
118
  template
119
    class packaged_task;
120
 
121
  template
122
    class promise;
123
 
124
  /// Launch code for futures
125
  enum class launch
126
  {
127
    async = 1,
128
    deferred = 2
129
  };
130
 
131
  constexpr launch operator&(launch __x, launch __y)
132
  {
133
    return static_cast(
134
        static_cast(__x) & static_cast(__y));
135
  }
136
 
137
  constexpr launch operator|(launch __x, launch __y)
138
  {
139
    return static_cast(
140
        static_cast(__x) | static_cast(__y));
141
  }
142
 
143
  constexpr launch operator^(launch __x, launch __y)
144
  {
145
    return static_cast(
146
        static_cast(__x) ^ static_cast(__y));
147
  }
148
 
149
  constexpr launch operator~(launch __x)
150
  { return static_cast(~static_cast(__x)); }
151
 
152
  inline launch& operator&=(launch& __x, launch __y)
153
  { return __x = __x & __y; }
154
 
155
  inline launch& operator|=(launch& __x, launch __y)
156
  { return __x = __x | __y; }
157
 
158
  inline launch& operator^=(launch& __x, launch __y)
159
  { return __x = __x ^ __y; }
160
 
161
  /// Status code for futures
162
  enum class future_status
163
  {
164
    ready,
165
    timeout,
166
    deferred
167
  };
168
 
169
  template
170
    future::type>
171
    async(launch __policy, _Fn&& __fn, _Args&&... __args);
172
 
173
  template
174
    struct __async_sfinae_helper
175
    {
176
      typedef future::type> type;
177
    };
178
 
179
  template
180
    struct __async_sfinae_helper
181
    { };
182
 
183
  template
184
    typename
185
    __async_sfinae_helper::type, _Fn, _Args...>::type
186
    async(_Fn&& __fn, _Args&&... __args);
187
 
188
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
189
  && (ATOMIC_INT_LOCK_FREE > 1)
190
 
191
  /// Base class and enclosing scope.
192
  struct __future_base
193
  {
194
    /// Base class for results.
195
    struct _Result_base
196
    {
197
      exception_ptr             _M_error;
198
 
199
      _Result_base(const _Result_base&) = delete;
200
      _Result_base& operator=(const _Result_base&) = delete;
201
 
202
      // _M_destroy() allows derived classes to control deallocation
203
      virtual void _M_destroy() = 0;
204
 
205
      struct _Deleter
206
      {
207
        void operator()(_Result_base* __fr) const { __fr->_M_destroy(); }
208
      };
209
 
210
    protected:
211
      _Result_base();
212
      virtual ~_Result_base();
213
    };
214
 
215
    /// Result.
216
    template
217
      struct _Result : _Result_base
218
      {
219
      private:
220
        typedef alignment_of<_Res>                            __a_of;
221
        typedef aligned_storage __align_storage;
222
        typedef typename __align_storage::type                  __align_type;
223
 
224
        __align_type            _M_storage;
225
        bool                    _M_initialized;
226
 
227
      public:
228
        _Result() noexcept : _M_initialized() { }
229
 
230
        ~_Result()
231
        {
232
          if (_M_initialized)
233
            _M_value().~_Res();
234
        }
235
 
236
        // Return lvalue, future will add const or rvalue-reference
237
        _Res&
238
        _M_value() noexcept { return *static_cast<_Res*>(_M_addr()); }
239
 
240
        void
241
        _M_set(const _Res& __res)
242
        {
243
          ::new (_M_addr()) _Res(__res);
244
          _M_initialized = true;
245
        }
246
 
247
        void
248
        _M_set(_Res&& __res)
249
        {
250
          ::new (_M_addr()) _Res(std::move(__res));
251
          _M_initialized = true;
252
        }
253
 
254
      private:
255
        void _M_destroy() { delete this; }
256
 
257
        void* _M_addr() noexcept { return static_cast(&_M_storage); }
258
    };
259
 
260
    /// A unique_ptr based on the instantiating type.
261
    template
262
      using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>;
263
 
264
    /// Result_alloc.
265
    template
266
      struct _Result_alloc final : _Result<_Res>, _Alloc
267
      {
268
        typedef typename allocator_traits<_Alloc>::template
269
          rebind_alloc<_Result_alloc> __allocator_type;
270
 
271
        explicit
272
        _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a)
273
        { }
274
 
275
      private:
276
        void _M_destroy()
277
        {
278
          typedef allocator_traits<__allocator_type> __traits;
279
          __allocator_type __a(*this);
280
          __traits::destroy(__a, this);
281
          __traits::deallocate(__a, this, 1);
282
        }
283
      };
284
 
285
    template
286
      static _Ptr<_Result_alloc<_Res, _Allocator>>
287
      _S_allocate_result(const _Allocator& __a)
288
      {
289
        typedef _Result_alloc<_Res, _Allocator>   __result_type;
290
        typedef allocator_traits
291
          __traits;
292
        typename __traits::allocator_type __a2(__a);
293
        __result_type* __p = __traits::allocate(__a2, 1);
294
        __try
295
        {
296
          __traits::construct(__a2, __p, __a);
297
        }
298
        __catch(...)
299
        {
300
          __traits::deallocate(__a2, __p, 1);
301
          __throw_exception_again;
302
        }
303
        return _Ptr<__result_type>(__p);
304
      }
305
 
306
 
307
    /// Base class for state between a promise and one or more
308
    /// associated futures.
309
    class _State_base
310
    {
311
      typedef _Ptr<_Result_base> _Ptr_type;
312
 
313
      _Ptr_type                 _M_result;
314
      mutex                     _M_mutex;
315
      condition_variable        _M_cond;
316
      atomic_flag               _M_retrieved;
317
      once_flag                 _M_once;
318
 
319
    public:
320
      _State_base() noexcept : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }
321
      _State_base(const _State_base&) = delete;
322
      _State_base& operator=(const _State_base&) = delete;
323
      virtual ~_State_base();
324
 
325
      _Result_base&
326
      wait()
327
      {
328
        _M_run_deferred();
329
        unique_lock __lock(_M_mutex);
330
        _M_cond.wait(__lock, [&] { return _M_ready(); });
331
        return *_M_result;
332
      }
333
 
334
      template
335
        future_status
336
        wait_for(const chrono::duration<_Rep, _Period>& __rel)
337
        {
338
          unique_lock __lock(_M_mutex);
339
          if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
340
            return future_status::ready;
341
          return future_status::timeout;
342
        }
343
 
344
      template
345
        future_status
346
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
347
        {
348
          unique_lock __lock(_M_mutex);
349
          if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
350
            return future_status::ready;
351
          return future_status::timeout;
352
        }
353
 
354
      void
355
      _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false)
356
      {
357
        bool __set = __ignore_failure;
358
        // all calls to this function are serialized,
359
        // side-effects of invoking __res only happen once
360
        call_once(_M_once, &_State_base::_M_do_set, this, ref(__res),
361
            ref(__set));
362
        if (!__set)
363
          __throw_future_error(int(future_errc::promise_already_satisfied));
364
      }
365
 
366
      void
367
      _M_break_promise(_Ptr_type __res)
368
      {
369
        if (static_cast(__res))
370
          {
371
            error_code __ec(make_error_code(future_errc::broken_promise));
372
            __res->_M_error = copy_exception(future_error(__ec));
373
            {
374
              lock_guard __lock(_M_mutex);
375
              _M_result.swap(__res);
376
            }
377
            _M_cond.notify_all();
378
          }
379
      }
380
 
381
      // Called when this object is passed to a future.
382
      void
383
      _M_set_retrieved_flag()
384
      {
385
        if (_M_retrieved.test_and_set())
386
          __throw_future_error(int(future_errc::future_already_retrieved));
387
      }
388
 
389
      template
390
        struct _Setter;
391
 
392
      // set lvalues
393
      template
394
        struct _Setter<_Res, _Arg&>
395
        {
396
          // check this is only used by promise::set_value(const R&)
397
          // or promise::set_value(R&)
398
          static_assert(is_same<_Res, _Arg&>::value  // promise
399
              || is_same::value,  // promise
400
              "Invalid specialisation");
401
 
402
          typename promise<_Res>::_Ptr_type operator()()
403
          {
404
            _State_base::_S_check(_M_promise->_M_future);
405
            _M_promise->_M_storage->_M_set(_M_arg);
406
            return std::move(_M_promise->_M_storage);
407
          }
408
          promise<_Res>*    _M_promise;
409
          _Arg&             _M_arg;
410
        };
411
 
412
      // set rvalues
413
      template
414
        struct _Setter<_Res, _Res&&>
415
        {
416
          typename promise<_Res>::_Ptr_type operator()()
417
          {
418
            _State_base::_S_check(_M_promise->_M_future);
419
            _M_promise->_M_storage->_M_set(std::move(_M_arg));
420
            return std::move(_M_promise->_M_storage);
421
          }
422
          promise<_Res>*    _M_promise;
423
          _Res&             _M_arg;
424
        };
425
 
426
      struct __exception_ptr_tag { };
427
 
428
      // set exceptions
429
      template
430
        struct _Setter<_Res, __exception_ptr_tag>
431
        {
432
          typename promise<_Res>::_Ptr_type operator()()
433
          {
434
            _State_base::_S_check(_M_promise->_M_future);
435
            _M_promise->_M_storage->_M_error = _M_ex;
436
            return std::move(_M_promise->_M_storage);
437
          }
438
 
439
          promise<_Res>*   _M_promise;
440
          exception_ptr&    _M_ex;
441
        };
442
 
443
      template
444
        static _Setter<_Res, _Arg&&>
445
        __setter(promise<_Res>* __prom, _Arg&& __arg)
446
        {
447
          return _Setter<_Res, _Arg&&>{ __prom, __arg };
448
        }
449
 
450
      template
451
        static _Setter<_Res, __exception_ptr_tag>
452
        __setter(exception_ptr& __ex, promise<_Res>* __prom)
453
        {
454
          return _Setter<_Res, __exception_ptr_tag>{ __prom, __ex };
455
        }
456
 
457
      static _Setter
458
      __setter(promise* __prom);
459
 
460
      template
461
        static bool
462
        _S_check(const shared_ptr<_Tp>& __p)
463
        {
464
          if (!static_cast(__p))
465
            __throw_future_error((int)future_errc::no_state);
466
        }
467
 
468
    private:
469
      void
470
      _M_do_set(function<_Ptr_type()>& __f, bool& __set)
471
      {
472
        _Ptr_type __res = __f();
473
        {
474
          lock_guard __lock(_M_mutex);
475
          _M_result.swap(__res);
476
        }
477
        _M_cond.notify_all();
478
        __set = true;
479
      }
480
 
481
      bool _M_ready() const noexcept { return static_cast(_M_result); }
482
 
483
      // Misnamed: waits for completion of async function.
484
      virtual void _M_run_deferred() { }
485
    };
486
 
487
    template
488
      class _Deferred_state;
489
 
490
    class _Async_state_common;
491
 
492
    template
493
      class _Async_state_impl;
494
 
495
    template
496
      class _Task_state;
497
 
498
    template
499
      static std::shared_ptr<_State_base>
500
      _S_make_deferred_state(_BoundFn&& __fn);
501
 
502
    template
503
      static std::shared_ptr<_State_base>
504
      _S_make_async_state(_BoundFn&& __fn);
505
 
506
    template
507
      struct _Task_setter;
508
 
509
    template
510
      class _Task_setter_helper
511
      {
512
        typedef typename remove_reference<_BoundFn>::type::result_type __res;
513
      public:
514
        typedef _Task_setter<_Res_ptr, __res> __type;
515
      };
516
 
517
    template
518
      static typename _Task_setter_helper<_Res_ptr, _BoundFn>::__type
519
      _S_task_setter(_Res_ptr& __ptr, _BoundFn&& __call)
520
      {
521
        typedef _Task_setter_helper<_Res_ptr, _BoundFn> __helper_type;
522
        typedef typename __helper_type::__type _Setter;
523
        return _Setter{ __ptr, std::ref(__call) };
524
      }
525
  };
526
 
527
  /// Partial specialization for reference types.
528
  template
529
    struct __future_base::_Result<_Res&> : __future_base::_Result_base
530
    {
531
      _Result() noexcept : _M_value_ptr() { }
532
 
533
      void _M_set(_Res& __res) noexcept { _M_value_ptr = &__res; }
534
 
535
      _Res& _M_get() noexcept { return *_M_value_ptr; }
536
 
537
    private:
538
      _Res*                     _M_value_ptr;
539
 
540
      void _M_destroy() { delete this; }
541
    };
542
 
543
  /// Explicit specialization for void.
544
  template<>
545
    struct __future_base::_Result : __future_base::_Result_base
546
    {
547
    private:
548
      void _M_destroy() { delete this; }
549
    };
550
 
551
 
552
  /// Common implementation for future and shared_future.
553
  template
554
    class __basic_future : public __future_base
555
    {
556
    protected:
557
      typedef shared_ptr<_State_base>                __state_type;
558
      typedef __future_base::_Result<_Res>&	__result_type;
559
 
560
    private:
561
      __state_type              _M_state;
562
 
563
    public:
564
      // Disable copying.
565
      __basic_future(const __basic_future&) = delete;
566
      __basic_future& operator=(const __basic_future&) = delete;
567
 
568
      bool
569
      valid() const noexcept { return static_cast(_M_state); }
570
 
571
      void
572
      wait() const
573
      {
574
        _State_base::_S_check(_M_state);
575
        _M_state->wait();
576
      }
577
 
578
      template
579
        future_status
580
        wait_for(const chrono::duration<_Rep, _Period>& __rel) const
581
        {
582
          _State_base::_S_check(_M_state);
583
          return _M_state->wait_for(__rel);
584
        }
585
 
586
      template
587
        future_status
588
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
589
        {
590
          _State_base::_S_check(_M_state);
591
          return _M_state->wait_until(__abs);
592
        }
593
 
594
    protected:
595
      /// Wait for the state to be ready and rethrow any stored exception
596
      __result_type
597
      _M_get_result()
598
      {
599
        _State_base::_S_check(_M_state);
600
        _Result_base& __res = _M_state->wait();
601
        if (!(__res._M_error == 0))
602
          rethrow_exception(__res._M_error);
603
        return static_cast<__result_type>(__res);
604
      }
605
 
606
      void _M_swap(__basic_future& __that) noexcept
607
      {
608
        _M_state.swap(__that._M_state);
609
      }
610
 
611
      // Construction of a future by promise::get_future()
612
      explicit
613
      __basic_future(const __state_type& __state) : _M_state(__state)
614
      {
615
        _State_base::_S_check(_M_state);
616
        _M_state->_M_set_retrieved_flag();
617
      }
618
 
619
      // Copy construction from a shared_future
620
      explicit
621
      __basic_future(const shared_future<_Res>&) noexcept;
622
 
623
      // Move construction from a shared_future
624
      explicit
625
      __basic_future(shared_future<_Res>&&) noexcept;
626
 
627
      // Move construction from a future
628
      explicit
629
      __basic_future(future<_Res>&&) noexcept;
630
 
631
      constexpr __basic_future() noexcept : _M_state() { }
632
 
633
      struct _Reset
634
      {
635
        explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { }
636
        ~_Reset() { _M_fut._M_state.reset(); }
637
        __basic_future& _M_fut;
638
      };
639
    };
640
 
641
 
642
  /// Primary template for future.
643
  template
644
    class future : public __basic_future<_Res>
645
    {
646
      friend class promise<_Res>;
647
      template friend class packaged_task;
648
      template
649
        friend future::type>
650
        async(launch, _Fn&&, _Args&&...);
651
 
652
      typedef __basic_future<_Res> _Base_type;
653
      typedef typename _Base_type::__state_type __state_type;
654
 
655
      explicit
656
      future(const __state_type& __state) : _Base_type(__state) { }
657
 
658
    public:
659
      constexpr future() noexcept : _Base_type() { }
660
 
661
      /// Move constructor
662
      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
663
 
664
      // Disable copying
665
      future(const future&) = delete;
666
      future& operator=(const future&) = delete;
667
 
668
      future& operator=(future&& __fut) noexcept
669
      {
670
        future(std::move(__fut))._M_swap(*this);
671
        return *this;
672
      }
673
 
674
      /// Retrieving the value
675
      _Res
676
      get()
677
      {
678
        typename _Base_type::_Reset __reset(*this);
679
        return std::move(this->_M_get_result()._M_value());
680
      }
681
 
682
      shared_future<_Res> share();
683
    };
684
 
685
  /// Partial specialization for future
686
  template
687
    class future<_Res&> : public __basic_future<_Res&>
688
    {
689
      friend class promise<_Res&>;
690
      template friend class packaged_task;
691
      template
692
        friend future::type>
693
        async(launch, _Fn&&, _Args&&...);
694
 
695
      typedef __basic_future<_Res&> _Base_type;
696
      typedef typename _Base_type::__state_type __state_type;
697
 
698
      explicit
699
      future(const __state_type& __state) : _Base_type(__state) { }
700
 
701
    public:
702
      constexpr future() noexcept : _Base_type() { }
703
 
704
      /// Move constructor
705
      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
706
 
707
      // Disable copying
708
      future(const future&) = delete;
709
      future& operator=(const future&) = delete;
710
 
711
      future& operator=(future&& __fut) noexcept
712
      {
713
        future(std::move(__fut))._M_swap(*this);
714
        return *this;
715
      }
716
 
717
      /// Retrieving the value
718
      _Res&
719
      get()
720
      {
721
        typename _Base_type::_Reset __reset(*this);
722
        return this->_M_get_result()._M_get();
723
      }
724
 
725
      shared_future<_Res&> share();
726
    };
727
 
728
  /// Explicit specialization for future
729
  template<>
730
    class future : public __basic_future
731
    {
732
      friend class promise;
733
      template friend class packaged_task;
734
      template
735
        friend future::type>
736
        async(launch, _Fn&&, _Args&&...);
737
 
738
      typedef __basic_future _Base_type;
739
      typedef typename _Base_type::__state_type __state_type;
740
 
741
      explicit
742
      future(const __state_type& __state) : _Base_type(__state) { }
743
 
744
    public:
745
      constexpr future() noexcept : _Base_type() { }
746
 
747
      /// Move constructor
748
      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
749
 
750
      // Disable copying
751
      future(const future&) = delete;
752
      future& operator=(const future&) = delete;
753
 
754
      future& operator=(future&& __fut) noexcept
755
      {
756
        future(std::move(__fut))._M_swap(*this);
757
        return *this;
758
      }
759
 
760
      /// Retrieving the value
761
      void
762
      get()
763
      {
764
        typename _Base_type::_Reset __reset(*this);
765
        this->_M_get_result();
766
      }
767
 
768
      shared_future share();
769
    };
770
 
771
 
772
  /// Primary template for shared_future.
773
  template
774
    class shared_future : public __basic_future<_Res>
775
    {
776
      typedef __basic_future<_Res> _Base_type;
777
 
778
    public:
779
      constexpr shared_future() noexcept : _Base_type() { }
780
 
781
      /// Copy constructor
782
      shared_future(const shared_future& __sf) : _Base_type(__sf) { }
783
 
784
      /// Construct from a future rvalue
785
      shared_future(future<_Res>&& __uf) noexcept
786
      : _Base_type(std::move(__uf))
787
      { }
788
 
789
      /// Construct from a shared_future rvalue
790
      shared_future(shared_future&& __sf) noexcept
791
      : _Base_type(std::move(__sf))
792
      { }
793
 
794
      shared_future& operator=(const shared_future& __sf)
795
      {
796
        shared_future(__sf)._M_swap(*this);
797
        return *this;
798
      }
799
 
800
      shared_future& operator=(shared_future&& __sf) noexcept
801
      {
802
        shared_future(std::move(__sf))._M_swap(*this);
803
        return *this;
804
      }
805
 
806
      /// Retrieving the value
807
      const _Res&
808
      get()
809
      {
810
        typename _Base_type::__result_type __r = this->_M_get_result();
811
        _Res& __rs(__r._M_value());
812
        return __rs;
813
      }
814
    };
815
 
816
  /// Partial specialization for shared_future
817
  template
818
    class shared_future<_Res&> : public __basic_future<_Res&>
819
    {
820
      typedef __basic_future<_Res&>           _Base_type;
821
 
822
    public:
823
      constexpr shared_future() noexcept : _Base_type() { }
824
 
825
      /// Copy constructor
826
      shared_future(const shared_future& __sf) : _Base_type(__sf) { }
827
 
828
      /// Construct from a future rvalue
829
      shared_future(future<_Res&>&& __uf) noexcept
830
      : _Base_type(std::move(__uf))
831
      { }
832
 
833
      /// Construct from a shared_future rvalue
834
      shared_future(shared_future&& __sf) noexcept
835
      : _Base_type(std::move(__sf))
836
      { }
837
 
838
      shared_future& operator=(const shared_future& __sf)
839
      {
840
        shared_future(__sf)._M_swap(*this);
841
        return *this;
842
      }
843
 
844
      shared_future& operator=(shared_future&& __sf) noexcept
845
      {
846
        shared_future(std::move(__sf))._M_swap(*this);
847
        return *this;
848
      }
849
 
850
      /// Retrieving the value
851
      _Res&
852
      get() { return this->_M_get_result()._M_get(); }
853
    };
854
 
855
  /// Explicit specialization for shared_future
856
  template<>
857
    class shared_future : public __basic_future
858
    {
859
      typedef __basic_future _Base_type;
860
 
861
    public:
862
      constexpr shared_future() noexcept : _Base_type() { }
863
 
864
      /// Copy constructor
865
      shared_future(const shared_future& __sf) : _Base_type(__sf) { }
866
 
867
      /// Construct from a future rvalue
868
      shared_future(future&& __uf) noexcept
869
      : _Base_type(std::move(__uf))
870
      { }
871
 
872
      /// Construct from a shared_future rvalue
873
      shared_future(shared_future&& __sf) noexcept
874
      : _Base_type(std::move(__sf))
875
      { }
876
 
877
      shared_future& operator=(const shared_future& __sf)
878
      {
879
        shared_future(__sf)._M_swap(*this);
880
        return *this;
881
      }
882
 
883
      shared_future& operator=(shared_future&& __sf) noexcept
884
      {
885
        shared_future(std::move(__sf))._M_swap(*this);
886
        return *this;
887
      }
888
 
889
      // Retrieving the value
890
      void
891
      get() { this->_M_get_result(); }
892
    };
893
 
894
  // Now we can define the protected __basic_future constructors.
895
  template
896
    inline __basic_future<_Res>::
897
    __basic_future(const shared_future<_Res>& __sf) noexcept
898
    : _M_state(__sf._M_state)
899
    { }
900
 
901
  template
902
    inline __basic_future<_Res>::
903
    __basic_future(shared_future<_Res>&& __sf) noexcept
904
    : _M_state(std::move(__sf._M_state))
905
    { }
906
 
907
  template
908
    inline __basic_future<_Res>::
909
    __basic_future(future<_Res>&& __uf) noexcept
910
    : _M_state(std::move(__uf._M_state))
911
    { }
912
 
913
  template
914
    inline shared_future<_Res>
915
    future<_Res>::share()
916
    { return shared_future<_Res>(std::move(*this)); }
917
 
918
  template
919
    inline shared_future<_Res&>
920
    future<_Res&>::share()
921
    { return shared_future<_Res&>(std::move(*this)); }
922
 
923
  inline shared_future
924
  future::share()
925
  { return shared_future(std::move(*this)); }
926
 
927
  /// Primary template for promise
928
  template
929
    class promise
930
    {
931
      typedef __future_base::_State_base        _State;
932
      typedef __future_base::_Result<_Res>    _Res_type;
933
      typedef __future_base::_Ptr<_Res_type>       _Ptr_type;
934
      template friend class _State::_Setter;
935
 
936
      shared_ptr<_State>                        _M_future;
937
      _Ptr_type                                 _M_storage;
938
 
939
    public:
940
      promise()
941
      : _M_future(std::make_shared<_State>()),
942
        _M_storage(new _Res_type())
943
      { }
944
 
945
      promise(promise&& __rhs) noexcept
946
      : _M_future(std::move(__rhs._M_future)),
947
        _M_storage(std::move(__rhs._M_storage))
948
      { }
949
 
950
      template
951
        promise(allocator_arg_t, const _Allocator& __a)
952
        : _M_future(std::allocate_shared<_State>(__a)),
953
          _M_storage(__future_base::_S_allocate_result<_Res>(__a))
954
        { }
955
 
956
      template
957
        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
958
        : _M_future(std::move(__rhs._M_future)),
959
          _M_storage(std::move(__rhs._M_storage))
960
        { }
961
 
962
      promise(const promise&) = delete;
963
 
964
      ~promise()
965
      {
966
        if (static_cast(_M_future) && !_M_future.unique())
967
          _M_future->_M_break_promise(std::move(_M_storage));
968
      }
969
 
970
      // Assignment
971
      promise&
972
      operator=(promise&& __rhs) noexcept
973
      {
974
        promise(std::move(__rhs)).swap(*this);
975
        return *this;
976
      }
977
 
978
      promise& operator=(const promise&) = delete;
979
 
980
      void
981
      swap(promise& __rhs) noexcept
982
      {
983
        _M_future.swap(__rhs._M_future);
984
        _M_storage.swap(__rhs._M_storage);
985
      }
986
 
987
      // Retrieving the result
988
      future<_Res>
989
      get_future()
990
      { return future<_Res>(_M_future); }
991
 
992
      // Setting the result
993
      void
994
      set_value(const _Res& __r)
995
      {
996
        auto __setter = _State::__setter(this, __r);
997
        _M_future->_M_set_result(std::move(__setter));
998
      }
999
 
1000
      void
1001
      set_value(_Res&& __r)
1002
      {
1003
        auto __setter = _State::__setter(this, std::move(__r));
1004
        _M_future->_M_set_result(std::move(__setter));
1005
      }
1006
 
1007
      void
1008
      set_exception(exception_ptr __p)
1009
      {
1010
        auto __setter = _State::__setter(__p, this);
1011
        _M_future->_M_set_result(std::move(__setter));
1012
      }
1013
    };
1014
 
1015
  template
1016
    inline void
1017
    swap(promise<_Res>& __x, promise<_Res>& __y) noexcept
1018
    { __x.swap(__y); }
1019
 
1020
  template
1021
    struct uses_allocator, _Alloc>
1022
    : public true_type { };
1023
 
1024
 
1025
  /// Partial specialization for promise
1026
  template
1027
    class promise<_Res&>
1028
    {
1029
      typedef __future_base::_State_base        _State;
1030
      typedef __future_base::_Result<_Res&>    _Res_type;
1031
      typedef __future_base::_Ptr<_Res_type>       _Ptr_type;
1032
      template friend class _State::_Setter;
1033
 
1034
      shared_ptr<_State>                        _M_future;
1035
      _Ptr_type                                 _M_storage;
1036
 
1037
    public:
1038
      promise()
1039
      : _M_future(std::make_shared<_State>()),
1040
        _M_storage(new _Res_type())
1041
      { }
1042
 
1043
      promise(promise&& __rhs) noexcept
1044
      : _M_future(std::move(__rhs._M_future)),
1045
        _M_storage(std::move(__rhs._M_storage))
1046
      { }
1047
 
1048
      template
1049
        promise(allocator_arg_t, const _Allocator& __a)
1050
        : _M_future(std::allocate_shared<_State>(__a)),
1051
          _M_storage(__future_base::_S_allocate_result<_Res&>(__a))
1052
        { }
1053
 
1054
      template
1055
        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1056
        : _M_future(std::move(__rhs._M_future)),
1057
          _M_storage(std::move(__rhs._M_storage))
1058
        { }
1059
 
1060
      promise(const promise&) = delete;
1061
 
1062
      ~promise()
1063
      {
1064
        if (static_cast(_M_future) && !_M_future.unique())
1065
          _M_future->_M_break_promise(std::move(_M_storage));
1066
      }
1067
 
1068
      // Assignment
1069
      promise&
1070
      operator=(promise&& __rhs) noexcept
1071
      {
1072
        promise(std::move(__rhs)).swap(*this);
1073
        return *this;
1074
      }
1075
 
1076
      promise& operator=(const promise&) = delete;
1077
 
1078
      void
1079
      swap(promise& __rhs) noexcept
1080
      {
1081
        _M_future.swap(__rhs._M_future);
1082
        _M_storage.swap(__rhs._M_storage);
1083
      }
1084
 
1085
      // Retrieving the result
1086
      future<_Res&>
1087
      get_future()
1088
      { return future<_Res&>(_M_future); }
1089
 
1090
      // Setting the result
1091
      void
1092
      set_value(_Res& __r)
1093
      {
1094
        auto __setter = _State::__setter(this, __r);
1095
        _M_future->_M_set_result(std::move(__setter));
1096
      }
1097
 
1098
      void
1099
      set_exception(exception_ptr __p)
1100
      {
1101
        auto __setter = _State::__setter(__p, this);
1102
        _M_future->_M_set_result(std::move(__setter));
1103
      }
1104
    };
1105
 
1106
  /// Explicit specialization for promise
1107
  template<>
1108
    class promise
1109
    {
1110
      typedef __future_base::_State_base        _State;
1111
      typedef __future_base::_Result    _Res_type;
1112
      typedef __future_base::_Ptr<_Res_type>       _Ptr_type;
1113
      template friend class _State::_Setter;
1114
 
1115
      shared_ptr<_State>                        _M_future;
1116
      _Ptr_type                                 _M_storage;
1117
 
1118
    public:
1119
      promise()
1120
      : _M_future(std::make_shared<_State>()),
1121
        _M_storage(new _Res_type())
1122
      { }
1123
 
1124
      promise(promise&& __rhs) noexcept
1125
      : _M_future(std::move(__rhs._M_future)),
1126
        _M_storage(std::move(__rhs._M_storage))
1127
      { }
1128
 
1129
      template
1130
        promise(allocator_arg_t, const _Allocator& __a)
1131
        : _M_future(std::allocate_shared<_State>(__a)),
1132
          _M_storage(__future_base::_S_allocate_result(__a))
1133
        { }
1134
 
1135
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1136
      // 2095.  missing constructors needed for uses-allocator construction
1137
      template
1138
        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1139
        : _M_future(std::move(__rhs._M_future)),
1140
          _M_storage(std::move(__rhs._M_storage))
1141
        { }
1142
 
1143
      promise(const promise&) = delete;
1144
 
1145
      ~promise()
1146
      {
1147
        if (static_cast(_M_future) && !_M_future.unique())
1148
          _M_future->_M_break_promise(std::move(_M_storage));
1149
      }
1150
 
1151
      // Assignment
1152
      promise&
1153
      operator=(promise&& __rhs) noexcept
1154
      {
1155
        promise(std::move(__rhs)).swap(*this);
1156
        return *this;
1157
      }
1158
 
1159
      promise& operator=(const promise&) = delete;
1160
 
1161
      void
1162
      swap(promise& __rhs) noexcept
1163
      {
1164
        _M_future.swap(__rhs._M_future);
1165
        _M_storage.swap(__rhs._M_storage);
1166
      }
1167
 
1168
      // Retrieving the result
1169
      future
1170
      get_future()
1171
      { return future(_M_future); }
1172
 
1173
      // Setting the result
1174
      void set_value();
1175
 
1176
      void
1177
      set_exception(exception_ptr __p)
1178
      {
1179
        auto __setter = _State::__setter(__p, this);
1180
        _M_future->_M_set_result(std::move(__setter));
1181
      }
1182
    };
1183
 
1184
  // set void
1185
  template<>
1186
    struct __future_base::_State_base::_Setter
1187
    {
1188
      promise::_Ptr_type operator()()
1189
      {
1190
        _State_base::_S_check(_M_promise->_M_future);
1191
        return std::move(_M_promise->_M_storage);
1192
      }
1193
 
1194
      promise*    _M_promise;
1195
    };
1196
 
1197
  inline __future_base::_State_base::_Setter
1198
  __future_base::_State_base::__setter(promise* __prom)
1199
  {
1200
    return _Setter{ __prom };
1201
  }
1202
 
1203
  inline void
1204
  promise::set_value()
1205
  {
1206
    auto __setter = _State::__setter(this);
1207
    _M_future->_M_set_result(std::move(__setter));
1208
  }
1209
 
1210
 
1211
  template
1212
    struct __future_base::_Task_setter
1213
    {
1214
      _Ptr_type operator()()
1215
      {
1216
        __try
1217
          {
1218
            _M_result->_M_set(_M_fn());
1219
          }
1220
        __catch(...)
1221
          {
1222
            _M_result->_M_error = current_exception();
1223
          }
1224
        return std::move(_M_result);
1225
      }
1226
      _Ptr_type&                _M_result;
1227
      std::function<_Res()>     _M_fn;
1228
    };
1229
 
1230
  template
1231
    struct __future_base::_Task_setter<_Ptr_type, void>
1232
    {
1233
      _Ptr_type operator()()
1234
      {
1235
        __try
1236
          {
1237
            _M_fn();
1238
          }
1239
        __catch(...)
1240
          {
1241
            _M_result->_M_error = current_exception();
1242
          }
1243
        return std::move(_M_result);
1244
      }
1245
      _Ptr_type&                _M_result;
1246
      std::function     _M_fn;
1247
    };
1248
 
1249
  template
1250
    struct __future_base::_Task_state<_Res(_Args...)> final
1251
    : __future_base::_State_base
1252
    {
1253
      typedef _Res _Res_type;
1254
 
1255
      _Task_state(std::function<_Res(_Args...)> __task)
1256
      : _M_result(new _Result<_Res>()), _M_task(std::move(__task))
1257
      { }
1258
 
1259
      template
1260
        _Task_state(_Func&& __task, const _Alloc& __a)
1261
        : _M_result(_S_allocate_result<_Res>(__a)),
1262
          _M_task(allocator_arg, __a, std::move(__task))
1263
        { }
1264
 
1265
      void
1266
      _M_run(_Args... __args)
1267
      {
1268
        // bound arguments decay so wrap lvalue references
1269
        auto __boundfn = std::__bind_simple(std::ref(_M_task),
1270
            _S_maybe_wrap_ref(std::forward<_Args>(__args))...);
1271
        auto __setter = _S_task_setter(_M_result, std::move(__boundfn));
1272
        _M_set_result(std::move(__setter));
1273
      }
1274
 
1275
      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1276
      _Ptr_type _M_result;
1277
      std::function<_Res(_Args...)> _M_task;
1278
 
1279
      template
1280
        static reference_wrapper<_Tp>
1281
        _S_maybe_wrap_ref(_Tp& __t)
1282
        { return std::ref(__t); }
1283
 
1284
      template
1285
        static typename enable_if::value,
1286
                        _Tp>::type&&
1287
        _S_maybe_wrap_ref(_Tp&& __t)
1288
        { return std::forward<_Tp>(__t); }
1289
    };
1290
 
1291
  template
1292
           = is_same<_Task, typename decay<_Fn>::type>::value>
1293
    struct __constrain_pkgdtask
1294
    { typedef void __type; };
1295
 
1296
  template
1297
    struct __constrain_pkgdtask<_Task, _Fn, true>
1298
    { };
1299
 
1300
  /// packaged_task
1301
  template
1302
    class packaged_task<_Res(_ArgTypes...)>
1303
    {
1304
      typedef __future_base::_Task_state<_Res(_ArgTypes...)>  _State_type;
1305
      shared_ptr<_State_type>                   _M_state;
1306
 
1307
    public:
1308
      // Construction and destruction
1309
      packaged_task() noexcept { }
1310
 
1311
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1312
      // 2095.  missing constructors needed for uses-allocator construction
1313
      template
1314
        explicit
1315
        packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
1316
        { }
1317
 
1318
      template
1319
               __constrain_pkgdtask::__type>
1320
        explicit
1321
        packaged_task(_Fn&& __fn)
1322
        : _M_state(std::make_shared<_State_type>(std::forward<_Fn>(__fn)))
1323
        { }
1324
 
1325
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1326
      // 2097.  packaged_task constructors should be constrained
1327
      template
1328
               __constrain_pkgdtask::__type>
1329
        explicit
1330
        packaged_task(allocator_arg_t, const _Allocator& __a, _Fn&& __fn)
1331
        : _M_state(std::allocate_shared<_State_type>(__a,
1332
                                                     std::forward<_Fn>(__fn)))
1333
        { }
1334
 
1335
      ~packaged_task()
1336
      {
1337
        if (static_cast(_M_state) && !_M_state.unique())
1338
          _M_state->_M_break_promise(std::move(_M_state->_M_result));
1339
      }
1340
 
1341
      // No copy
1342
      packaged_task(const packaged_task&) = delete;
1343
      packaged_task& operator=(const packaged_task&) = delete;
1344
 
1345
      template
1346
        explicit
1347
        packaged_task(allocator_arg_t, const _Allocator&,
1348
                      const packaged_task&) = delete;
1349
 
1350
      // Move support
1351
      packaged_task(packaged_task&& __other) noexcept
1352
      { this->swap(__other); }
1353
 
1354
      template
1355
        explicit
1356
        packaged_task(allocator_arg_t, const _Allocator&,
1357
                      packaged_task&& __other) noexcept
1358
        { this->swap(__other); }
1359
 
1360
      packaged_task& operator=(packaged_task&& __other) noexcept
1361
      {
1362
        packaged_task(std::move(__other)).swap(*this);
1363
        return *this;
1364
      }
1365
 
1366
      void
1367
      swap(packaged_task& __other) noexcept
1368
      { _M_state.swap(__other._M_state); }
1369
 
1370
      bool
1371
      valid() const noexcept
1372
      { return static_cast(_M_state); }
1373
 
1374
      // Result retrieval
1375
      future<_Res>
1376
      get_future()
1377
      { return future<_Res>(_M_state); }
1378
 
1379
      // Execution
1380
      void
1381
      operator()(_ArgTypes... __args)
1382
      {
1383
        __future_base::_State_base::_S_check(_M_state);
1384
        _M_state->_M_run(std::forward<_ArgTypes>(__args)...);
1385
      }
1386
 
1387
      void
1388
      reset()
1389
      {
1390
        __future_base::_State_base::_S_check(_M_state);
1391
        packaged_task(std::move(_M_state->_M_task)).swap(*this);
1392
      }
1393
    };
1394
 
1395
  /// swap
1396
  template
1397
    inline void
1398
    swap(packaged_task<_Res(_ArgTypes...)>& __x,
1399
         packaged_task<_Res(_ArgTypes...)>& __y) noexcept
1400
    { __x.swap(__y); }
1401
 
1402
  template
1403
    struct uses_allocator, _Alloc>
1404
    : public true_type { };
1405
 
1406
 
1407
  template
1408
    class __future_base::_Deferred_state final
1409
    : public __future_base::_State_base
1410
    {
1411
    public:
1412
      explicit
1413
      _Deferred_state(_BoundFn&& __fn)
1414
      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
1415
      { }
1416
 
1417
    private:
1418
      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1419
      _Ptr_type _M_result;
1420
      _BoundFn _M_fn;
1421
 
1422
      virtual void
1423
      _M_run_deferred()
1424
      {
1425
        // safe to call multiple times so ignore failure
1426
        _M_set_result(_S_task_setter(_M_result, _M_fn), true);
1427
      }
1428
    };
1429
 
1430
  class __future_base::_Async_state_common : public __future_base::_State_base
1431
  {
1432
  protected:
1433
#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
1434
    ~_Async_state_common();
1435
#else
1436
    ~_Async_state_common() = default;
1437
#endif
1438
 
1439
    // Allow non-timed waiting functions to block until the thread completes,
1440
    // as if joined.
1441
    virtual void _M_run_deferred() { _M_join(); }
1442
 
1443
    void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); }
1444
 
1445
    thread _M_thread;
1446
    once_flag _M_once;
1447
  };
1448
 
1449
  template
1450
    class __future_base::_Async_state_impl final
1451
    : public __future_base::_Async_state_common
1452
    {
1453
    public:
1454
      explicit
1455
      _Async_state_impl(_BoundFn&& __fn)
1456
      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
1457
      {
1458
        _M_thread = std::thread{ [this] {
1459
          _M_set_result(_S_task_setter(_M_result, _M_fn));
1460
        } };
1461
      }
1462
 
1463
      ~_Async_state_impl() { _M_join(); }
1464
 
1465
    private:
1466
      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1467
      _Ptr_type _M_result;
1468
      _BoundFn _M_fn;
1469
    };
1470
 
1471
  template
1472
    inline std::shared_ptr<__future_base::_State_base>
1473
    __future_base::_S_make_deferred_state(_BoundFn&& __fn)
1474
    {
1475
      typedef typename remove_reference<_BoundFn>::type __fn_type;
1476
      typedef _Deferred_state<__fn_type> __state_type;
1477
      return std::make_shared<__state_type>(std::move(__fn));
1478
    }
1479
 
1480
  template
1481
    inline std::shared_ptr<__future_base::_State_base>
1482
    __future_base::_S_make_async_state(_BoundFn&& __fn)
1483
    {
1484
      typedef typename remove_reference<_BoundFn>::type __fn_type;
1485
      typedef _Async_state_impl<__fn_type> __state_type;
1486
      return std::make_shared<__state_type>(std::move(__fn));
1487
    }
1488
 
1489
 
1490
  /// async
1491
  template
1492
    future::type>
1493
    async(launch __policy, _Fn&& __fn, _Args&&... __args)
1494
    {
1495
      typedef typename result_of<_Fn(_Args...)>::type result_type;
1496
      std::shared_ptr<__future_base::_State_base> __state;
1497
      if ((__policy & (launch::async|launch::deferred)) == launch::async)
1498
        {
1499
          __state = __future_base::_S_make_async_state(std::__bind_simple(
1500
              std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
1501
        }
1502
      else
1503
        {
1504
          __state = __future_base::_S_make_deferred_state(std::__bind_simple(
1505
              std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
1506
        }
1507
      return future(__state);
1508
    }
1509
 
1510
  /// async, potential overload
1511
  template
1512
    inline typename
1513
    __async_sfinae_helper::type, _Fn, _Args...>::type
1514
    async(_Fn&& __fn, _Args&&... __args)
1515
    {
1516
      return async(launch::async|launch::deferred, std::forward<_Fn>(__fn),
1517
                   std::forward<_Args>(__args)...);
1518
    }
1519
 
1520
#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
1521
       // && ATOMIC_INT_LOCK_FREE
1522
 
1523
  // @} group futures
1524
_GLIBCXX_END_NAMESPACE_VERSION
1525
} // namespace
1526
 
1527
#endif // C++11
1528
 
1529
#endif // _GLIBCXX_FUTURE

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.