diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/future.hpp')
| -rw-r--r-- | 3rdParty/Boost/src/boost/thread/future.hpp | 1243 | 
1 files changed, 864 insertions, 379 deletions
| diff --git a/3rdParty/Boost/src/boost/thread/future.hpp b/3rdParty/Boost/src/boost/thread/future.hpp index a4b4343..6bf5cf6 100644 --- a/3rdParty/Boost/src/boost/thread/future.hpp +++ b/3rdParty/Boost/src/boost/thread/future.hpp @@ -1,4 +1,5 @@ -//  (C) Copyright 2008-10 Anthony Williams  +//  (C) Copyright 2008-10 Anthony Williams +//  (C) Copyright 2011-2012 Vicente J. Botet Escriba  //  //  Distributed under the Boost Software License, Version 1.0. (See  //  accompanying file LICENSE_1_0.txt or copy at @@ -6,6 +7,15 @@  #ifndef BOOST_THREAD_FUTURE_HPP  #define BOOST_THREAD_FUTURE_HPP + +#include <boost/thread/detail/config.hpp> + +// boost::thread::future requires exception handling +// due to boost::exception::exception_ptr dependency + +#ifndef BOOST_NO_EXCEPTIONS + +#include <boost/detail/scoped_enum_emulation.hpp>  #include <stdexcept>  #include <boost/thread/detail/move.hpp>  #include <boost/thread/thread_time.hpp> @@ -16,6 +26,8 @@  #include <boost/scoped_ptr.hpp>  #include <boost/type_traits/is_fundamental.hpp>  #include <boost/type_traits/is_convertible.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/remove_cv.hpp>  #include <boost/mpl/if.hpp>  #include <boost/config.hpp>  #include <boost/throw_exception.hpp> @@ -28,59 +40,168 @@  #include <list>  #include <boost/next_prior.hpp>  #include <vector> +#include <boost/system/error_code.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#endif + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include <boost/thread/detail/memory.hpp> +#endif + +#include <boost/utility/result_of.hpp> +#include <boost/thread/thread.hpp> + +#if defined BOOST_THREAD_PROVIDES_FUTURE +#define BOOST_THREAD_FUTURE future +#else +#define BOOST_THREAD_FUTURE unique_future +#endif +  namespace boost  { -    class future_uninitialized: -        public std::logic_error + +  //enum class future_errc +  BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc) +  { +      broken_promise, +      future_already_retrieved, +      promise_already_satisfied, +      no_state +  } +  BOOST_SCOPED_ENUM_DECLARE_END(future_errc) + +  namespace system +  { +    template <> +    struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type {}; + +    #ifdef BOOST_NO_CXX11_SCOPED_ENUMS +    template <> +    struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { }; +    #endif +  } + +  //enum class launch +  BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch) +  { +      async = 1, +      deferred = 2, +      any = async | deferred +  } +  BOOST_SCOPED_ENUM_DECLARE_END(launch) + +  //enum class future_status +  BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status) +  { +      ready, +      timeout, +      deferred +  } +  BOOST_SCOPED_ENUM_DECLARE_END(future_status) + +  BOOST_THREAD_DECL +  const system::error_category& future_category() BOOST_NOEXCEPT; + +  namespace system +  { +    inline +    error_code +    make_error_code(future_errc e) //BOOST_NOEXCEPT +    { +        return error_code(underlying_cast<int>(e), boost::future_category()); +    } + +    inline +    error_condition +    make_error_condition(future_errc e) //BOOST_NOEXCEPT +    { +        return error_condition(underlying_cast<int>(e), future_category()); +    } +  } + +  class BOOST_SYMBOL_VISIBLE future_error +      : public std::logic_error +  { +      system::error_code ec_; +  public: +      future_error(system::error_code ec) +      : logic_error(ec.message()), +        ec_(ec) +      { +      } + +      const system::error_code& code() const BOOST_NOEXCEPT +      { +        return ec_; +      } +      const char* what() const BOOST_THREAD_NOEXCEPT_OR_THROW +      { +        return code().message().c_str(); +      } + +  }; + +    class BOOST_SYMBOL_VISIBLE future_uninitialized: +        public future_error      {      public: -        future_uninitialized(): -            std::logic_error("Future Uninitialized") +        future_uninitialized() : +          future_error(system::make_error_code(future_errc::no_state))          {}      }; -    class broken_promise: -        public std::logic_error +    class BOOST_SYMBOL_VISIBLE broken_promise: +        public future_error      {      public:          broken_promise(): -            std::logic_error("Broken promise") +          future_error(system::make_error_code(future_errc::broken_promise))          {}      }; -    class future_already_retrieved: -        public std::logic_error +    class BOOST_SYMBOL_VISIBLE future_already_retrieved: +        public future_error      {      public:          future_already_retrieved(): -            std::logic_error("Future already retrieved") +          future_error(system::make_error_code(future_errc::future_already_retrieved))          {}      }; -    class promise_already_satisfied: -        public std::logic_error +    class BOOST_SYMBOL_VISIBLE promise_already_satisfied: +        public future_error      {      public:          promise_already_satisfied(): -            std::logic_error("Promise already satisfied") +          future_error(system::make_error_code(future_errc::promise_already_satisfied))          {}      }; -    class task_already_started: -        public std::logic_error +    class BOOST_SYMBOL_VISIBLE task_already_started: +        public future_error      {      public:          task_already_started(): -            std::logic_error("Task already started") +        future_error(system::make_error_code(future_errc::promise_already_satisfied))          {}      }; -    class task_moved: -        public std::logic_error -    { -    public: -        task_moved(): -            std::logic_error("Task moved") -        {} -    }; +        class BOOST_SYMBOL_VISIBLE task_moved: +            public future_error +        { +        public: +            task_moved(): +              future_error(system::make_error_code(future_errc::no_state)) +            {} +        }; + +            class promise_moved: +                public future_error +            { +            public: +                  promise_moved(): +                  future_error(system::make_error_code(future_errc::no_state)) +                {} +            };      namespace future_state      { @@ -93,6 +214,7 @@ namespace boost          {              boost::exception_ptr exception;              bool done; +            bool thread_was_interrupted;              boost::mutex mutex;              boost::condition_variable waiters;              typedef std::list<boost::condition_variable_any*> waiter_list; @@ -100,7 +222,8 @@ namespace boost              boost::function<void()> callback;              future_object_base(): -                done(false) +                done(false), +                thread_was_interrupted(false)              {}              virtual ~future_object_base()              {} @@ -111,7 +234,7 @@ namespace boost                  do_callback(lock);                  return external_waiters.insert(external_waiters.end(),&cv);              } -             +              void remove_external_waiter(waiter_list::iterator it)              {                  boost::lock_guard<boost::mutex> lock(mutex); @@ -132,7 +255,7 @@ namespace boost              struct relocker              {                  boost::unique_lock<boost::mutex>& lock; -                 +                  relocker(boost::unique_lock<boost::mutex>& lock_):                      lock(lock_)                  { @@ -155,7 +278,7 @@ namespace boost                      local_callback();                  }              } -             +              void wait(bool rethrow=true)              { @@ -165,6 +288,10 @@ namespace boost                  {                      waiters.wait(lock);                  } +                if(rethrow && thread_was_interrupted) +                { +                    throw boost::thread_interrupted(); +                }                  if(rethrow && exception)                  {                      boost::rethrow_exception(exception); @@ -185,7 +312,26 @@ namespace boost                  }                  return true;              } -             + +#ifdef BOOST_THREAD_USES_CHRONO + +            template <class Clock, class Duration> +            future_status +            wait_until(const chrono::time_point<Clock, Duration>& abs_time) +            { +              boost::unique_lock<boost::mutex> lock(mutex); +              do_callback(lock); +              while(!done) +              { +                  cv_status const st=waiters.wait_until(lock,abs_time); +                  if(st==cv_status::timeout && !done) +                  { +                    return future_status::timeout; +                  } +              } +              return future_status::ready; +            } +#endif              void mark_exceptional_finish_internal(boost::exception_ptr const& e)              {                  exception=e; @@ -196,16 +342,21 @@ namespace boost                  boost::lock_guard<boost::mutex> lock(mutex);                  mark_exceptional_finish_internal(boost::current_exception());              } - +            void mark_interrupted_finish() +            { +                boost::lock_guard<boost::mutex> lock(mutex); +                thread_was_interrupted=true; +                mark_finished_internal(); +            }              bool has_value()              {                  boost::lock_guard<boost::mutex> lock(mutex); -                return done && !exception; +                return done && !(exception || thread_was_interrupted);              }              bool has_exception()              {                  boost::lock_guard<boost::mutex> lock(mutex); -                return done && exception; +                return done && (exception || thread_was_interrupted);              }              template<typename F,typename U> @@ -213,7 +364,7 @@ namespace boost              {                  callback=boost::bind(f,boost::ref(*u));              } -             +          private:              future_object_base(future_object_base const&);              future_object_base& operator=(future_object_base const&); @@ -223,25 +374,31 @@ namespace boost          struct future_traits          {              typedef boost::scoped_ptr<T> storage_type; -#ifndef BOOST_NO_RVALUE_REFERENCES +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES              typedef T const& source_reference_type;              struct dummy; -            typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type; -            typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,T&&>::type move_dest_type; +            typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type; +            typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type; +#elif defined BOOST_THREAD_USES_MOVE +            typedef T& source_reference_type; +            typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type; +            typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;  #else              typedef T& source_reference_type; -            typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T const&>::type rvalue_source_type; -            typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T>::type move_dest_type; +            typedef typename boost::mpl::if_<boost::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type; +            typedef typename boost::mpl::if_<boost::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;  #endif +            typedef const T& shared_future_get_result_type; +              static void init(storage_type& storage,source_reference_type t)              {                  storage.reset(new T(t));              } -             +              static void init(storage_type& storage,rvalue_source_type t)              { -                storage.reset(new T(static_cast<rvalue_source_type>(t))); +              storage.reset(new T(static_cast<rvalue_source_type>(t)));              }              static void cleanup(storage_type& storage) @@ -249,7 +406,7 @@ namespace boost                  storage.reset();              }          }; -         +          template<typename T>          struct future_traits<T&>          { @@ -258,6 +415,7 @@ namespace boost              struct rvalue_source_type              {};              typedef T& move_dest_type; +            typedef T& shared_future_get_result_type;              static void init(storage_type& storage,T& t)              { @@ -275,6 +433,7 @@ namespace boost          {              typedef bool storage_type;              typedef void move_dest_type; +            typedef void shared_future_get_result_type;              static void init(storage_type& storage)              { @@ -296,7 +455,8 @@ namespace boost              typedef typename future_traits<T>::source_reference_type source_reference_type;              typedef typename future_traits<T>::rvalue_source_type rvalue_source_type;              typedef typename future_traits<T>::move_dest_type move_dest_type; -             +            typedef typename future_traits<T>::shared_future_get_result_type shared_future_get_result_type; +              storage_type result;              future_object(): @@ -308,6 +468,7 @@ namespace boost                  future_traits<T>::init(result,result_);                  mark_finished_internal();              } +              void mark_finished_with_result_internal(rvalue_source_type result_)              {                  future_traits<T>::init(result,static_cast<rvalue_source_type>(result_)); @@ -319,10 +480,11 @@ namespace boost                  boost::lock_guard<boost::mutex> lock(mutex);                  mark_finished_with_result_internal(result_);              } +              void mark_finished_with_result(rvalue_source_type result_)              {                  boost::lock_guard<boost::mutex> lock(mutex); -                mark_finished_with_result_internal(result_); +                mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_));              }              move_dest_type get() @@ -331,6 +493,12 @@ namespace boost                  return static_cast<move_dest_type>(*result);              } +            shared_future_get_result_type get_sh() +            { +                wait(); +                return static_cast<shared_future_get_result_type>(*result); +            } +              future_state::state get_state()              {                  boost::lock_guard<boost::mutex> guard(mutex); @@ -353,6 +521,8 @@ namespace boost          struct future_object<void>:              detail::future_object_base          { +          typedef void shared_future_get_result_type; +              future_object()              {} @@ -371,7 +541,10 @@ namespace boost              {                  wait();              } -             +            void get_sh() +            { +                wait(); +            }              future_state::state get_state()              {                  boost::lock_guard<boost::mutex> guard(mutex); @@ -384,74 +557,93 @@ namespace boost                      return future_state::ready;                  }              } -          private:              future_object(future_object const&);              future_object& operator=(future_object const&);          }; +//        template<typename T, typename Allocator> +//        struct future_object_alloc: public future_object<T> +//        { +//          typedef future_object<T> base; +//          Allocator alloc_; +// +//        public: +//          explicit future_object_alloc(const Allocator& a) +//              : alloc_(a) {} +// +//        };          class future_waiter          {              struct registered_waiter; -            typedef std::vector<registered_waiter>::size_type count_type; -             +            typedef std::vector<int>::size_type count_type; +              struct registered_waiter              { -                boost::shared_ptr<detail::future_object_base> future; +                boost::shared_ptr<detail::future_object_base> future_;                  detail::future_object_base::waiter_list::iterator wait_iterator;                  count_type index; -                registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_, +                registered_waiter(boost::shared_ptr<detail::future_object_base> const& a_future,                                    detail::future_object_base::waiter_list::iterator wait_iterator_,                                    count_type index_): -                    future(future_),wait_iterator(wait_iterator_),index(index_) +                    future_(a_future),wait_iterator(wait_iterator_),index(index_)                  {}              }; -             +              struct all_futures_lock              { -                count_type count; +#ifdef _MANAGED +                typedef std::ptrdiff_t count_type_portable; +#else +                typedef count_type count_type_portable; +#endif +                count_type_portable count;                  boost::scoped_array<boost::unique_lock<boost::mutex> > locks; -                 +                  all_futures_lock(std::vector<registered_waiter>& futures):                      count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])                  { -                    for(count_type i=0;i<count;++i) +                    for(count_type_portable i=0;i<count;++i)                      { -                        locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex); +#if defined __DECCXX || defined __SUNPRO_CC || defined __hpux +                        locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex).move(); +#else +                        locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex); +#endif                      }                  } -                 +                  void lock()                  {                      boost::lock(locks.get(),locks.get()+count);                  } -                 +                  void unlock()                  { -                    for(count_type i=0;i<count;++i) +                    for(count_type_portable i=0;i<count;++i)                      {                          locks[i].unlock();                      }                  }              }; -             +              boost::condition_variable_any cv;              std::vector<registered_waiter> futures;              count_type future_count; -             +          public:              future_waiter():                  future_count(0)              {} -             +              template<typename F>              void add(F& f)              { -                if(f.future) +                if(f.future_)                  { -                    futures.push_back(registered_waiter(f.future,f.future->register_external_waiter(cv),future_count)); +                    futures.push_back(registered_waiter(f.future_,f.future_->register_external_waiter(cv),future_count));                  }                  ++future_count;              } @@ -463,7 +655,7 @@ namespace boost                  {                      for(count_type i=0;i<futures.size();++i)                      { -                        if(futures[i].future->done) +                        if(futures[i].future_->done)                          {                              return futures[i].index;                          } @@ -471,21 +663,21 @@ namespace boost                      cv.wait(lk);                  }              } -             +              ~future_waiter()              {                  for(count_type i=0;i<futures.size();++i)                  { -                    futures[i].future->remove_external_waiter(futures[i].wait_iterator); +                    futures[i].future_->remove_external_waiter(futures[i].wait_iterator);                  }              } -             +          }; -         +      }      template <typename R> -    class unique_future; +    class BOOST_THREAD_FUTURE;      template <typename R>      class shared_future; @@ -495,13 +687,13 @@ namespace boost      {          BOOST_STATIC_CONSTANT(bool, value=false);      }; -     +      template<typename T> -    struct is_future_type<unique_future<T> > +    struct is_future_type<BOOST_THREAD_FUTURE<T> >      {          BOOST_STATIC_CONSTANT(bool, value=true);      }; -     +      template<typename T>      struct is_future_type<shared_future<T> >      { @@ -531,7 +723,7 @@ namespace boost          f2.wait();          f3.wait();      } -     +      template<typename F1,typename F2,typename F3,typename F4>      void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)      { @@ -556,7 +748,7 @@ namespace boost      {          if(begin==end)              return end; -         +          detail::future_waiter waiter;          for(Iterator current=begin;current!=end;++current)          { @@ -583,7 +775,7 @@ namespace boost          waiter.add(f3);          return waiter.wait();      } -     +      template<typename F1,typename F2,typename F3,typename F4>      unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)      { @@ -606,7 +798,7 @@ namespace boost          waiter.add(f5);          return waiter.wait();      } -     +      template <typename R>      class promise; @@ -614,14 +806,13 @@ namespace boost      class packaged_task;      template <typename R> -    class unique_future +    class BOOST_THREAD_FUTURE      { -        unique_future(unique_future & rhs);// = delete; -        unique_future& operator=(unique_future& rhs);// = delete; +    private:          typedef boost::shared_ptr<detail::future_object<R> > future_ptr; -         -        future_ptr future; + +        future_ptr future_;          friend class shared_future<R>;          friend class promise<R>; @@ -630,139 +821,151 @@ namespace boost          typedef typename detail::future_traits<R>::move_dest_type move_dest_type; -        unique_future(future_ptr future_): -            future(future_) +        BOOST_THREAD_FUTURE(future_ptr a_future): +            future_(a_future)          {}      public: +        BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)          typedef future_state::state state; -        unique_future() +        BOOST_THREAD_FUTURE()          {} -        -        ~unique_future() + +        ~BOOST_THREAD_FUTURE()          {} -#ifndef BOOST_NO_RVALUE_REFERENCES -        unique_future(unique_future && other) -        { -            future.swap(other.future); -        } -        unique_future& operator=(unique_future && other) -        { -            future=other.future; -            other.future.reset(); -            return *this; -        } -#else -        unique_future(boost::detail::thread_move_t<unique_future> other): -            future(other->future) +        BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT: +            future_(BOOST_THREAD_RV(other).future_)          { -            other->future.reset(); +            BOOST_THREAD_RV(other).future_.reset();          } -        unique_future& operator=(boost::detail::thread_move_t<unique_future> other) +        BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT          { -            future=other->future; -            other->future.reset(); +            future_=BOOST_THREAD_RV(other).future_; +            BOOST_THREAD_RV(other).future_.reset();              return *this;          } -        operator boost::detail::thread_move_t<unique_future>() +        shared_future<R> share()          { -            return boost::detail::thread_move_t<unique_future>(*this); +          return shared_future<R>(::boost::move(*this));          } -#endif -        void swap(unique_future& other) +        void swap(BOOST_THREAD_FUTURE& other)          { -            future.swap(other.future); +            future_.swap(other.future_);          }          // retrieving the value          move_dest_type get()          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            return future->get(); +            return future_->get();          } -         +          // functions to check state, and wait for ready -        state get_state() const +        state get_state() const BOOST_NOEXCEPT          { -            if(!future) +            if(!future_)              {                  return future_state::uninitialized;              } -            return future->get_state(); +            return future_->get_state();          } -         -        bool is_ready() const +        bool is_ready() const BOOST_NOEXCEPT          {              return get_state()==future_state::ready;          } -         -        bool has_exception() const + +        bool has_exception() const BOOST_NOEXCEPT          { -            return future && future->has_exception(); +            return future_ && future_->has_exception();          } -         -        bool has_value() const + +        bool has_value() const BOOST_NOEXCEPT          { -            return future && future->has_value(); +            return future_ && future_->has_value();          } -         + +        bool valid() const BOOST_NOEXCEPT +        { +            return future_ != 0; +        } + +          void wait() const          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            future->wait(false); +            future_->wait(false);          } -         +          template<typename Duration>          bool timed_wait(Duration const& rel_time) const          {              return timed_wait_until(boost::get_system_time()+rel_time);          } -         +          bool timed_wait_until(boost::system_time const& abs_time) const          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            return future->timed_wait_until(abs_time); +            return future_->timed_wait_until(abs_time);          } -         +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        future_status +        wait_for(const chrono::duration<Rep, Period>& rel_time) const +        { +          return wait_until(chrono::steady_clock::now() + rel_time); + +        } +        template <class Clock, class Duration> +        future_status +        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const +        { +          if(!future_) +          { +              boost::throw_exception(future_uninitialized()); +          } +          return future_->wait_until(abs_time); +        } +#endif      }; +    BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END +      template <typename R>      class shared_future      {          typedef boost::shared_ptr<detail::future_object<R> > future_ptr; -         -        future_ptr future; -//         shared_future(const unique_future<R>& other); -//         shared_future& operator=(const unique_future<R>& other); +        future_ptr future_;          friend class detail::future_waiter;          friend class promise<R>;          friend class packaged_task<R>; -         -        shared_future(future_ptr future_): -            future(future_) + +        shared_future(future_ptr a_future): +            future_(a_future)          {}      public: +        BOOST_THREAD_MOVABLE(shared_future) +          shared_future(shared_future const& other): -            future(other.future) +            future_(other.future_)          {}          typedef future_state::state state; @@ -775,396 +978,405 @@ namespace boost          shared_future& operator=(shared_future const& other)          { -            future=other.future; +            future_=other.future_;              return *this;          } -#ifndef BOOST_NO_RVALUE_REFERENCES -        shared_future(shared_future && other) +        shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT : +            future_(BOOST_THREAD_RV(other).future_)          { -            future.swap(other.future); +            BOOST_THREAD_RV(other).future_.reset();          } -        shared_future(unique_future<R> && other) +        shared_future(BOOST_THREAD_RV_REF_BEG BOOST_THREAD_FUTURE<R> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT : +            future_(BOOST_THREAD_RV(other).future_)          { -            future.swap(other.future); +            BOOST_THREAD_RV(other).future_.reset();          } -        shared_future& operator=(shared_future && other) +        shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT          { -            future.swap(other.future); -            other.future.reset(); +            future_.swap(BOOST_THREAD_RV(other).future_); +            BOOST_THREAD_RV(other).future_.reset();              return *this;          } -        shared_future& operator=(unique_future<R> && other) +        shared_future& operator=(BOOST_THREAD_RV_REF_BEG BOOST_THREAD_FUTURE<R> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT          { -            future.swap(other.future); -            other.future.reset(); +            future_.swap(BOOST_THREAD_RV(other).future_); +            BOOST_THREAD_RV(other).future_.reset();              return *this;          } -#else             -        shared_future(boost::detail::thread_move_t<shared_future> other): -            future(other->future) -        { -            other->future.reset(); -        } -//         shared_future(const unique_future<R> &) = delete; -        shared_future(boost::detail::thread_move_t<unique_future<R> > other): -            future(other->future) -        { -            other->future.reset(); -        } -        shared_future& operator=(boost::detail::thread_move_t<shared_future> other) -        { -            future.swap(other->future); -            other->future.reset(); -            return *this; -        } -        shared_future& operator=(boost::detail::thread_move_t<unique_future<R> > other) -        { -            future.swap(other->future); -            other->future.reset(); -            return *this; -        } - -        operator boost::detail::thread_move_t<shared_future>() -        { -            return boost::detail::thread_move_t<shared_future>(*this); -        } - -#endif -        void swap(shared_future& other) +        void swap(shared_future& other) BOOST_NOEXCEPT          { -            future.swap(other.future); +            future_.swap(other.future_);          }          // retrieving the value -        R get() +        typename detail::future_object<R>::shared_future_get_result_type get()          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            return future->get(); +            return future_->get_sh();          } -         +          // functions to check state, and wait for ready -        state get_state() const +        state get_state() const  BOOST_NOEXCEPT          { -            if(!future) +            if(!future_)              {                  return future_state::uninitialized;              } -            return future->get_state(); +            return future_->get_state();          } -         -        bool is_ready() const +        bool valid() const  BOOST_NOEXCEPT +        { +            return future_ != 0; +        } + +        bool is_ready() const  BOOST_NOEXCEPT          {              return get_state()==future_state::ready;          } -         -        bool has_exception() const + +        bool has_exception() const BOOST_NOEXCEPT          { -            return future && future->has_exception(); +            return future_ && future_->has_exception();          } -         -        bool has_value() const + +        bool has_value() const BOOST_NOEXCEPT          { -            return future && future->has_value(); +            return future_ && future_->has_value();          }          void wait() const          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            future->wait(false); +            future_->wait(false);          } -         +          template<typename Duration>          bool timed_wait(Duration const& rel_time) const          {              return timed_wait_until(boost::get_system_time()+rel_time);          } -         +          bool timed_wait_until(boost::system_time const& abs_time) const          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            return future->timed_wait_until(abs_time); +            return future_->timed_wait_until(abs_time);          } -         +#ifdef BOOST_THREAD_USES_CHRONO + +        template <class Rep, class Period> +        future_status +        wait_for(const chrono::duration<Rep, Period>& rel_time) const +        { +          return wait_until(chrono::steady_clock::now() + rel_time); + +        } +        template <class Clock, class Duration> +        future_status +        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const +        { +          if(!future_) +          { +              boost::throw_exception(future_uninitialized()); +          } +          return future_->wait_until(abs_time); +        } +#endif      }; +    BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END +      template <typename R>      class promise      {          typedef boost::shared_ptr<detail::future_object<R> > future_ptr; -         -        future_ptr future; + +        future_ptr future_;          bool future_obtained; -         -        promise(promise & rhs);// = delete; -        promise & operator=(promise & rhs);// = delete;          void lazy_init()          { -            if(!atomic_load(&future)) +#if defined BOOST_THREAD_PROMISE_LAZY +            if(!atomic_load(&future_))              {                  future_ptr blank; -                atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<R>)); +                atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object<R>));              } +#endif          } -         +      public: -//         template <class Allocator> explicit promise(Allocator a); +        BOOST_THREAD_MOVABLE_ONLY(promise) +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +        template <class Allocator> +        promise(boost::allocator_arg_t, Allocator a) +        { +          typedef typename Allocator::template rebind<detail::future_object<R> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; +          future_ = future_ptr(::new(a2.allocate(1)) detail::future_object<R>(), D(a2, 1) ); +          future_obtained = false; +        } +#endif          promise(): -            future(),future_obtained(false) +#if defined BOOST_THREAD_PROMISE_LAZY +            future_(), +#else +            future_(new detail::future_object<R>()), +#endif +            future_obtained(false)          {} -         +          ~promise()          { -            if(future) +            if(future_)              { -                boost::lock_guard<boost::mutex> lock(future->mutex); +                boost::lock_guard<boost::mutex> lock(future_->mutex); -                if(!future->done) +                if(!future_->done)                  { -                    future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); +                    future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));                  }              }          }          // Assignment -#ifndef BOOST_NO_RVALUE_REFERENCES -        promise(promise && rhs): -            future_obtained(rhs.future_obtained) +        promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT : +            future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)          { -            future.swap(rhs.future); -            rhs.future_obtained=false; +            BOOST_THREAD_RV(rhs).future_.reset(); +            BOOST_THREAD_RV(rhs).future_obtained=false;          } -        promise & operator=(promise&& rhs) +        promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT          { -            future.swap(rhs.future); -            future_obtained=rhs.future_obtained; -            rhs.future.reset(); -            rhs.future_obtained=false; -            return *this; -        } -#else -        promise(boost::detail::thread_move_t<promise> rhs): -            future(rhs->future),future_obtained(rhs->future_obtained) -        { -            rhs->future.reset(); -            rhs->future_obtained=false; -        } -        promise & operator=(boost::detail::thread_move_t<promise> rhs) -        { -            future=rhs->future; -            future_obtained=rhs->future_obtained; -            rhs->future.reset(); -            rhs->future_obtained=false; +            future_=BOOST_THREAD_RV(rhs).future_; +            future_obtained=BOOST_THREAD_RV(rhs).future_obtained; +            BOOST_THREAD_RV(rhs).future_.reset(); +            BOOST_THREAD_RV(rhs).future_obtained=false;              return *this;          } -        operator boost::detail::thread_move_t<promise>() -        { -            return boost::detail::thread_move_t<promise>(*this); -        } -#endif    -                  void swap(promise& other)          { -            future.swap(other.future); +            future_.swap(other.future_);              std::swap(future_obtained,other.future_obtained);          }          // Result retrieval -        unique_future<R> get_future() +        BOOST_THREAD_FUTURE<R> get_future()          {              lazy_init(); -            if(future_obtained) +            if (future_.get()==0) +            { +                boost::throw_exception(promise_moved()); +            } +            if (future_obtained)              {                  boost::throw_exception(future_already_retrieved());              }              future_obtained=true; -            return unique_future<R>(future); +            return BOOST_THREAD_FUTURE<R>(future_);          }          void set_value(typename detail::future_traits<R>::source_reference_type r)          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_finished_with_result_internal(r); +            future_->mark_finished_with_result_internal(r);          }  //         void set_value(R && r);          void set_value(typename detail::future_traits<R>::rvalue_source_type r)          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r)); +            future_->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r));          }          void set_exception(boost::exception_ptr p)          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_exceptional_finish_internal(p); +            future_->mark_exceptional_finish_internal(p);          } +        // setting the result with deferred notification +        //void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED +        //void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED +        //void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED +          template<typename F>          void set_wait_callback(F f)          {              lazy_init(); -            future->set_wait_callback(f,this); +            future_->set_wait_callback(f,this);          } -         +      };      template <>      class promise<void>      {          typedef boost::shared_ptr<detail::future_object<void> > future_ptr; -         -        future_ptr future; + +        future_ptr future_;          bool future_obtained; -         -        promise(promise & rhs);// = delete; -        promise & operator=(promise & rhs);// = delete;          void lazy_init()          { -            if(!atomic_load(&future)) +#if defined BOOST_THREAD_PROMISE_LAZY +            if(!atomic_load(&future_))              {                  future_ptr blank; -                atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<void>)); +                atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object<void>));              } +#endif          }      public: -//         template <class Allocator> explicit promise(Allocator a); +        BOOST_THREAD_MOVABLE_ONLY(promise) + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +        template <class Allocator> +        promise(boost::allocator_arg_t, Allocator a) +        { +          typedef typename Allocator::template rebind<detail::future_object<void> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; +          future_ = future_ptr(::new(a2.allocate(1)) detail::future_object<void>(), D(a2, 1) ); +          future_obtained = false; +        } +#endif          promise(): -            future(),future_obtained(false) +#if defined BOOST_THREAD_PROMISE_LAZY +            future_(), +#else +            future_(new detail::future_object<void>), +#endif +            future_obtained(false)          {} -         +          ~promise()          { -            if(future) +            if(future_)              { -                boost::lock_guard<boost::mutex> lock(future->mutex); +                boost::lock_guard<boost::mutex> lock(future_->mutex); -                if(!future->done) +                if(!future_->done)                  { -                    future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); +                    future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));                  }              }          }          // Assignment -#ifndef BOOST_NO_RVALUE_REFERENCES -        promise(promise && rhs): -            future_obtained(rhs.future_obtained) -        { -            future.swap(rhs.future); -            rhs.future_obtained=false; -        } -        promise & operator=(promise&& rhs) +        promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT : +            future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)          { -            future.swap(rhs.future); -            future_obtained=rhs.future_obtained; -            rhs.future.reset(); -            rhs.future_obtained=false; -            return *this; -        } -#else -        promise(boost::detail::thread_move_t<promise> rhs): -            future(rhs->future),future_obtained(rhs->future_obtained) -        { -            rhs->future.reset(); -            rhs->future_obtained=false; +          // we need to release the future as shared_ptr doesn't implements move semantics +            BOOST_THREAD_RV(rhs).future_.reset(); +            BOOST_THREAD_RV(rhs).future_obtained=false;          } -        promise & operator=(boost::detail::thread_move_t<promise> rhs) + +        promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT          { -            future=rhs->future; -            future_obtained=rhs->future_obtained; -            rhs->future.reset(); -            rhs->future_obtained=false; +            future_=BOOST_THREAD_RV(rhs).future_; +            future_obtained=BOOST_THREAD_RV(rhs).future_obtained; +            BOOST_THREAD_RV(rhs).future_.reset(); +            BOOST_THREAD_RV(rhs).future_obtained=false;              return *this;          } -        operator boost::detail::thread_move_t<promise>() -        { -            return boost::detail::thread_move_t<promise>(*this); -        } -#endif -                  void swap(promise& other)          { -            future.swap(other.future); +            future_.swap(other.future_);              std::swap(future_obtained,other.future_obtained);          }          // Result retrieval -        unique_future<void> get_future() +        BOOST_THREAD_FUTURE<void> get_future()          {              lazy_init(); -             + +            if (future_.get()==0) +            { +                boost::throw_exception(promise_moved()); +            }              if(future_obtained)              {                  boost::throw_exception(future_already_retrieved());              }              future_obtained=true; -            return unique_future<void>(future); +            return BOOST_THREAD_FUTURE<void>(future_);          }          void set_value()          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_finished_with_result_internal(); +            future_->mark_finished_with_result_internal();          }          void set_exception(boost::exception_ptr p)          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_exceptional_finish_internal(p); +            future_->mark_exceptional_finish_internal(p);          }          template<typename F>          void set_wait_callback(F f)          {              lazy_init(); -            future->set_wait_callback(f,this); +            future_->set_wait_callback(f,this);          } -         +      }; +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +    namespace container +    { +      template <class R, class Alloc> +      struct uses_allocator<promise<R> , Alloc> : true_type +      { +      }; +    } +#endif + +    BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END +      namespace detail      {          template<typename R> @@ -1177,6 +1389,10 @@ namespace boost                  started(false)              {} +            void reset() +            { +              started=false; +            }              void run()              {                  { @@ -1199,30 +1415,44 @@ namespace boost                      this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()));                  }              } -             -             + +              virtual void do_run()=0;          }; -         -         + + + +          template<typename R,typename F>          struct task_object:              task_base<R>          { +        private: +          task_object(task_object&); +        public:              F f;              task_object(F const& f_):                  f(f_)              {} -            task_object(boost::detail::thread_move_t<F> f_): -                f(f_) +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +            task_object(BOOST_THREAD_RV_REF(F) f_): +              f(boost::forward<F>(f_)) +            {} +#else +            task_object(BOOST_THREAD_RV_REF(F) f_): +                f(boost::move(f_))              {} -             +#endif              void do_run()              {                  try                  {                      this->mark_finished_with_result(f());                  } +                catch(thread_interrupted& ) +                { +                    this->mark_interrupted_finish(); +                }                  catch(...)                  {                      this->mark_exceptional_finish(); @@ -1230,18 +1460,55 @@ namespace boost              }          }; +            template<typename R> +            struct task_object<R,R (*)()>: +                task_base<R> +            { +            private: +              task_object(task_object&); +            public: +                R (*f)(); +                task_object(R (*f_)()): +                    f(f_) +                {} +                void do_run() +                { +                    try +                    { +                        this->mark_finished_with_result(f()); +                    } +                    catch(thread_interrupted& ) +                    { +                        this->mark_interrupted_finish(); +                    } +                    catch(...) +                    { +                        this->mark_exceptional_finish(); +                    } +                } +            }; +          template<typename F>          struct task_object<void,F>:              task_base<void>          { +        private: +          task_object(task_object&); +        public:              F f;              task_object(F const& f_):                  f(f_)              {} -            task_object(boost::detail::thread_move_t<F> f_): -                f(f_) +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +            task_object(BOOST_THREAD_RV_REF(F) f_): +              f(boost::forward<F>(f_))              {} -             +#else +            task_object(BOOST_THREAD_RV_REF(F) f_): +                f(boost::move(f_)) +            {} +#endif +              void do_run()              {                  try @@ -1249,6 +1516,39 @@ namespace boost                      f();                      this->mark_finished_with_result();                  } +                catch(thread_interrupted& ) +                { +                    this->mark_interrupted_finish(); +                } +                catch(...) +                { +                    this->mark_exceptional_finish(); +                } +            } +        }; + +        template<> +        struct task_object<void,void (*)()>: +            task_base<void> +        { +        private: +          task_object(task_object&); +        public: +            void (*f)(); +            task_object(void (*f_)()): +                f(f_) +            {} +            void do_run() +            { +                try +                { +                  f(); +                  this->mark_finished_with_result(); +                } +                catch(thread_interrupted& ) +                { +                    this->mark_interrupted_finish(); +                }                  catch(...)                  {                      this->mark_exceptional_finish(); @@ -1257,41 +1557,92 @@ namespace boost          };      } -          template<typename R>      class packaged_task      { +        typedef boost::shared_ptr<detail::task_base<R> > task_ptr;          boost::shared_ptr<detail::task_base<R> > task;          bool future_obtained; -        packaged_task(packaged_task&);// = delete; -        packaged_task& operator=(packaged_task&);// = delete; -              public: +        typedef R result_type; +        BOOST_THREAD_MOVABLE_ONLY(packaged_task) +          packaged_task():              future_obtained(false)          {} -         +          // construction and destruction -        template <class F> -        explicit packaged_task(F const& f): -            task(new detail::task_object<R,F>(f)),future_obtained(false) -        {} +          explicit packaged_task(R(*f)()):              task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)          {} -         +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +        template <class F> +        explicit packaged_task(BOOST_THREAD_RV_REF(F) f): +            task(new detail::task_object<R, +                typename remove_cv<typename remove_reference<F>::type>::type +                >(boost::forward<F>(f))),future_obtained(false) +        {} +#else          template <class F> -        explicit packaged_task(boost::detail::thread_move_t<F> f): +        explicit packaged_task(F const& f):              task(new detail::task_object<R,F>(f)),future_obtained(false)          {} +        template <class F> +        explicit packaged_task(BOOST_THREAD_RV_REF(F) f): +            task(new detail::task_object<R,F>(boost::move(f))),future_obtained(false) +        {} +#endif -//         template <class F, class Allocator> -//         explicit packaged_task(F const& f, Allocator a); -//         template <class F, class Allocator> -//         explicit packaged_task(F&& f, Allocator a); +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +        template <class Allocator> +        packaged_task(boost::allocator_arg_t, Allocator a, R(*f)()) +        { +          typedef R(*FR)(); +          typedef typename Allocator::template rebind<detail::task_object<R,FR> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; +          task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,FR>(f), D(a2, 1) ); +          future_obtained = false; +        } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +        template <class F, class Allocator> +        packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f) +        { +          typedef typename remove_cv<typename remove_reference<F>::type>::type FR; +          typedef typename Allocator::template rebind<detail::task_object<R,FR> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; + +          task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,FR>(boost::forward<F>(f)), D(a2, 1) ); +          future_obtained = false; +        } +#else +        template <class F, class Allocator> +        packaged_task(boost::allocator_arg_t, Allocator a, const F& f) +        { +          typedef typename Allocator::template rebind<detail::task_object<R,F> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; + +          task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,F>(f), D(a2, 1) ); +          future_obtained = false; +        } +        template <class F, class Allocator> +        packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f) +        { +          typedef typename Allocator::template rebind<detail::task_object<R,F> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; + +          task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,F>(boost::move(f)), D(a2, 1) ); +          future_obtained = false; +        } +#endif //BOOST_NO_CXX11_RVALUE_REFERENCES +#endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS          ~packaged_task()          { @@ -1302,46 +1653,39 @@ namespace boost          }          // assignment -#ifndef BOOST_NO_RVALUE_REFERENCES -        packaged_task(packaged_task&& other): -            future_obtained(other.future_obtained) +        packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT : +            future_obtained(BOOST_THREAD_RV(other).future_obtained)          { -            task.swap(other.task); -            other.future_obtained=false; +            task.swap(BOOST_THREAD_RV(other).task); +            BOOST_THREAD_RV(other).future_obtained=false;          } -        packaged_task& operator=(packaged_task&& other) +        packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT          { -            packaged_task temp(static_cast<packaged_task&&>(other)); +            packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));              swap(temp);              return *this;          } -#else -        packaged_task(boost::detail::thread_move_t<packaged_task> other): -            future_obtained(other->future_obtained) -        { -            task.swap(other->task); -            other->future_obtained=false; -        } -        packaged_task& operator=(boost::detail::thread_move_t<packaged_task> other) -        { -            packaged_task temp(other); -            swap(temp); -            return *this; -        } -        operator boost::detail::thread_move_t<packaged_task>() + +        void reset()          { -            return boost::detail::thread_move_t<packaged_task>(*this); +            if (!valid()) +                throw future_error(system::make_error_code(future_errc::no_state)); +            task->reset(); +            future_obtained=false;          } -#endif -        void swap(packaged_task& other) +        void swap(packaged_task& other) BOOST_NOEXCEPT          {              task.swap(other.task);              std::swap(future_obtained,other.future_obtained);          } +        bool valid() const BOOST_NOEXCEPT +        { +          return task.get()!=0; +        }          // result retrieval -        unique_future<R> get_future() +        BOOST_THREAD_FUTURE<R> get_future()          {              if(!task)              { @@ -1350,14 +1694,16 @@ namespace boost              else if(!future_obtained)              {                  future_obtained=true; -                return unique_future<R>(task); +                return BOOST_THREAD_FUTURE<R>(task);              }              else              {                  boost::throw_exception(future_already_retrieved());              } +            return BOOST_THREAD_FUTURE<R>(); +          } -         +          // execution          void operator()() @@ -1374,10 +1720,149 @@ namespace boost          {              task->set_wait_callback(f,this);          } -         +      }; -} +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +    namespace container +    { +      template <class R, class Alloc> +      struct uses_allocator<packaged_task<R>, Alloc> +        : public true_type {}; +    } +#endif + +    BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END + + +        template <class R> +        BOOST_THREAD_FUTURE<R> +        async(launch policy, R(*f)()) +        { +            if (int(policy) & int(launch::async)) +            { +              packaged_task<R> pt( f ); + +              BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +              boost::thread( boost::move(pt) ).detach(); +              return ::boost::move(ret); +            } +            else if (int(policy) & int(launch::deferred)) +            { +              packaged_task<R> pt( f ); +              BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +              return ::boost::move(ret); +            } else { +              BOOST_THREAD_FUTURE<R> ret; +              return ::boost::move(ret); +            } +        } + +        template <class R> +        BOOST_THREAD_FUTURE<R> +        async(R(*f)()) +        { +            return async(launch::any, f); +        } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +    template <class F> +    BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type> +    async(launch policy, BOOST_THREAD_FWD_REF(F)  f) +    { +        typedef typename boost::result_of<typename decay<F>::type()>::type R; +        if (int(policy) & int(launch::async)) +        { +          packaged_task<R> pt( boost::forward<F>(f) ); + +          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +          boost::thread( boost::move(pt) ).detach(); +          return ::boost::move(ret); +        } +        else if (int(policy) & int(launch::deferred)) +        { +          packaged_task<R> pt( boost::forward<F>(f) ); + +          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +          return ::boost::move(ret); +        } else { +          BOOST_THREAD_FUTURE<R> ret; +          return ::boost::move(ret); +        } +    } +    template <class F> +    BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type> +    async(BOOST_THREAD_RV_REF(F) f) +    { +        return async(launch::any, boost::forward<F>(f)); +    } +#else + +//    template <class F> +//    BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type> +//    async(launch policy, F const& f) +//    { +//        typedef typename boost::result_of<typename decay<F>::type()>::type R; +//        if (int(policy) & int(launch::async)) +//        { +//          packaged_task<R> pt( f ); +// +//          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +//          boost::thread( boost::move(pt) ).detach(); +//          return ::boost::move(ret); +//        } +//        else if (int(policy) & int(launch::deferred)) +//        { +//          packaged_task<R> pt( f ); +// +//          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +//          return ::boost::move(ret); +//        } else { +//          BOOST_THREAD_FUTURE<R> ret; +//          return ::boost::move(ret); +//        } +//    } +//    template <class F> +//    BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type> +//    async(F const& f) +//    { +//        return async(launch::any, f); +//    } + +    template <class F> +    BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type> +    async(launch policy, BOOST_THREAD_FWD_REF(F)  f) +    { +        typedef typename boost::result_of<typename decay<F>::type()>::type R; +        if (int(policy) & int(launch::async)) +        { +          packaged_task<R> pt( boost::forward<F>(f) ); + +          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +          boost::thread( boost::move(pt) ).detach(); +          return ::boost::move(ret); +        } +        else if (int(policy) & int(launch::deferred)) +        { +          packaged_task<R> pt( boost::forward<F>(f) ); + +          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +          return ::boost::move(ret); +        } else { +          BOOST_THREAD_FUTURE<R> ret; +          return ::boost::move(ret); +        } +    } +    template <class F> +    BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type> +    async(BOOST_THREAD_FWD_REF(F) f) +    { +        return async(launch::any, boost::forward<F>(f)); +    }  #endif + +} + +#endif // BOOST_NO_EXCEPTION +#endif // header | 
 Swift
 Swift