future

Go to the documentation of this file.
00001 // <future> -*- C++ -*-
00002 
00003 // Copyright (C) 2009 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file future
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_FUTURE
00030 #define _GLIBCXX_FUTURE 1
00031 
00032 #pragma GCC system_header
00033 
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <c++0x_warning.h>
00036 #else
00037 
00038 #include <functional>
00039 #include <memory>
00040 #include <mutex>
00041 #include <condition_variable>
00042 #include <system_error>
00043 #include <exception>
00044 #include <atomic>
00045 #include <bits/functexcept.h>
00046 
00047 namespace std
00048 {
00049   /**
00050    * @defgroup futures Futures
00051    * @ingroup concurrency
00052    *
00053    * Classes for futures support.
00054    * @{
00055    */
00056 
00057   /// Error code for futures
00058   enum class future_errc
00059   { broken_promise, future_already_retrieved, promise_already_satisfied };
00060 
00061   // TODO: requires concepts
00062   // concept_map ErrorCodeEnum<future_errc> { }
00063   template<>
00064     struct is_error_code_enum<future_errc> : public true_type { };
00065 
00066   /// Points to a statically-allocated object derived from error_category.
00067   extern const error_category* const future_category;
00068 
00069   // TODO: requires constexpr
00070   inline error_code make_error_code(future_errc __errc)
00071   { return error_code(static_cast<int>(__errc), *future_category); }
00072 
00073   // TODO: requires constexpr
00074   inline error_condition make_error_condition(future_errc __errc)
00075   { return error_condition(static_cast<int>(__errc), *future_category); }
00076 
00077   /**
00078    *  @brief Exception type thrown by futures.
00079    *  @ingroup exceptions
00080    */
00081   class future_error : public logic_error
00082   {
00083     error_code          _M_code;
00084 
00085   public:
00086     explicit future_error(future_errc __ec)
00087     : logic_error("std::future_error"), _M_code(make_error_code(__ec))
00088     { }
00089 
00090     virtual ~future_error() throw();
00091 
00092     virtual const char* 
00093     what() const throw();
00094 
00095     const error_code& 
00096     code() const throw() { return _M_code; }
00097   };
00098 
00099   // Forward declarations.
00100   template<typename _Res>
00101     class unique_future;
00102 
00103   template<typename _Res>
00104     class shared_future;
00105 
00106   template<typename> 
00107     class packaged_task;
00108 
00109   template<typename _Res>
00110     class promise;
00111 
00112 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
00113   && defined(_GLIBCXX_ATOMIC_BUILTINS_4)
00114 
00115   /// Base class and enclosing scope.
00116   struct __future_base
00117   {
00118     /// Base class for results.
00119     struct _Result_base
00120     {
00121       exception_ptr     _M_error;
00122 
00123       _Result_base() = default;
00124       _Result_base(const _Result_base&) = delete;
00125       _Result_base& operator=(const _Result_base&) = delete;
00126 
00127       // _M_destroy() allows derived classes to control deallocation,
00128       // which will be needed when allocator support is added to promise.
00129       // See http://gcc.gnu.org/ml/libstdc++/2009-06/msg00032.html
00130       virtual void _M_destroy() = 0;
00131 
00132       struct _Deleter
00133       {
00134     void operator()(_Result_base* __fr) const { __fr->_M_destroy(); }
00135       };
00136 
00137     protected:
00138       ~_Result_base();
00139     };
00140 
00141     /// Result.
00142     template<typename _Res>
00143       struct _Result : _Result_base
00144       {
00145       private:
00146     typedef alignment_of<_Res>              __a_of;
00147     typedef aligned_storage<sizeof(_Res), __a_of::value>    __align_storage;
00148     typedef typename __align_storage::type          __align_type;
00149 
00150     __align_type        _M_storage;
00151     bool            _M_initialized;
00152 
00153       public:
00154     _Result() : _M_initialized() { }
00155     
00156     ~_Result()
00157     {
00158       if (_M_initialized)
00159         _M_value().~_Res();
00160     }
00161 
00162     // Return lvalue, future will add const or rvalue-reference
00163     _Res& 
00164     _M_value() { return *static_cast<_Res*>(_M_addr()); }
00165 
00166     void
00167     _M_set(const _Res& __res)
00168     {
00169       ::new (_M_addr()) _Res(__res);
00170       _M_initialized = true;
00171     }
00172 
00173     void
00174     _M_set(_Res&& __res)
00175     {
00176       ::new (_M_addr()) _Res(std::move(__res));
00177       _M_initialized = true;
00178     }
00179 
00180       private:
00181     void _M_destroy() { delete this; }
00182 
00183     void* _M_addr() { return static_cast<void*>(&_M_storage); }
00184     };
00185 
00186 
00187     // TODO: use template alias when available
00188     /*
00189       template<typename _Res>
00190       using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>;
00191     */
00192     /// A unique_ptr based on the instantiating type.
00193     template<typename _Res>
00194       struct _Ptr
00195       {
00196     typedef unique_ptr<_Res, _Result_base::_Deleter> type;
00197       };
00198 
00199 
00200     /// Shared state between a promise and one or more associated futures.
00201     class _State
00202     {
00203       typedef _Ptr<_Result_base>::type _Ptr_type;
00204 
00205       _Ptr_type         _M_result;
00206       mutex                 _M_mutex;
00207       condition_variable    _M_cond;
00208       atomic_flag           _M_retrieved;
00209 
00210     public:
00211       _State() : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }
00212 
00213       _State(const _State&) = delete;
00214       _State& operator=(const _State&) = delete;
00215 
00216       bool
00217       is_ready()
00218       { return _M_get() != 0; }
00219 
00220       bool
00221       has_exception()
00222       {
00223     _Result_base* const __res = _M_get();
00224     return __res && !(__res->_M_error == 0);
00225       }
00226 
00227       bool
00228       has_value()
00229       {
00230     _Result_base* const __res = _M_get();
00231     return __res && (__res->_M_error == 0);
00232       }
00233 
00234       _Result_base&
00235       wait()
00236       {
00237     unique_lock<mutex> __lock(_M_mutex);
00238     if (!_M_ready())
00239       _M_cond.wait(__lock, std::bind(&_State::_M_ready, this));
00240     return *_M_result;
00241       }
00242 
00243       template<typename _Rep, typename _Period>
00244         bool
00245         wait_for(const chrono::duration<_Rep, _Period>& __rel)
00246         {
00247       unique_lock<mutex> __lock(_M_mutex);
00248       auto __bound = std::bind(&_State::_M_ready, this);
00249       return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound);
00250     }
00251 
00252       template<typename _Clock, typename _Duration>
00253         bool
00254         wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
00255         {
00256       unique_lock<mutex> __lock(_M_mutex);
00257       auto __bound = std::bind(&_State::_M_ready, this);
00258       return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound);
00259     }
00260 
00261       void
00262       _M_set_result(_Ptr_type __res)
00263       {
00264     {
00265       lock_guard<mutex> __lock(_M_mutex);
00266       if (_M_ready())
00267         __throw_future_error(int(future_errc::promise_already_satisfied));
00268       _M_result.swap(__res);
00269     }
00270     _M_cond.notify_all();
00271       }
00272 
00273       void
00274       _M_break_promise(_Ptr_type __res)
00275       {
00276     if (static_cast<bool>(__res))
00277       {
00278         future_errc __ec(future_errc::broken_promise); // XXX
00279         __res->_M_error = copy_exception(future_error(__ec));
00280         {
00281           lock_guard<mutex> __lock(_M_mutex);
00282           _M_result.swap(__res);
00283         }
00284         _M_cond.notify_all();
00285       }
00286       }
00287 
00288       // Called when this object is passed to a unique_future.
00289       void
00290       _M_set_retrieved_flag()
00291       {
00292     if (_M_retrieved.test_and_set())
00293       __throw_future_error(int(future_errc::future_already_retrieved));
00294       }
00295 
00296     private:
00297       _Result_base*
00298       _M_get()
00299       {
00300     lock_guard<mutex> __lock(_M_mutex);
00301     return _M_result.get();
00302       }
00303 
00304       bool _M_ready() const { return static_cast<bool>(_M_result); }
00305     };
00306   };
00307 
00308   inline __future_base::_Result_base::~_Result_base() = default;
00309 
00310   /// Partial specialization for reference types.
00311   template<typename _Res>
00312     struct __future_base::_Result<_Res&> : __future_base::_Result_base
00313     {
00314       _Result() : _M_value_ptr() { }
00315 
00316       _Res*             _M_value_ptr;
00317       
00318     private:
00319       void _M_destroy() { delete this; }
00320     };
00321 
00322   /// Explicit specialization for void.
00323   template<>
00324     struct __future_base::_Result<void> : __future_base::_Result_base
00325     {
00326     private:
00327       void _M_destroy() { delete this; }
00328     };
00329 
00330 
00331   /// Common implementation for unique_future and shared_future.
00332   template<typename _Res>
00333     class __basic_future : public __future_base
00334     {
00335     protected:
00336       typedef shared_ptr<_State>        __state_type;
00337       typedef __future_base::_Result<_Res>& __result_type;
00338 
00339     private:
00340       __state_type      _M_state;
00341 
00342     public:
00343       // Disable copying.
00344       __basic_future(const __basic_future&) = delete;
00345       __basic_future& operator=(const __basic_future&) = delete;
00346 
00347       // Functions to check state and wait for ready.
00348       bool 
00349       is_ready() const { return this->_M_state->is_ready(); }
00350 
00351       bool 
00352       has_exception() const { return this->_M_state->has_exception(); }
00353 
00354       bool 
00355       has_value() const { return this->_M_state->has_value(); }
00356 
00357       void 
00358       wait() const { this->_M_state->wait(); }
00359 
00360       template<typename _Rep, typename _Period>
00361         bool
00362         wait_for(const chrono::duration<_Rep, _Period>& __rel) const
00363         { return this->_M_state->wait_for(__rel); }
00364 
00365       template<typename _Clock, typename _Duration>
00366         bool
00367         wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
00368         { return this->_M_state->wait_until(__abs); }
00369 
00370     protected:
00371       /// Wait for the state to be ready and rethrow any stored exception
00372       __result_type
00373       _M_get_result()
00374       {
00375         _Result_base& __res = this->_M_state->wait();
00376         if (!(__res._M_error == 0))
00377           rethrow_exception(__res._M_error);
00378         return static_cast<__result_type>(__res);
00379       }
00380 
00381       // Construction of a unique_future by promise::get_future()
00382       explicit
00383       __basic_future(const __state_type& __state) : _M_state(__state)
00384       {
00385         if (static_cast<bool>(this->_M_state))
00386           this->_M_state->_M_set_retrieved_flag();
00387         else
00388           __throw_future_error(int(future_errc::future_already_retrieved));
00389       }
00390 
00391       // Copy construction from a shared_future
00392       explicit
00393       __basic_future(const shared_future<_Res>&);
00394 
00395       // Move construction from a unique_future
00396       explicit
00397       __basic_future(unique_future<_Res>&&);
00398     };
00399 
00400 
00401   /// Primary template for unique_future.
00402   template<typename _Res>
00403     class unique_future : public __basic_future<_Res>
00404     {
00405       friend class promise<_Res>;
00406 
00407       typedef __basic_future<_Res> _Base_type;
00408       typedef typename _Base_type::__state_type __state_type;
00409 
00410       explicit
00411       unique_future(const __state_type& __state) : _Base_type(__state) { }
00412 
00413     public:
00414       /// Move constructor
00415       unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
00416 
00417       // Disable copying
00418       unique_future(const unique_future&) = delete;
00419       unique_future& operator=(const unique_future&) = delete;
00420 
00421       /// Retrieving the value
00422       _Res&&
00423       get()
00424       { return std::move(this->_M_get_result()._M_value()); }
00425     };
00426  
00427   /// Partial specialization for unique_future<R&>
00428   template<typename _Res>
00429     class unique_future<_Res&> : public __basic_future<_Res&>
00430     {
00431       friend class promise<_Res&>;
00432 
00433       typedef __basic_future<_Res&> _Base_type;
00434       typedef typename _Base_type::__state_type __state_type;
00435 
00436       explicit
00437       unique_future(const __state_type& __state) : _Base_type(__state) { }
00438 
00439     public:
00440       /// Move constructor
00441       unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
00442 
00443       // Disable copying
00444       unique_future(const unique_future&) = delete;
00445       unique_future& operator=(const unique_future&) = delete;
00446 
00447       /// Retrieving the value
00448       _Res& 
00449       get() { return *this->_M_get_result()._M_value_ptr; }
00450     };
00451 
00452   /// Explicit specialization for unique_future<void>
00453   template<>
00454     class unique_future<void> : public __basic_future<void>
00455     {
00456       friend class promise<void>;
00457 
00458       typedef __basic_future<void> _Base_type;
00459       typedef typename _Base_type::__state_type __state_type;
00460 
00461       explicit
00462       unique_future(const __state_type& __state) : _Base_type(__state) { }
00463 
00464     public:
00465       /// Move constructor
00466       unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
00467 
00468       // Disable copying
00469       unique_future(const unique_future&) = delete;
00470       unique_future& operator=(const unique_future&) = delete;
00471 
00472       /// Retrieving the value
00473       void 
00474       get() { this->_M_get_result(); }
00475     };
00476 
00477 
00478   /// Primary template for shared_future.
00479   template<typename _Res>
00480     class shared_future : public __basic_future<_Res>
00481     {
00482       typedef __basic_future<_Res> _Base_type;
00483 
00484     public:
00485       /// Copy constructor
00486       shared_future(const shared_future& __sf) : _Base_type(__sf) { }
00487 
00488       /// Construct from a unique_future rvalue
00489       shared_future(unique_future<_Res>&& __uf)
00490       : _Base_type(std::move(__uf))
00491       { }
00492 
00493       shared_future& operator=(const shared_future&) = delete;
00494 
00495       /// Retrieving the value
00496       const _Res&
00497       get()
00498       { 
00499     typename _Base_type::__result_type __r = this->_M_get_result();
00500     _Res& __rs(__r._M_value());
00501     return __rs;
00502       }
00503     };
00504  
00505   /// Partial specialization for shared_future<R&>
00506   template<typename _Res>
00507     class shared_future<_Res&> : public __basic_future<_Res&>
00508     {
00509       typedef __basic_future<_Res&>           _Base_type;
00510 
00511     public:
00512       /// Copy constructor
00513       shared_future(const shared_future& __sf) : _Base_type(__sf) { }
00514 
00515       /// Construct from a unique_future rvalue
00516       shared_future(unique_future<_Res&>&& __uf)
00517       : _Base_type(std::move(__uf))
00518       { }
00519 
00520       shared_future& operator=(const shared_future&) = delete;
00521 
00522       /// Retrieving the value
00523       _Res& 
00524       get() { return *this->_M_get_result()._M_value_ptr; }
00525     };
00526 
00527   /// Explicit specialization for shared_future<void>
00528   template<>
00529     class shared_future<void> : public __basic_future<void>
00530     {
00531       typedef __basic_future<void> _Base_type;
00532 
00533     public:
00534       /// Copy constructor
00535       shared_future(const shared_future& __sf) : _Base_type(__sf) { }
00536 
00537       /// Construct from a unique_future rvalue
00538       shared_future(unique_future<void>&& __uf)
00539       : _Base_type(std::move(__uf))
00540       { }
00541 
00542       shared_future& operator=(const shared_future&) = delete;
00543 
00544       // Retrieving the value
00545       void 
00546       get() { this->_M_get_result(); }
00547     };
00548 
00549   // Now we can define the protected __basic_future constructors.
00550   template<typename _Res>
00551     __basic_future<_Res>::__basic_future(const shared_future<_Res>& __sf)
00552     : _M_state(__sf._M_state)
00553     { }
00554 
00555   template<typename _Res>
00556     __basic_future<_Res>::__basic_future(unique_future<_Res>&& __uf)
00557     : _M_state(std::move(__uf._M_state))
00558     { }
00559 
00560 
00561   /// Primary template for promise
00562   template<typename _Res>
00563     class promise
00564     {
00565       template<typename> friend class packaged_task;
00566 
00567       typedef __future_base::_State         _State;
00568       typedef __future_base::_Result<_Res>  result_type;
00569       
00570       shared_ptr<_State>                        _M_future;
00571       typename __future_base::_Ptr<result_type>::type   _M_storage;
00572 
00573     public:
00574       promise()
00575       : _M_future(std::make_shared<_State>()), _M_storage(new result_type())
00576       { }
00577 
00578       promise(promise&& __rhs)
00579       : _M_future(std::move(__rhs._M_future)),
00580       _M_storage(std::move(__rhs._M_storage))
00581       { }
00582 
00583       // TODO: requires allocator concepts
00584       /*
00585       template<typename _Allocator>
00586         promise(allocator_arg_t, const _Allocator& __a);
00587 
00588       template<typename _Allocator>
00589         promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
00590        */
00591 
00592       promise(const promise&) = delete;
00593 
00594       ~promise()
00595       {
00596         if (static_cast<bool>(_M_future) && !_M_future.unique())
00597           _M_future->_M_break_promise(std::move(_M_storage));
00598       }
00599 
00600       // Assignment
00601       promise&
00602       operator=(promise&& __rhs)
00603       {
00604         promise(std::move(__rhs)).swap(*this);
00605         return *this;
00606       }
00607 
00608       promise& operator=(const promise&) = delete;
00609 
00610       void
00611       swap(promise& __rhs)
00612       {
00613         _M_future.swap(__rhs._M_future);
00614         _M_storage.swap(__rhs._M_storage);
00615       }
00616 
00617       // Retrieving the result
00618       unique_future<_Res>
00619       get_future()
00620       { return unique_future<_Res>(_M_future); }
00621 
00622       // Setting the result
00623       void
00624       set_value(const _Res& __r)
00625       {
00626         if (!_M_satisfied())
00627           _M_storage->_M_set(__r);
00628         _M_future->_M_set_result(std::move(_M_storage));
00629       }
00630 
00631       void
00632       set_value(_Res&& __r)
00633       {
00634         if (!_M_satisfied())
00635           _M_storage->_M_set(std::move(__r));
00636         _M_future->_M_set_result(std::move(_M_storage));
00637       }
00638 
00639       void
00640       set_exception(exception_ptr __p)
00641       {
00642         if (!_M_satisfied())
00643           _M_storage->_M_error = __p;
00644         _M_future->_M_set_result(std::move(_M_storage));
00645       }
00646 
00647     private:
00648       bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
00649     };
00650 
00651   /// Partial specialization for promise<R&>
00652   template<typename _Res>
00653     class promise<_Res&>
00654     {
00655       template<typename> friend class packaged_task;
00656       typedef __future_base::_State         _State;
00657  
00658       typedef __future_base::_Result<_Res&> result_type;
00659 
00660       shared_ptr<_State>                        _M_future;
00661       typename __future_base::_Ptr<result_type>::type  _M_storage;
00662 
00663     public:
00664       promise()
00665       : _M_future(std::make_shared<_State>()), _M_storage(new result_type())
00666       { }
00667 
00668       promise(promise&& __rhs)
00669       : _M_future(std::move(__rhs._M_future)), 
00670     _M_storage(std::move(__rhs._M_storage))
00671       { }
00672 
00673       // TODO: requires allocator concepts
00674       /*
00675       template<typename _Allocator>
00676         promise(allocator_arg_t, const _Allocator& __a);
00677 
00678       template<typename _Allocator>
00679         promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
00680        */
00681 
00682       promise(const promise&) = delete;
00683 
00684       ~promise()
00685       {
00686         if (static_cast<bool>(_M_future) && !_M_future.unique())
00687           _M_future->_M_break_promise(std::move(_M_storage));
00688       }
00689 
00690       // Assignment
00691       promise&
00692       operator=(promise&& __rhs)
00693       {
00694         promise(std::move(__rhs)).swap(*this);
00695         return *this;
00696       }
00697 
00698       promise& operator=(const promise&) = delete;
00699 
00700       void
00701       swap(promise& __rhs)
00702       {
00703         _M_future.swap(__rhs._M_future);
00704         _M_storage.swap(__rhs._M_storage);
00705       }
00706 
00707       // Retrieving the result
00708       unique_future<_Res&>
00709       get_future()
00710       { return unique_future<_Res&>(_M_future); }
00711 
00712       // Setting the result
00713       void
00714       set_value(_Res& __r)
00715       {
00716         if (!_M_satisfied())
00717           _M_storage->_M_value_ptr = &__r;
00718         _M_future->_M_set_result(std::move(_M_storage));
00719       }
00720 
00721       void
00722       set_exception(exception_ptr __p)
00723       {
00724         if (!_M_satisfied())
00725           _M_storage->_M_error = __p;
00726         _M_future->_M_set_result(std::move(_M_storage));
00727       }
00728 
00729     private:
00730       bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
00731     };
00732 
00733   /// Explicit specialization for promise<void>
00734   template<>
00735     class promise<void>
00736     {
00737       template<typename> friend class packaged_task;
00738       typedef __future_base::_State         _State;
00739       typedef __future_base::_Result<void>  result_type;
00740 
00741       shared_ptr<__future_base::_State>                 _M_future;
00742       typename __future_base::_Ptr<result_type>::type   _M_storage;
00743 
00744     public:
00745       promise()
00746       : _M_future(std::make_shared<_State>()),
00747     _M_storage(new result_type())
00748       { }
00749 
00750       promise(promise&& __rhs)
00751       : _M_future(std::move(__rhs._M_future)),
00752       _M_storage(std::move(__rhs._M_storage))
00753       { }
00754 
00755       // TODO: requires allocator concepts
00756       /*
00757       template<typename _Allocator>
00758         promise(allocator_arg_t, const _Allocator& __a);
00759 
00760       template<typename _Allocator>
00761         promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
00762        */
00763 
00764       promise(const promise&) = delete;
00765 
00766       ~promise()
00767       {
00768         if (static_cast<bool>(_M_future) && !_M_future.unique())
00769           _M_future->_M_break_promise(std::move(_M_storage));
00770       }
00771 
00772       // Assignment
00773       promise&
00774       operator=(promise&& __rhs)
00775       {
00776         promise(std::move(__rhs)).swap(*this);
00777         return *this;
00778       }
00779 
00780       promise& operator=(const promise&) = delete;
00781 
00782       void
00783       swap(promise& __rhs)
00784       {
00785         _M_future.swap(__rhs._M_future);
00786         _M_storage.swap(__rhs._M_storage);
00787       }
00788 
00789       // Retrieving the result
00790       unique_future<void>
00791       get_future()
00792       { return unique_future<void>(_M_future); }
00793 
00794       // Setting the result
00795       void
00796       set_value()
00797       {
00798         _M_future->_M_set_result(std::move(_M_storage));
00799       }
00800 
00801       void
00802       set_exception(exception_ptr __p)
00803       {
00804         if (!_M_satisfied())
00805           _M_storage->_M_error = __p;
00806         _M_future->_M_set_result(std::move(_M_storage));
00807       }
00808 
00809     private:
00810       bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
00811     };
00812 
00813   // TODO: requires allocator concepts
00814   /*
00815   template<typename _Res, class Alloc>
00816     concept_map UsesAllocator<promise<_Res>, Alloc>
00817     {
00818       typedef Alloc allocator_type;
00819     }
00820    */
00821   /// Primary template.
00822   template<typename _Res, typename... _ArgTypes>
00823     struct _Run_task
00824     {
00825       static void
00826       _S_run(promise<_Res>& __p, function<_Res(_ArgTypes...)>& __f,
00827          _ArgTypes... __args)
00828       {
00829         __p.set_value(__f(std::forward<_ArgTypes>(__args)...));
00830       }
00831     };
00832 
00833   /// Specialization used by packaged_task<void(...)>
00834   template<typename... _ArgTypes>
00835     struct _Run_task<void, _ArgTypes...>
00836     {
00837       static void
00838       _S_run(promise<void>& __p, function<void(_ArgTypes...)>& __f,
00839          _ArgTypes... __args)
00840       {
00841         __f(std::forward<_ArgTypes>(__args)...);
00842         __p.set_value();
00843       }
00844     };
00845 
00846 
00847   /// packaged_task
00848   template<typename _Res, typename... _ArgTypes>
00849     class packaged_task<_Res(_ArgTypes...)>
00850     {
00851       function<_Res(_ArgTypes...)>   _M_task;
00852       promise<_Res>                  _M_promise;
00853 
00854     public:
00855       typedef _Res result_type;
00856 
00857       // Construction and destruction
00858       packaged_task() { }
00859 
00860       template<typename _Fn>
00861         explicit
00862         packaged_task(const _Fn& __fn) : _M_task(__fn) { }
00863 
00864       template<typename _Fn>
00865         explicit
00866         packaged_task(_Fn&& __fn) : _M_task(std::move(__fn)) { }
00867 
00868       explicit
00869       packaged_task(_Res(*__fn)(_ArgTypes...)) : _M_task(__fn) { }
00870 
00871       // TODO: requires allocator concepts
00872       /*
00873       template<typename _Fn, typename _Allocator>
00874         explicit
00875         packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn __fn)
00876         : _M_task(__tag, __a, __fn), _M_promise(__tag, __a)
00877         { }
00878 
00879       template<typename _Fn, typename _Allocator>
00880         explicit
00881         packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn&& __fn)
00882         : _M_task(__tag, __a, std::move(__fn)), _M_promise(__tag, __a)
00883         { }
00884        */
00885 
00886       ~packaged_task() = default;
00887 
00888       // No copy
00889       packaged_task(packaged_task&) = delete;
00890       packaged_task& operator=(packaged_task&) = delete;
00891 
00892       // Move support
00893       packaged_task(packaged_task&& __other)
00894       { this->swap(__other); }
00895 
00896       packaged_task& operator=(packaged_task&& __other)
00897       {
00898         packaged_task(std::move(__other)).swap(*this);
00899         return *this;
00900       }
00901 
00902       void
00903       swap(packaged_task& __other)
00904       {
00905         _M_task.swap(__other._M_task);
00906         _M_promise.swap(__other._M_promise);
00907       }
00908 
00909       explicit operator bool() const { return static_cast<bool>(_M_task); }
00910 
00911       // Result retrieval
00912       unique_future<_Res>
00913       get_future()
00914       {
00915         __try
00916         {
00917           return _M_promise.get_future();
00918         }
00919         __catch (const future_error& __e)
00920         {
00921           if (__e.code() == future_errc::future_already_retrieved)
00922             __throw_bad_function_call();
00923           __throw_exception_again;
00924         }
00925       }
00926 
00927       // Execution
00928       void
00929       operator()(_ArgTypes... __args)
00930       {
00931         if (!static_cast<bool>(_M_task) || _M_promise._M_satisfied())
00932           __throw_bad_function_call();
00933 
00934         __try
00935         {
00936           _Run_task<_Res, _ArgTypes...>::_S_run(_M_promise, _M_task,
00937               std::forward<_ArgTypes>(__args)...);
00938         }
00939         __catch (...)
00940         {
00941           _M_promise.set_exception(current_exception());
00942         }
00943       }
00944 
00945       void reset() { promise<_Res>().swap(_M_promise); }
00946     };
00947 
00948 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
00949        // && _GLIBCXX_ATOMIC_BUILTINS_4
00950 
00951   // @} group futures
00952 }
00953 
00954 #endif // __GXX_EXPERIMENTAL_CXX0X__
00955 
00956 #endif // _GLIBCXX_FUTURE

Generated on 11 Jan 2010 for libstdc++ by  doxygen 1.6.1