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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libstdc++-v3/] [include/] [std/] [future] - Blame information for rev 826

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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