summaryrefslogtreecommitdiff
path: root/boost/thread/future.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/thread/future.hpp')
-rw-r--r--boost/thread/future.hpp970
1 files changed, 615 insertions, 355 deletions
diff --git a/boost/thread/future.hpp b/boost/thread/future.hpp
index bd87158338..8cad994de5 100644
--- a/boost/thread/future.hpp
+++ b/boost/thread/future.hpp
@@ -1,4 +1,5 @@
// (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.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_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();
+
+ namespace system
+ {
+ inline BOOST_THREAD_DECL
+ error_code
+ make_error_code(future_errc e)
+ {
+ return error_code(underlying_cast<int>(e), boost::future_category());
+ }
+
+ inline BOOST_THREAD_DECL
+ error_condition
+ make_error_condition(future_errc e)
+ {
+ 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_;
+ }
+
+ //virtual ~future_error() BOOST_NOEXCEPT;
+ };
+
+ class BOOST_SYMBOL_VISIBLE future_uninitialized:
+ public future_error
{
public:
future_uninitialized():
- std::logic_error("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))
+ //std::logic_error("Task already started")
{}
};
- 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))
+ //std::logic_error("Task moved")
+ {}
+ };
+
+ class promise_moved:
+ public future_error
+ {
+ public:
+ promise_moved():
+ future_error(system::make_error_code(future_errc::no_state))
+ //std::logic_error("Promise moved")
+ {}
+ };
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()
{}
@@ -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);
@@ -186,6 +313,25 @@ 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>
@@ -226,14 +377,20 @@ namespace boost
#ifndef BOOST_NO_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));
@@ -241,7 +398,7 @@ namespace boost
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)
@@ -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,6 +455,7 @@ 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;
@@ -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,7 +521,7 @@ namespace boost
struct future_object<void>:
detail::future_object_base
{
- typedef void move_dest_type;
+ typedef void shared_future_get_result_type;
future_object()
{}
@@ -373,7 +541,10 @@ namespace boost
{
wait();
}
-
+ void get_sh()
+ {
+ wait();
+ }
future_state::state get_state()
{
boost::lock_guard<boost::mutex> guard(mutex);
@@ -386,12 +557,22 @@ 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;
@@ -399,38 +580,32 @@ namespace boost
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
{
-#ifdef _MANAGED
- typedef std::ptrdiff_t count_type_portable;
-#else
- typedef count_type count_type_portable;
-#endif
- count_type_portable count;
-
+ count_type 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_portable i=0;i<count;++i)
+ for(count_type i=0;i<count;++i)
{
#if defined __DECCXX || defined __SUNPRO_CC
- locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex).move();
+ locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex).move();
#else
- locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex);
+ locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex);
#endif
}
}
@@ -442,7 +617,7 @@ namespace boost
void unlock()
{
- for(count_type_portable i=0;i<count;++i)
+ for(count_type i=0;i<count;++i)
{
locks[i].unlock();
}
@@ -461,9 +636,9 @@ namespace boost
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;
}
@@ -475,7 +650,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;
}
@@ -488,7 +663,7 @@ namespace boost
{
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);
}
}
@@ -497,7 +672,7 @@ namespace boost
}
template <typename R>
- class unique_future;
+ class BOOST_THREAD_FUTURE;
template <typename R>
class shared_future;
@@ -509,7 +684,7 @@ namespace boost
};
template<typename T>
- struct is_future_type<unique_future<T> >
+ struct is_future_type<BOOST_THREAD_FUTURE<T> >
{
BOOST_STATIC_CONSTANT(bool, value=true);
};
@@ -626,14 +801,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>;
@@ -642,99 +816,92 @@ 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>
@@ -745,43 +912,55 @@ namespace boost
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
};
-#ifdef BOOST_NO_RVALUE_REFERENCES
- template <typename T>
- struct has_move_emulation_enabled_aux<unique_future<T> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
-#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;
@@ -794,112 +973,85 @@ 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)
- {
- future.swap(other.future);
- }
- shared_future(unique_future<R> && other)
- {
- future.swap(other.future);
- }
- shared_future& operator=(shared_future && other)
- {
- future.swap(other.future);
- other.future.reset();
- return *this;
- }
- shared_future& operator=(unique_future<R> && other)
+ shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
+ future_(BOOST_THREAD_RV(other).future_)
{
- future.swap(other.future);
- other.future.reset();
- return *this;
+ BOOST_THREAD_RV(other).future_.reset();
}
-#else
- shared_future(boost::detail::thread_move_t<shared_future> other):
- future(other->future)
+ 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_)
{
- other->future.reset();
+ BOOST_THREAD_RV(other).future_.reset();
}
-// shared_future(const unique_future<R> &) = delete;
- shared_future(boost::detail::thread_move_t<unique_future<R> > other):
- future(other->future)
+ shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
{
- other->future.reset();
- }
- shared_future& operator=(boost::detail::thread_move_t<shared_future> other)
- {
- 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=(boost::detail::thread_move_t<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;
}
- 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
- //typename detail::future_object<R>::move_dest_type get()
- 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 valid() const BOOST_NOEXCEPT
+ {
+ return future_ != 0;
+ }
- 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();
}
void wait() const
{
- if(!future)
+ if(!future_)
{
boost::throw_exception(future_uninitialized());
}
- future->wait(false);
+ future_->wait(false);
}
template<typename Duration>
@@ -910,157 +1062,168 @@ namespace boost
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);
-#ifdef BOOST_NO_RVALUE_REFERENCES
- template <typename T>
- struct has_move_emulation_enabled_aux<shared_future<T> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
+ }
+ 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;
+ 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;
}
-#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;
- 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);
}
template<typename F>
void set_wait_callback(F f)
{
lazy_init();
- future->set_wait_callback(f,this);
+ future_->set_wait_callback(f,this);
}
};
@@ -1070,135 +1233,140 @@ namespace boost
{
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)
- {
- 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)
+ promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
+ future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
{
- future=rhs->future;
- future_obtained=rhs->future_obtained;
- rhs->future.reset();
- rhs->future_obtained=false;
- return *this;
+ // 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;
}
- operator boost::detail::thread_move_t<promise>()
+ promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
{
- return boost::detail::thread_move_t<promise>(*this);
+ 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;
}
-#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);
}
};
-#ifdef BOOST_NO_RVALUE_REFERENCES
- template <typename T>
- struct has_move_emulation_enabled_aux<promise<T> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
+#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>
@@ -1211,6 +1379,10 @@ namespace boost
started(false)
{}
+ void reset()
+ {
+ started=false;
+ }
void run()
{
{
@@ -1243,26 +1415,32 @@ namespace boost
struct task_object:
task_base<R>
{
+ private:
+ task_object(task_object&);
+ public:
F f;
task_object(F const& f_):
f(f_)
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
- task_object(F&& f_):
- f(f_)
+ task_object(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::forward<F>(f_))
{}
#else
- task_object(boost::detail::thread_move_t<F> f_):
- f(f_)
+ 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();
@@ -1274,17 +1452,20 @@ namespace boost
struct task_object<void,F>:
task_base<void>
{
+ private:
+ task_object(task_object&);
+ public:
F f;
task_object(F const& f_):
f(f_)
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
- task_object(F&& f_):
- f(f_)
+ task_object(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::forward<F>(f_))
{}
#else
- task_object(boost::detail::thread_move_t<F> f_):
- f(f_)
+ task_object(BOOST_THREAD_RV_REF(F) f_):
+ f(boost::move(f_))
{}
#endif
@@ -1295,6 +1476,10 @@ namespace boost
f();
this->mark_finished_with_result();
}
+ catch(thread_interrupted& )
+ {
+ this->mark_interrupted_finish();
+ }
catch(...)
{
this->mark_exceptional_finish();
@@ -1304,47 +1489,91 @@ 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_RVALUE_REFERENCES
template <class F>
- explicit packaged_task(F&& f):
- task(new detail::task_object<R,F>(f)),future_obtained(false)
+ 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_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_RVALUE_REFERENCES
+#endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
~packaged_task()
{
@@ -1355,46 +1584,39 @@ namespace boost
}
// assignment
-#ifndef BOOST_NO_RVALUE_REFERENCES
- packaged_task(packaged_task&& other):
- future_obtained(other.future_obtained)
- {
- task.swap(other.task);
- other.future_obtained=false;
- }
- packaged_task& operator=(packaged_task&& other)
+ packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT :
+ future_obtained(BOOST_THREAD_RV(other).future_obtained)
{
- packaged_task temp(static_cast<packaged_task&&>(other));
- swap(temp);
- return *this;
+ task.swap(BOOST_THREAD_RV(other).task);
+ BOOST_THREAD_RV(other).future_obtained=false;
}
-#else
- packaged_task(boost::detail::thread_move_t<packaged_task> other):
- future_obtained(other->future_obtained)
+ packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
{
- task.swap(other->task);
- other->future_obtained=false;
- }
- packaged_task& operator=(boost::detail::thread_move_t<packaged_task> other)
- {
- packaged_task temp(other);
+ packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(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)
{
@@ -1403,12 +1625,14 @@ 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>();
+
}
@@ -1430,14 +1654,50 @@ namespace boost
};
-#ifdef BOOST_NO_RVALUE_REFERENCES
- template <typename T>
- struct has_move_emulation_enabled_aux<packaged_task<T> >
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
+#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 F>
+// BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
+// async(launch policy, F f)
+// {
+// typedef typename boost::result_of<F()>::type R;
+// typedef BOOST_THREAD_FUTURE<R> future;
+// if (int(policy) & int(launch::async))
+// {
+// packaged_task<R> pt( f );
+//
+// BOOST_THREAD_FUTURE 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 ret = pt.get_future();
+// return ::boost::move(ret);
+// }
+// }
+//
+// template <class F>
+// BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
+// async(F f)
+// {
+// return async(launch::any, f);
+// }
-#endif
+
+}
+
+#endif // BOOST_NO_EXCEPTION
+#endif // header