OSDN Git Service

2009-08-10 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / future
1 // <future> -*- C++ -*-
2
3 // Copyright (C) 2009 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 // <http://www.gnu.org/licenses/>.
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 <c++0x_warning.h>
36 #else
37
38 #include <functional>
39 #include <memory>
40 #include <mutex>
41 #include <condition_variable>
42 #include <system_error>
43 #include <exception>
44 #include <cstdatomic>
45
46 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
47   && defined(_GLIBCXX_ATOMIC_BUILTINS_4)
48
49 namespace std
50 {
51   /**
52    * @defgroup futures Futures
53    * @ingroup concurrency
54    *
55    * Classes for futures support.
56    * @{
57    */
58
59   /// Error code for futures
60   enum class future_errc
61   { broken_promise, future_already_retrieved, promise_already_satisfied };
62
63   // TODO: requires concepts
64   // concept_map ErrorCodeEnum<future_errc> { }
65   template<>
66     struct is_error_code_enum<future_errc> : public true_type { };
67
68   /// Points to a statically-allocated object derived from error_category.
69   extern const error_category* const future_category;
70
71   // TODO: requires constexpr
72   inline error_code make_error_code(future_errc __errc)
73   { return error_code(static_cast<int>(__errc), *future_category); }
74
75   // TODO: requires constexpr
76   inline error_condition make_error_condition(future_errc __errc)
77   { return error_condition(static_cast<int>(__errc), *future_category); }
78
79   /**
80    *  @brief Exception type thrown by futures.
81    *  @ingroup exceptions
82    */
83   class future_error : public logic_error
84   {
85     error_code _M_code;
86
87   public:
88     explicit future_error(future_errc __ec)
89     : logic_error("std::future_error"), _M_code(make_error_code(__ec))
90     { }
91
92     virtual ~future_error() throw();
93
94     virtual const char* 
95     what() const throw();
96
97     const error_code& 
98     code() const throw() { return _M_code; }
99   };
100
101   // Forward declarations.
102   template<typename _Result>
103     class unique_future;
104
105   template<typename _Result>
106     class shared_future;
107
108   template<typename> 
109     class packaged_task;
110
111   template<typename _Result>
112     class promise;
113
114   // Holds the result of a future
115   struct _Future_result_base
116   {
117     _Future_result_base() = default;
118     _Future_result_base(const _Future_result_base&) = delete;
119     _Future_result_base& operator=(const _Future_result_base&) = delete;
120
121     exception_ptr _M_error;
122
123     // _M_destroy() allows derived classes to control deallocation,
124     // which will be needed when allocator support is added to promise.
125     // See http://gcc.gnu.org/ml/libstdc++/2009-06/msg00032.html
126     virtual void _M_destroy() = 0;
127     struct _Deleter
128     {
129       void operator()(_Future_result_base* __fr) const { __fr->_M_destroy(); }
130     };
131
132   protected:
133     ~_Future_result_base() = default;
134   };
135
136   // TODO: use template alias when available
137   /*
138    template<typename _Res>
139      using _Future_ptr = unique_ptr<_Res, _Future_result_base::_Deleter>;
140    */
141   template<typename _Res>
142     struct _Future_ptr
143     {
144       typedef unique_ptr<_Res, _Future_result_base::_Deleter> type;
145     };
146
147   // State shared between a promise and one or more associated futures.
148   class _Future_state
149   {
150     typedef _Future_ptr<_Future_result_base>::type _Future_ptr_type;
151
152   public:
153     _Future_state() : _M_result(), _M_retrieved(false) { }
154
155     _Future_state(const _Future_state&) = delete;
156     _Future_state& operator=(const _Future_state&) = delete;
157
158     bool
159     is_ready()
160     { return _M_get() != 0; }
161
162     bool
163     has_exception()
164     {
165       _Future_result_base* const __res = _M_get();
166       return __res && !(__res->_M_error == 0);
167     }
168
169     bool
170     has_value()
171     {
172       _Future_result_base* const __res = _M_get();
173       return __res && (__res->_M_error == 0);
174     }
175
176     _Future_result_base&
177     wait()
178     {
179       unique_lock<mutex> __lock(_M_mutex);
180       if (!_M_ready())
181         _M_cond.wait(__lock, std::bind(&_Future_state::_M_ready, this));
182       return *_M_result;
183     }
184
185     template<typename _Rep, typename _Period>
186       bool
187       wait_for(const chrono::duration<_Rep, _Period>& __rel)
188       {
189         unique_lock<mutex> __lock(_M_mutex);
190         return _M_ready() || _M_cond.wait_for(__lock, __rel,
191             std::bind(&_Future_state::_M_ready, this));
192       }
193
194     template<typename _Clock, typename _Duration>
195       bool
196       wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
197       {
198         unique_lock<mutex> __lock(_M_mutex);
199         return _M_ready() || _M_cond.wait_until(__lock, __abs,
200             std::bind(&_Future_state::_M_ready, this));
201       }
202
203     void
204     _M_set_result(_Future_ptr_type __res)
205     {
206       {
207         lock_guard<mutex> __lock(_M_mutex);
208         if (_M_ready())
209           __throw_future_error(int(future_errc::promise_already_satisfied));
210         _M_result.swap(__res);
211       }
212       _M_cond.notify_all();
213     }
214
215     void
216     _M_break_promise(_Future_ptr_type __res)
217     {
218       if (static_cast<bool>(__res))
219       {
220         __res->_M_error
221           = std::copy_exception(future_error(future_errc::broken_promise));
222         {
223           lock_guard<mutex> __lock(_M_mutex);
224           _M_result.swap(__res);
225         }
226         _M_cond.notify_all();
227       }
228     }
229
230     // called when this object is passed to a unique_future
231     void
232     _M_set_retrieved_flag()
233     {
234       if (_M_retrieved.test_and_set())
235         __throw_future_error(int(future_errc::future_already_retrieved));
236     }
237
238   private:
239     _Future_result_base*
240     _M_get()
241     {
242       lock_guard<mutex> __lock(_M_mutex);
243       return _M_result.get();
244     }
245
246     bool _M_ready() const { return static_cast<bool>(_M_result); }
247
248     _Future_ptr_type    _M_result;
249     mutex               _M_mutex;
250     condition_variable  _M_cond;
251     atomic_flag         _M_retrieved;
252   };
253
254   // workaround for CWG issue 664 and c++/34022
255   template<typename _Result, bool = is_scalar<_Result>::value>
256     struct _Move_future_result
257     {
258       typedef _Result&& __rval_type;
259       static _Result&& _S_move(_Result& __res) { return std::move(__res); }
260     };
261
262   // specialization for scalar types returns rvalue not rvalue-reference
263   template<typename _Result>
264     struct _Move_future_result<_Result, true>
265     {
266       typedef _Result __rval_type;
267       static _Result _S_move(_Result __res) { return __res; }
268     };
269
270   template<typename _Result>
271     struct _Future_result : _Future_result_base
272     {
273       _Future_result() : _M_initialized() { }
274
275       ~_Future_result()
276       {
277         if (_M_initialized)
278           _M_value().~_Result();
279       }
280
281       // return lvalue, future will add const or rvalue-reference
282       _Result& _M_value()
283       { return *static_cast<_Result*>(_M_addr()); }
284
285       void
286       _M_set(const _Result& __res)
287       {
288         ::new (_M_addr()) _Result(__res);
289         _M_initialized = true;
290       }
291
292       void
293       _M_set(_Result&& __res)
294       {
295         typedef _Move_future_result<_Result> _Mover;
296         ::new (_M_addr()) _Result(_Mover::_S_move(__res));
297         _M_initialized = true;
298       }
299
300     private:
301       void _M_destroy() { delete this; }
302
303       void* _M_addr() { return static_cast<void*>(&_M_storage); }
304
305       typename aligned_storage<sizeof(_Result),
306                alignment_of<_Result>::value>::type _M_storage;
307       bool _M_initialized;
308     };
309
310   template<typename _Result>
311     struct _Future_result<_Result&> : _Future_result_base
312     {
313       _Future_result() : _M_value_ptr() { }
314
315       _Result* _M_value_ptr;
316
317       void _M_destroy() { delete this; }
318     };
319
320   template<>
321     struct _Future_result<void> : _Future_result_base
322     {
323       void _M_destroy() { delete this; }
324     };
325
326   // common implementation for unique_future and shared_future
327   template<typename _Result>
328     class _Future_impl
329     {
330     public:
331       // disable copying
332       _Future_impl(const _Future_impl&) = delete;
333       _Future_impl& operator=(const _Future_impl&) = delete;
334
335       // functions to check state and wait for ready
336       bool is_ready() const { return this->_M_state->is_ready(); }
337
338       bool has_exception() const { return this->_M_state->has_exception(); }
339
340       bool has_value() const { return this->_M_state->has_value(); }
341
342       void wait() const { this->_M_state->wait(); }
343
344       template<typename _Rep, typename _Period>
345         bool
346         wait_for(const chrono::duration<_Rep, _Period>& __rel) const
347         { return this->_M_state->wait_for(__rel); }
348
349       template<typename _Clock, typename _Duration>
350         bool
351         wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
352         { return this->_M_state->wait_until(__abs); }
353
354     protected:
355       // wait for the state to be ready and rethrow any stored exception
356       _Future_result<_Result>&
357       _M_get_result()
358       {
359         _Future_result_base& __res = this->_M_state->wait();
360         if (!(__res._M_error == 0))
361           rethrow_exception(__res._M_error);
362         return static_cast<_Future_result<_Result>&>(__res);
363       }
364
365       typedef shared_ptr<_Future_state> _State_ptr;
366
367       // construction of a unique_future by promise::get_future()
368       explicit
369       _Future_impl(const _State_ptr& __state)
370       : _M_state(__state)
371       {
372         if (static_cast<bool>(this->_M_state))
373           this->_M_state->_M_set_retrieved_flag();
374         else
375           __throw_future_error(int(future_errc::future_already_retrieved));
376       }
377
378       // copy construction from a shared_future
379       explicit
380       _Future_impl(const shared_future<_Result>&);
381
382       // move construction from a unique_future
383       explicit
384       _Future_impl(unique_future<_Result>&&);
385
386       _State_ptr _M_state;
387     };
388
389   /// primary template for unique_future
390   template<typename _Result>
391     class unique_future : public _Future_impl<_Result>
392     {
393       typedef _Move_future_result<_Result> _Mover;
394
395     public:
396       /// Move constructor
397       unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
398
399       // disable copying
400       unique_future(const unique_future&) = delete;
401       unique_future& operator=(const unique_future&) = delete;
402
403       // retrieving the value
404       typename _Mover::__rval_type
405       get()
406       { return _Mover::_S_move(this->_M_get_result()._M_value()); }
407
408     private:
409       typedef _Future_impl<_Result> _Base_type;
410       typedef typename _Base_type::_State_ptr _State_ptr;
411
412       friend class promise<_Result>;
413
414       explicit
415       unique_future(const _State_ptr& __state) : _Base_type(__state) { }
416     };
417  
418   // partial specialization for unique_future<R&>
419   template<typename _Result>
420     class unique_future<_Result&> : public _Future_impl<_Result&>
421     {
422     public:
423       /// Move constructor
424       unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
425
426       // disable copying
427       unique_future(const unique_future&) = delete;
428       unique_future& operator=(const unique_future&) = delete;
429
430       // retrieving the value
431       _Result& get() { return *this->_M_get_result()._M_value_ptr; }
432
433     private:
434       typedef _Future_impl<_Result&>           _Base_type;
435       typedef typename _Base_type::_State_ptr _State_ptr;
436
437       friend class promise<_Result&>;
438
439       explicit
440       unique_future(const _State_ptr& __state) : _Base_type(__state) { }
441     };
442
443   // specialization for unique_future<void>
444   template<>
445     class unique_future<void> : public _Future_impl<void>
446     {
447     public:
448       /// Move constructor
449       unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
450
451       // disable copying
452       unique_future(const unique_future&) = delete;
453       unique_future& operator=(const unique_future&) = delete;
454
455       // retrieving the value
456       void get() { this->_M_get_result(); }
457
458     private:
459       typedef _Future_impl<void> _Base_type;
460       typedef _Base_type::_State_ptr _State_ptr;
461
462       friend class promise<void>;
463
464       explicit
465       unique_future(const _State_ptr& __state) : _Base_type(__state) { }
466     };
467
468   /// primary template for shared_future
469   template<typename _Result>
470     class shared_future : public _Future_impl<_Result>
471     {
472     public:
473       /// Copy constructor
474       shared_future(const shared_future& __sf) : _Base_type(__sf) { }
475
476       /// Construct from a unique_future rvalue
477       shared_future(unique_future<_Result>&& __uf)
478       : _Base_type(std::move(__uf))
479       { }
480
481       shared_future& operator=(const shared_future&) = delete;
482
483       // retrieving the value
484       const _Result&
485       get()
486       { return this->_M_get_result()._M_value(); }
487
488     private:
489       typedef _Future_impl<_Result> _Base_type;
490     };
491  
492   // partial specialization for shared_future<R&>
493   template<typename _Result>
494     class shared_future<_Result&> : public _Future_impl<_Result&>
495     {
496     public:
497       /// Copy constructor
498       shared_future(const shared_future& __sf) : _Base_type(__sf) { }
499
500       /// Construct from a unique_future rvalue
501       shared_future(unique_future<_Result&>&& __uf)
502       : _Base_type(std::move(__uf))
503       { }
504
505       shared_future& operator=(const shared_future&) = delete;
506
507       // retrieving the value
508       _Result& get() { return *this->_M_get_result()._M_value_ptr; }
509
510     private:
511       typedef _Future_impl<_Result&>           _Base_type;
512     };
513
514   // specialization for shared_future<void>
515   template<>
516     class shared_future<void> : public _Future_impl<void>
517     {
518     public:
519       /// Copy constructor
520       shared_future(const shared_future& __sf) : _Base_type(__sf) { }
521
522       /// Construct from a unique_future rvalue
523       shared_future(unique_future<void>&& __uf)
524       : _Base_type(std::move(__uf))
525       { }
526
527       shared_future& operator=(const shared_future&) = delete;
528
529       // retrieving the value
530       void get() { this->_M_get_result(); }
531
532     private:
533       typedef _Future_impl<void> _Base_type;
534     };
535
536   // now we can define the protected _Future_impl constructors
537
538   template<typename _Result>
539     _Future_impl<_Result>::_Future_impl(const shared_future<_Result>& __sf)
540     : _M_state(__sf._M_state)
541     { }
542
543   template<typename _Result>
544     _Future_impl<_Result>::_Future_impl(unique_future<_Result>&& __uf)
545     : _M_state(std::move(__uf._M_state))
546     { }
547
548   /// primary template for promise
549   template<typename _Result>
550     class promise
551     {
552     public:
553       promise()
554       : _M_future(std::make_shared<_Future_state>()),
555       _M_storage(new _Future_result<_Result>())
556       { }
557
558       promise(promise&& __rhs)
559       : _M_future(std::move(__rhs._M_future)),
560       _M_storage(std::move(__rhs._M_storage))
561       { }
562
563       // TODO: requires allocator concepts
564       /*
565       template<typename _Allocator>
566         promise(allocator_arg_t, const _Allocator& __a);
567
568       template<typename _Allocator>
569         promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
570        */
571
572       promise(const promise&) = delete;
573
574       ~promise()
575       {
576         if (static_cast<bool>(_M_future) && !_M_future.unique())
577           _M_future->_M_break_promise(std::move(_M_storage));
578       }
579
580       // assignment
581       promise&
582       operator=(promise&& __rhs)
583       {
584         promise(std::move(__rhs)).swap(*this);
585         return *this;
586       }
587
588       promise& operator=(const promise&) = delete;
589
590       void
591       swap(promise& __rhs)
592       {
593         _M_future.swap(__rhs._M_future);
594         _M_storage.swap(__rhs._M_storage);
595       }
596
597       // retrieving the result
598       unique_future<_Result>
599       get_future()
600       { return unique_future<_Result>(_M_future); }
601
602       // setting the result
603       void
604       set_value(const _Result& __r)
605       {
606         if (!_M_satisfied())
607           _M_storage->_M_set(__r);
608         _M_future->_M_set_result(std::move(_M_storage));
609       }
610
611       void
612       set_value(_Result&& __r)
613       {
614         if (!_M_satisfied())
615           _M_storage->_M_set(_Mover::_S_move(__r));
616         _M_future->_M_set_result(std::move(_M_storage));
617       }
618
619       void
620       set_exception(exception_ptr __p)
621       {
622         if (!_M_satisfied())
623           _M_storage->_M_error = __p;
624         _M_future->_M_set_result(std::move(_M_storage));
625       }
626
627     private:
628       template<typename> friend class packaged_task;
629       typedef _Move_future_result<_Result> _Mover;
630       bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
631       shared_ptr<_Future_state>                           _M_future;
632       typename _Future_ptr<_Future_result<_Result>>::type _M_storage;
633     };
634
635   // partial specialization for promise<R&>
636   template<typename _Result>
637     class promise<_Result&>
638     {
639     public:
640       promise()
641       : _M_future(std::make_shared<_Future_state>()),
642       _M_storage(new _Future_result<_Result&>())
643       { }
644
645       promise(promise&& __rhs)
646       : _M_future(std::move(__rhs._M_future)),
647       _M_storage(std::move(__rhs._M_storage))
648       { }
649
650       // TODO: requires allocator concepts
651       /*
652       template<typename _Allocator>
653         promise(allocator_arg_t, const _Allocator& __a);
654
655       template<typename _Allocator>
656         promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
657        */
658
659       promise(const promise&) = delete;
660
661       ~promise()
662       {
663         if (static_cast<bool>(_M_future) && !_M_future.unique())
664           _M_future->_M_break_promise(std::move(_M_storage));
665       }
666
667       // assignment
668       promise&
669       operator=(promise&& __rhs)
670       {
671         promise(std::move(__rhs)).swap(*this);
672         return *this;
673       }
674
675       promise& operator=(const promise&) = delete;
676
677       void
678       swap(promise& __rhs)
679       {
680         _M_future.swap(__rhs._M_future);
681         _M_storage.swap(__rhs._M_storage);
682       }
683
684       // retrieving the result
685       unique_future<_Result&>
686       get_future()
687       { return unique_future<_Result&>(_M_future); }
688
689       // setting the result
690       void
691       set_value(_Result& __r)
692       {
693         if (!_M_satisfied())
694           _M_storage->_M_value_ptr = &__r;
695         _M_future->_M_set_result(std::move(_M_storage));
696       }
697
698       void
699       set_exception(exception_ptr __p)
700       {
701         if (!_M_satisfied())
702           _M_storage->_M_error = __p;
703         _M_future->_M_set_result(std::move(_M_storage));
704       }
705
706     private:
707       template<typename> friend class packaged_task;
708       bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
709       shared_ptr<_Future_state>                             _M_future;
710       typename _Future_ptr<_Future_result<_Result&>>::type  _M_storage;
711     };
712
713   // specialization for promise<void>
714   template<>
715     class promise<void>
716     {
717     public:
718       promise()
719       : _M_future(std::make_shared<_Future_state>()),
720       _M_storage(new _Future_result<void>())
721       { }
722
723       promise(promise&& __rhs)
724       : _M_future(std::move(__rhs._M_future)),
725       _M_storage(std::move(__rhs._M_storage))
726       { }
727
728       // TODO: requires allocator concepts
729       /*
730       template<typename _Allocator>
731         promise(allocator_arg_t, const _Allocator& __a);
732
733       template<typename _Allocator>
734         promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
735        */
736
737       promise(const promise&) = delete;
738
739       ~promise()
740       {
741         if (static_cast<bool>(_M_future) && !_M_future.unique())
742           _M_future->_M_break_promise(std::move(_M_storage));
743       }
744
745       // assignment
746       promise&
747       operator=(promise&& __rhs)
748       {
749         promise(std::move(__rhs)).swap(*this);
750         return *this;
751       }
752
753       promise& operator=(const promise&) = delete;
754
755       void
756       swap(promise& __rhs)
757       {
758         _M_future.swap(__rhs._M_future);
759         _M_storage.swap(__rhs._M_storage);
760       }
761
762       // retrieving the result
763       unique_future<void>
764       get_future()
765       { return unique_future<void>(_M_future); }
766
767       // setting the result
768       void
769       set_value()
770       {
771         _M_future->_M_set_result(std::move(_M_storage));
772       }
773
774       void
775       set_exception(exception_ptr __p)
776       {
777         if (!_M_satisfied())
778           _M_storage->_M_error = __p;
779         _M_future->_M_set_result(std::move(_M_storage));
780       }
781
782     private:
783       template<typename> friend class packaged_task;
784       bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
785       shared_ptr<_Future_state>                 _M_future;
786       _Future_ptr<_Future_result<void>>::type   _M_storage;
787     };
788
789   // TODO: requires allocator concepts
790   /*
791   template<typename _Result, class Alloc>
792     concept_map UsesAllocator<promise<_Result>, Alloc>
793     {
794       typedef Alloc allocator_type;
795     }
796    */
797
798   template<typename _Result, typename... _ArgTypes>
799     struct _Run_task
800     {
801       static void
802       _S_run(promise<_Result>& __p, function<_Result(_ArgTypes...)>& __f,
803           _ArgTypes... __args)
804       {
805         __p.set_value(__f(std::forward<_ArgTypes>(__args)...));
806       }
807     };
808
809   // specialization used by packaged_task<void(...)>
810   template<typename... _ArgTypes>
811     struct _Run_task<void, _ArgTypes...>
812     {
813       static void
814       _S_run(promise<void>& __p, function<void(_ArgTypes...)>& __f,
815           _ArgTypes... __args)
816       {
817         __f(std::forward<_ArgTypes>(__args)...);
818         __p.set_value();
819       }
820     };
821
822   /// packaged_task
823   template<typename _Result, typename... _ArgTypes>
824     class packaged_task<_Result(_ArgTypes...)>
825     {
826     public:
827       typedef _Result result_type;
828
829       // construction and destruction
830       packaged_task() { }
831
832       template<typename _Fn>
833         explicit
834         packaged_task(const _Fn& __fn) : _M_task(__fn) { }
835
836       template<typename _Fn>
837         explicit
838         packaged_task(_Fn&& __fn) : _M_task(std::move(__fn)) { }
839
840       explicit
841       packaged_task(_Result(*__fn)(_ArgTypes...)) : _M_task(__fn) { }
842
843       // TODO: requires allocator concepts
844       /*
845       template<typename _Fn, typename _Allocator>
846         explicit
847         packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn __fn)
848         : _M_task(__tag, __a, __fn), _M_promise(__tag, __a)
849         { }
850
851       template<typename _Fn, typename _Allocator>
852         explicit
853         packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn&& __fn)
854         : _M_task(__tag, __a, std::move(__fn)), _M_promise(__tag, __a)
855         { }
856        */
857
858       ~packaged_task() = default;
859
860       // no copy
861       packaged_task(packaged_task&) = delete;
862       packaged_task& operator=(packaged_task&) = delete;
863
864       // move support
865       packaged_task(packaged_task&& __other)
866       { this->swap(__other); }
867
868       packaged_task& operator=(packaged_task&& __other)
869       {
870         packaged_task(std::move(__other)).swap(*this);
871         return *this;
872       }
873
874       void
875       swap(packaged_task& __other)
876       {
877         _M_task.swap(__other._M_task);
878         _M_promise.swap(__other._M_promise);
879       }
880
881       explicit operator bool() const { return static_cast<bool>(_M_task); }
882
883       // result retrieval
884       unique_future<_Result>
885       get_future()
886       {
887         __try
888         {
889           return _M_promise.get_future();
890         }
891         __catch (const future_error& __e)
892         {
893 #ifdef __EXCEPTIONS
894           if (__e.code() == future_errc::future_already_retrieved)
895             throw std::bad_function_call();
896           throw;
897 #endif
898         }
899       }
900
901       // execution
902       void
903       operator()(_ArgTypes... __args)
904       {
905         if (!static_cast<bool>(_M_task) || _M_promise._M_satisfied())
906           {
907 #ifdef __EXCEPTIONS
908             throw std::bad_function_call();
909 #else
910             __builtin_abort();
911 #endif
912           }
913
914         __try
915         {
916           _Run_task<_Result, _ArgTypes...>::_S_run(_M_promise, _M_task,
917               std::forward<_ArgTypes>(__args)...);
918         }
919         __catch (...)
920         {
921           _M_promise.set_exception(current_exception());
922         }
923       }
924
925       void reset() { promise<_Result>().swap(_M_promise); }
926
927     private:
928       function<_Result(_ArgTypes...)>   _M_task;
929       promise<_Result>                  _M_promise;
930     };
931
932   // @} group futures
933 }
934
935 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
936        // && _GLIBCXX_ATOMIC_BUILTINS_4
937
938 #endif // __GXX_EXPERIMENTAL_CXX0X__
939
940 #endif // _GLIBCXX_FUTURE