|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r80755 - in trunk: boost/thread boost/thread/detail libs/thread/doc libs/thread/test libs/thread/test/sync/futures/async libs/thread/test/sync/futures/future libs/thread/test/sync/futures/packaged_task libs/thread/test/sync/futures/promise libs/thread/test/threads/thread/constr
From: vicente.botet_at_[hidden]
Date: 2012-09-29 12:31:30
Author: viboes
Date: 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
New Revision: 80755
URL: http://svn.boost.org/trac/boost/changeset/80755
Log:
Thread: version 4: Added variadic templates for packed_task cons, async, thread cons + added make_future + future::get() can be called just once
Added:
trunk/libs/thread/test/sync/futures/promise/set_exception_pass.cpp (contents, props changed)
trunk/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp (contents, props changed)
trunk/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp (contents, props changed)
trunk/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp (contents, props changed)
trunk/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp (contents, props changed)
Text files modified:
trunk/boost/thread/detail/config.hpp | 32 ++
trunk/boost/thread/detail/thread.hpp | 188 +++++++++++++
trunk/boost/thread/future.hpp | 549 ++++++++++++++++++++++++++++++++-------
trunk/libs/thread/doc/changes.qbk | 52 +++
trunk/libs/thread/doc/future_ref.qbk | 55 ++-
trunk/libs/thread/doc/mutex_concepts.qbk | 6
trunk/libs/thread/doc/thread.qbk | 2
trunk/libs/thread/test/Jamfile.v2 | 23 +
trunk/libs/thread/test/sync/futures/async/async_pass.cpp | 17
trunk/libs/thread/test/sync/futures/future/get_pass.cpp | 163 +++++++----
trunk/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp | 20 +
trunk/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp | 12
trunk/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp | 12
trunk/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp | 10
trunk/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp | 55 +++
trunk/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp | 39 ++
trunk/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp | 13
trunk/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp | 15
trunk/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp | 15
trunk/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp | 15
trunk/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp | 15
trunk/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp | 135 ++++++++-
trunk/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp | 12
trunk/libs/thread/test/sync/futures/packaged_task/types_pass.cpp | 2
trunk/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp | 9
trunk/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp | 7
26 files changed, 1168 insertions(+), 305 deletions(-)
Modified: trunk/boost/thread/detail/config.hpp
==============================================================================
--- trunk/boost/thread/detail/config.hpp (original)
+++ trunk/boost/thread/detail/config.hpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -15,6 +15,7 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
+#include <boost/thread/detail/platform.hpp>
#ifdef BOOST_NO_NOEXCEPT
# define BOOST_THREAD_NOEXCEPT_OR_THROW throw()
@@ -49,8 +50,8 @@
#if !defined BOOST_THREAD_VERSION
#define BOOST_THREAD_VERSION 2
#else
-#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3
-#error "BOOST_THREAD_VERSION must be 2 or 3"
+#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4
+#error "BOOST_THREAD_VERSION must be 2, 3 or 4"
#endif
#endif
@@ -76,7 +77,7 @@
#endif
#endif
-#if BOOST_THREAD_VERSION==3
+#if BOOST_THREAD_VERSION>=3
#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 \
&& ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11
#define BOOST_THREAD_PROVIDES_ONCE_CXX11
@@ -120,6 +121,31 @@
#endif
+#if BOOST_THREAD_VERSION>=4
+
+#if ! defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKAGED_TASK
+#define BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#endif
+
+#if ! defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_VARIADIC_THREAD
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
+ defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#define BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+#endif
+
+#if ! defined BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
+#define BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+#endif
+
+
+#endif
+#endif
+
// BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN is defined if BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS \
&& ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
Modified: trunk/boost/thread/detail/thread.hpp
==============================================================================
--- trunk/boost/thread/detail/thread.hpp (original)
+++ trunk/boost/thread/detail/thread.hpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -6,6 +6,15 @@
// (C) Copyright 2007-10 Anthony Williams
// (C) Copyright 20011-12 Vicente J. Botet Escriba
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+// The code taking care of thread creation and invoke have been taken from libcxx.
+//===----------------------------------------------------------------------===//
#include <boost/thread/detail/config.hpp>
#include <boost/thread/exceptions.hpp>
#ifndef BOOST_NO_IOSTREAM
@@ -36,6 +45,9 @@
#include <boost/chrono/ceil.hpp>
#endif
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#include <tuple>
+#endif
#include <boost/config/abi_prefix.hpp>
#ifdef BOOST_MSVC
@@ -48,6 +60,126 @@
namespace detail
{
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+ // __make_tuple_indices
+
+ template <std::size_t...> struct tuple_indices {};
+
+ template <std::size_t Sp, class IntTuple, std::size_t Ep>
+ struct make_indices_imp;
+
+ template <std::size_t Sp, std::size_t ...Indices, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<Indices...>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<Indices..., Sp>, Ep>::type type;
+ };
+
+ template <std::size_t Ep, std::size_t ...Indices>
+ struct make_indices_imp<Ep, tuple_indices<Indices...>, Ep>
+ {
+ typedef tuple_indices<Indices...> type;
+ };
+
+ template <std::size_t Ep, std::size_t Sp = 0>
+ struct make_tuple_indices
+ {
+ static_assert(Sp <= Ep, "make_tuple_indices input error");
+ typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
+ };
+
+
+// // bullets 1 and 2
+//
+// template <class Fp, class A0, class ...Args>
+// inline
+// auto
+// invoke(Fp&& f, A0&& a0, Args&& ...args)
+// -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...))
+// {
+// return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+// }
+//
+// template <class Fp, class A0, class ...Args>
+// inline
+// auto
+// invoke(Fp&& f, A0&& a0, Args&& ...args)
+// -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...))
+// {
+// return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+// }
+//
+// // bullets 3 and 4
+//
+// template <class Fp, class A0>
+// inline
+// auto
+// invoke(Fp&& f, A0&& a0)
+// -> decltype(boost::forward<A0>(a0).*f)
+// {
+// return boost::forward<A0>(a0).*f;
+// }
+//
+// template <class Fp, class A0>
+// inline
+// auto
+// invoke(Fp&& f, A0&& a0)
+// -> decltype((*boost::forward<A0>(a0)).*f)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+ // bullet 5
+
+ template <class Fp, class ...Args>
+ inline
+ auto
+ invoke(Fp&& f, Args&& ...args)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<Args>(args)...))
+ {
+ return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
+ }
+
+// template <class Tp, class ...Args>
+// struct invoke_return
+// {
+// typedef decltype(invoke(boost::declval<Tp>(), boost::declval<Args>()...)) type;
+// };
+
+
+
+ template<typename F, class ...ArgTypes>
+ class thread_data:
+ public detail::thread_data_base
+ {
+ public:
+ BOOST_THREAD_NO_COPYABLE(thread_data)
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ thread_data(BOOST_THREAD_RV_REF(F) f_, BOOST_THREAD_RV_REF(ArgTypes)... args_):
+ fp(boost::forward<F>(f_), boost::forward<ArgTypes>(args_)...)
+ {}
+#endif
+ template <std::size_t ...Indices>
+ void run2(tuple_indices<Indices...>)
+ {
+
+ invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
+ }
+ void run()
+ {
+ typedef typename make_tuple_indices<std::tuple_size<std::tuple<F, ArgTypes...> >::value, 1>::type index_type;
+
+ run2(index_type());
+ }
+
+ private:
+ //F f;
+ //std::tuple<ArgTypes...> args;
+ std::tuple<typename decay<F>::type, typename decay<ArgTypes>::type...> fp;
+ };
+#else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
template<typename F>
class thread_data:
public detail::thread_data_base
@@ -115,6 +247,7 @@
f();
}
};
+#endif
}
class BOOST_THREAD_DECL thread
@@ -125,6 +258,8 @@
BOOST_THREAD_MOVABLE_ONLY(thread)
private:
+ struct dummy;
+
void release_handle();
detail::thread_data_ptr thread_info;
@@ -137,12 +272,25 @@
detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template<typename F, class ...ArgTypes>
+ static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ return detail::thread_data_ptr(detail::heap_new<
+ detail::thread_data<typename boost::remove_reference<F>::type, ArgTypes...>
+ >(
+ boost::forward<F>(f), boost::forward<ArgTypes>(args)...
+ )
+ );
+ }
+#else
template<typename F>
static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(
boost::forward<F>(f)));
}
+#endif
static inline detail::thread_data_ptr make_thread_info(void (*f)())
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(
@@ -150,7 +298,11 @@
}
#else
template<typename F>
- static inline detail::thread_data_ptr make_thread_info(F f)
+ static inline detail::thread_data_ptr make_thread_info(F f
+ , typename disable_if_c<
+ boost::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value || is_same<typename decay<F>::type, thread>::value,
+ dummy* >::type=0
+ )
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
}
@@ -161,7 +313,6 @@
}
#endif
- struct dummy;
public:
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
@@ -216,8 +367,9 @@
#else
template <class F>
explicit thread(F f
- // todo Disable also if Or is_same<typename decay<F>::type, thread>
- , typename disable_if<boost::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0):
+ , typename disable_if_c<
+ boost::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value || is_same<typename decay<F>::type, thread>::value,
+ dummy* >::type=0):
thread_info(make_thread_info(f))
{
start_thread();
@@ -234,14 +386,22 @@
explicit thread(BOOST_THREAD_RV_REF(F) f
, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
):
- thread_info(make_thread_info(f))
+#ifdef BOOST_THREAD_USES_MOVE
+ thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
+#else
+ thread_info(make_thread_info(f)) // todo : Add forward
+#endif
{
start_thread();
}
template <class F>
thread(attributes& attrs, BOOST_THREAD_RV_REF(F) f):
- thread_info(make_thread_info(f))
+#ifdef BOOST_THREAD_USES_MOVE
+ thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
+#else
+ thread_info(make_thread_info(f)) // todo : Add forward
+#endif
{
start_thread(attrs);
}
@@ -272,6 +432,20 @@
return *this;
}
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ template <class F, class Arg, class ...Args>
+ thread(F&& f, Arg&& arg, Args&&... args) :
+ thread_info(make_thread_info(
+ thread_detail::decay_copy(boost::forward<F>(f)),
+ thread_detail::decay_copy(boost::forward<Arg>(arg)),
+ thread_detail::decay_copy(boost::forward<Args>(args))...)
+ )
+
+ {
+ start_thread();
+ }
+
+#else
template <class F,class A1>
thread(F f,A1 a1,typename disable_if<boost::is_convertible<F&,thread_attributes >, dummy* >::type=0):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1)))
@@ -333,7 +507,7 @@
{
start_thread();
}
-
+#endif
void swap(thread& x) BOOST_NOEXCEPT
{
thread_info.swap(x.thread_info);
Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp (original)
+++ trunk/boost/thread/future.hpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -65,7 +65,7 @@
//enum class future_errc
BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
{
- broken_promise,
+ broken_promise = 1,
future_already_retrieved,
promise_already_satisfied,
no_state
@@ -282,20 +282,28 @@
void wait(bool rethrow=true)
{
+ //std::cout << __FILE__ << ":" << __LINE__ << std::endl;
boost::unique_lock<boost::mutex> lock(mutex);
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
do_callback(lock);
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
while(!done)
{
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
waiters.wait(lock);
}
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
if(rethrow && thread_was_interrupted)
{
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
throw boost::thread_interrupted();
}
if(rethrow && exception)
{
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
boost::rethrow_exception(exception);
}
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
}
bool timed_wait_until(boost::system_time const& target_time)
@@ -490,7 +498,9 @@
move_dest_type get()
{
wait();
+ std::cout << __FILE__ << ":" << __LINE__ << " " << " " <<std::endl;
return static_cast<move_dest_type>(*result);
+ //return boost::move(*result); // todo check why this doesn't works (references?)
}
shared_future_get_result_type get_sh()
@@ -605,7 +615,7 @@
#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);
+ locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex); // TODO shouldn't be moved explicitly
#endif
}
}
@@ -811,24 +821,32 @@
friend class shared_future<R>;
friend class promise<R>;
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template <class> friend class packaged_task; // todo check if this works in windows
+#else
friend class packaged_task<R>;
+#endif
friend class detail::future_waiter;
typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
BOOST_THREAD_FUTURE(future_ptr a_future):
future_(a_future)
- {}
+ {
+ }
public:
BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
typedef future_state::state state;
BOOST_THREAD_FUTURE()
- {}
+ {
+ }
~BOOST_THREAD_FUTURE()
- {}
+ {
+ }
BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
future_(BOOST_THREAD_RV(other).future_)
@@ -860,8 +878,13 @@
{
boost::throw_exception(future_uninitialized());
}
-
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ future_ptr fut_=future_;
+ future_.reset();
+ return fut_->get();
+#else
return future_->get();
+#endif
}
// functions to check state, and wait for ready
@@ -891,6 +914,7 @@
bool valid() const BOOST_NOEXCEPT
{
+ //std::cout << __FILE__ << ":" << __LINE__ << std::endl;
return future_ != 0;
}
@@ -950,8 +974,12 @@
friend class detail::future_waiter;
friend class promise<R>;
- friend class packaged_task<R>;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template <class> friend class packaged_task;// todo check if this works in windows
+#else
+ friend class packaged_task<R>;
+#endif
shared_future(future_ptr a_future):
future_(a_future)
{}
@@ -1374,8 +1402,20 @@
namespace detail
{
- template<typename R>
- struct task_base:
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template<typename R>
+ struct task_base;
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename R, typename ...ArgTypes>
+ struct task_base<R(ArgTypes...)>:
+#else
+ template<typename R>
+ struct task_base<R()>:
+#endif
+#else
+ template<typename R>
+ struct task_base:
+#endif
detail::future_object<R>
{
bool started;
@@ -1388,7 +1428,13 @@
{
started=false;
}
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
+ void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+#else
+ virtual void do_run()=0;
void run()
+#endif
{
{
boost::lock_guard<boost::mutex> lk(this->mutex);
@@ -1398,7 +1444,11 @@
}
started=true;
}
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ do_run(boost::forward<ArgTypes>(args)...);
+#else
do_run();
+#endif
}
void owner_destroyed()
@@ -1411,16 +1461,25 @@
}
}
-
- virtual void do_run()=0;
};
-
-
-
- template<typename R,typename F>
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ template<typename F, typename R>
+ struct task_object;
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename F, typename R, typename ...ArgTypes>
+ struct task_object<F, R(ArgTypes...)>:
+ task_base<R(ArgTypes...)>
+#else
+ template<typename F, typename R>
+ struct task_object<F, R()>:
+ task_base<R()>
+#endif
+#else
+ template<typename F, typename R>
struct task_object:
task_base<R>
+#endif
{
private:
task_object(task_object&);
@@ -1435,15 +1494,25 @@
{}
#else
task_object(BOOST_THREAD_RV_REF(F) f_):
- f(boost::move(f_))
+ f(boost::move(f_)) // TODO forward
{}
#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
void do_run()
{
try
{
this->mark_finished_with_result(f());
}
+#endif
catch(thread_interrupted& )
{
this->mark_interrupted_finish();
@@ -1455,9 +1524,21 @@
}
};
- template<typename R>
- struct task_object<R,R (*)()>:
- task_base<R>
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename R, typename ...ArgTypes>
+ struct task_object<R (*)(ArgTypes...), R(ArgTypes...)>:
+ task_base<R(ArgTypes...)>
+#else
+ template<typename R>
+ struct task_object<R (*)(), R()>:
+ task_base<R()>
+#endif
+#else
+ template<typename R>
+ struct task_object<R (*)(), R> :
+ task_base<R>
+#endif
{
private:
task_object(task_object&);
@@ -1466,12 +1547,21 @@
task_object(R (*f_)()):
f(f_)
{}
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
+ }
+#else
void do_run()
{
try
{
this->mark_finished_with_result(f());
}
+#endif
catch(thread_interrupted& )
{
this->mark_interrupted_finish();
@@ -1483,9 +1573,21 @@
}
};
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename F, typename ...ArgTypes>
+ struct task_object<F, void(ArgTypes...)>:
+ task_base<void(ArgTypes...)>
+#else
+ template<typename F>
+ struct task_object<F, void()>:
+ task_base<void()>
+#endif
+#else
template<typename F>
- struct task_object<void,F>:
- task_base<void>
+ struct task_object<F,void>:
+ task_base<void>
+#endif
{
private:
task_object(task_object&);
@@ -1500,15 +1602,23 @@
{}
#else
task_object(BOOST_THREAD_RV_REF(F) f_):
- f(boost::move(f_))
+ f(boost::move(f_)) // TODO forward
{}
#endif
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ f(boost::forward<ArgTypes>(args)...);
+#else
void do_run()
{
try
{
f();
+#endif
this->mark_finished_with_result();
}
catch(thread_interrupted& )
@@ -1522,9 +1632,21 @@
}
};
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename ...ArgTypes>
+ struct task_object<void (*)(ArgTypes...), void(ArgTypes...)>:
+ task_base<void(ArgTypes...)>
+#else
+ template<>
+ struct task_object<void (*)(), void()>:
+ task_base<void()>
+#endif
+#else
template<>
- struct task_object<void,void (*)()>:
- task_base<void>
+ struct task_object<void (*)(),void>:
+ task_base<void>
+#endif
{
private:
task_object(task_object&);
@@ -1533,11 +1655,19 @@
task_object(void (*f_)()):
f(f_)
{}
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
+ {
+ try
+ {
+ f(boost::forward<ArgTypes>(args)...);
+#else
void do_run()
{
try
{
f();
+#endif
this->mark_finished_with_result();
}
catch(thread_interrupted& )
@@ -1553,12 +1683,29 @@
}
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename R, typename ...ArgTypes>
+ class packaged_task<R(ArgTypes...)>
+ {
+ typedef boost::shared_ptr<detail::task_base<R(ArgTypes...)> > task_ptr;
+ boost::shared_ptr<detail::task_base<R(ArgTypes...)> > task;
+ #else
+ template<typename R>
+ class packaged_task<R()>
+ {
+ typedef boost::shared_ptr<detail::task_base<R()> > task_ptr;
+ boost::shared_ptr<detail::task_base<R()> > task;
+ #endif
+#else
template<typename R>
class packaged_task
{
- typedef boost::shared_ptr<detail::task_base<R> > task_ptr;
- boost::shared_ptr<detail::task_base<R> > task;
+ typedef boost::shared_ptr<detail::task_base<R> > task_ptr;
+ boost::shared_ptr<detail::task_base<R> > task;
+#endif
bool future_obtained;
+ struct dummy;
public:
typedef R result_type;
@@ -1570,25 +1717,77 @@
// construction and destruction
- explicit packaged_task(R(*f)()):
- task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)
- {}
+ explicit packaged_task(R(*f)())
+ {
+ typedef R(*FR)();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ typedef detail::task_object<FR,R(ArgTypes...)> task_object_type;
+ #else
+ typedef detail::task_object<FR,R()> task_object_type;
+ #endif
+#else
+ typedef detail::task_object<FR,R> task_object_type;
+#endif
+ task= task_ptr(new task_object_type(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)
- {}
+ explicit packaged_task(BOOST_THREAD_RV_REF(F) f
+ , typename disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
+ )
+ {
+ typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ typedef detail::task_object<FR,R(ArgTypes...)> task_object_type;
+ #else
+ typedef detail::task_object<FR,R()> task_object_type;
+ #endif
+#else
+ typedef detail::task_object<FR,R> task_object_type;
+#endif
+ task = task_ptr(new task_object_type(boost::forward<F>(f)));
+ future_obtained = false;
+
+ }
#else
template <class F>
- explicit packaged_task(F const& f):
- task(new detail::task_object<R,F>(f)),future_obtained(false)
- {}
+ explicit packaged_task(F const& f
+ , typename disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
+ )
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ typedef detail::task_object<F,R(ArgTypes...)> task_object_type;
+ #else
+ typedef detail::task_object<F,R()> task_object_type;
+ #endif
+#else
+ typedef detail::task_object<F,R> task_object_type;
+#endif
+ task = task_ptr(new task_object_type(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)
- {}
+ explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ typedef detail::task_object<F,R(ArgTypes...)> task_object_type;
+ task = task_ptr(new task_object_type(boost::forward<F>(f)));
+#else
+ typedef detail::task_object<F,R()> task_object_type;
+ task = task_ptr(new task_object_type(boost::move<F>(f))); // TODO forward
+#endif
+#else
+ typedef detail::task_object<F,R> task_object_type;
+ task = task_ptr(new task_object_type(boost::forward<F>(f)));
+#endif
+ future_obtained=false;
+
+ }
#endif
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
@@ -1596,11 +1795,20 @@
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;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ typedef detail::task_object<FR,R(ArgTypes...)> task_object_type;
+ #else
+ typedef detail::task_object<FR,R()> task_object_type;
+ #endif
+#else
+ typedef detail::task_object<FR,R> task_object_type;
+#endif
+ typedef typename Allocator::template rebind<task_object_type>::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) );
+ task = task_ptr(::new(a2.allocate(1)) task_object_type(f), D(a2, 1) );
future_obtained = false;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -1608,32 +1816,63 @@
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;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ typedef detail::task_object<FR,R(ArgTypes...)> task_object_type;
+ #else
+ typedef detail::task_object<FR,R()> task_object_type;
+ #endif
+#else
+ typedef detail::task_object<FR,R> task_object_type;
+#endif
+ typedef typename Allocator::template rebind<task_object_type>::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) );
+ task = task_ptr(::new(a2.allocate(1)) task_object_type(boost::forward<F>(f)), D(a2, 1) );
future_obtained = false;
}
-#else
+#else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
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;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ typedef detail::task_object<F,R(ArgTypes...)> task_object_type;
+ #else
+ typedef detail::task_object<F,R()> task_object_type;
+ #endif
+#else
+ typedef detail::task_object<F,R> task_object_type;
+#endif
+ typedef typename Allocator::template rebind<task_object_type>::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) );
+ task = task_ptr(::new(a2.allocate(1)) task_object_type(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;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ typedef detail::task_object<F,R(ArgTypes...)> task_object_type;
+ #else
+ typedef detail::task_object<F,R()> task_object_type;
+ #endif
+#else
+ typedef detail::task_object<F,R> task_object_type;
+#endif
+ typedef typename Allocator::template rebind<task_object_type>::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) );
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ task = task_ptr(::new(a2.allocate(1)) task_object_type(boost::forward<F>(f)), D(a2, 1) );
+#else
+ task = task_ptr(::new(a2.allocate(1)) task_object_type(boost::move(f)), D(a2, 1) ); // TODO forward
+#endif
future_obtained = false;
}
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -1682,6 +1921,7 @@
// result retrieval
BOOST_THREAD_FUTURE<R> get_future()
{
+
if(!task)
{
boost::throw_exception(task_moved());
@@ -1701,6 +1941,16 @@
// execution
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ void operator()(BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ if(!task)
+ {
+ boost::throw_exception(task_moved());
+ }
+ task->run(boost::forward<ArgTypes>(args)...);
+ }
+#else
void operator()()
{
if(!task)
@@ -1709,7 +1959,7 @@
}
task->run();
}
-
+#endif
template<typename F>
void set_wait_callback(F f)
{
@@ -1730,21 +1980,42 @@
BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class R, class... ArgTypes>
+ BOOST_THREAD_FUTURE<R>
+ async(launch policy, R(*f)(ArgTypes...), BOOST_THREAD_FWD_REF(ArgTypes)... args)
+ {
+ typedef packaged_task<R(ArgTypes...)> packaged_task_type;
+ #else
+ template <class R>
+ BOOST_THREAD_FUTURE<R>
+ async(launch policy, R(*f)())
+ {
+ typedef packaged_task<R()> packaged_task_type;
+ #endif
+#else
template <class R>
BOOST_THREAD_FUTURE<R>
async(launch policy, R(*f)())
{
- if (int(policy) & int(launch::async))
+ typedef packaged_task<R> packaged_task_type;
+#endif
+ if (int(policy) & int(launch::async))
{
- packaged_task<R> pt( f );
+ packaged_task_type pt( f );
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread( boost::move(pt), boost::forward<ArgTypes>(args)... ).detach();
+#else
boost::thread( boost::move(pt) ).detach();
+#endif
return ::boost::move(ret);
}
else if (int(policy) & int(launch::deferred))
{
- packaged_task<R> pt( f );
+ packaged_task_type pt( f );
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
return ::boost::move(ret);
@@ -1761,22 +2032,47 @@
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 defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class F, class ...ArgTypes>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
+ async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
+ {
+
+ typedef typename boost::result_of<typename decay<F>::type()>::type R;
+ typedef packaged_task<R(ArgTypes...)> packaged_task_type;
+ #else
+ 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;
+ typedef packaged_task<R()> packaged_task_type;
+ #endif
+#else
+ 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;
+ typedef packaged_task<R> packaged_task_type;
+#endif
+
if (int(policy) & int(launch::async))
{
- packaged_task<R> pt( boost::forward<F>(f) );
+ packaged_task_type pt( boost::forward<F>(f) );
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread( boost::move(pt), boost::forward(args)... ).detach(); // todo forward
+#else
boost::thread( boost::move(pt) ).detach();
+#endif
return ::boost::move(ret);
}
else if (int(policy) & int(launch::deferred))
{
- packaged_task<R> pt( boost::forward<F>(f) );
+ packaged_task_type pt( boost::forward<F>(f) );
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
return ::boost::move(ret);
@@ -1793,53 +2089,47 @@
}
#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);
-// }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class F, class ...ArgTypes>
+ BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
+ async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
+ {
+
+ typedef typename boost::result_of<typename decay<F>::type()>::type R;
+ typedef packaged_task<R(ArgTypes...)> packaged_task_type;
+ #else
+ 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;
+ typedef packaged_task<R()> packaged_task_type;
+ #endif
+#else
+ 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;
+ typedef packaged_task<R> packaged_task_type;
+#endif
- 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) );
+ packaged_task_type pt( boost::forward<F>(f) );
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread( boost::move(pt), boost::forward<ArgTypes>(args)... ).detach();
+#else
boost::thread( boost::move(pt) ).detach();
+#endif
return ::boost::move(ret);
}
else if (int(policy) & int(launch::deferred))
{
- packaged_task<R> pt( boost::forward<F>(f) );
+ packaged_task_type pt( boost::forward<F>(f) );
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
return ::boost::move(ret);
@@ -1848,15 +2138,68 @@
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));
- }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class F, class ...ArgTypes>
+ BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
+ async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args )
+ {
+ return async(launch::any, boost::forward<F>(f), boost::forward<ArgTypes>(args)...);
+ }
+ #else
+ 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
+#else
+ 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
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template <typename T>
+ BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(T&& value)
+ {
+ typedef typename decay<T>::type future_type;
+ promise<future_type> p;
+ p.set_value(value);
+ return boost::move(p.get_future());
+ }
+
+
+ BOOST_THREAD_FUTURE<void> make_future()
+ {
+ promise<void> p;
+ return boost::move(p.get_future());
+
+ }
+
+ template <typename T>
+ shared_future<typename decay<T>::type> make_shared_future(T&& value)
+ {
+ typedef typename decay<T>::type future_type;
+ promise<future_type> p;
+ p.set_value(value);
+ return p.get_future().share();
+ }
+
+
+ shared_future<void> make_shared_future()
+ {
+ promise<void> p;
+ return p.get_future().share();
+
+ }
+#endif
}
#endif // BOOST_NO_EXCEPTION
Modified: trunk/libs/thread/doc/changes.qbk
==============================================================================
--- trunk/libs/thread/doc/changes.qbk (original)
+++ trunk/libs/thread/doc/changes.qbk 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -8,6 +8,41 @@
[section:changes History]
+[heading Version 4.0.0 - boost 1.53]
+
+Breaking changes:
+
+BOOST_THREAD_VERSION==3 by default since Boost 1.53. So that all the deprecated features since 1.50 are not included by default. You can change this by setting the appropriated define (see Configuration section).
+
+Deprecated Features:
+
+Deprecated features since boost 1.53 available only until boost 1.58:
+
+* packaged_task<R> is deprecated, use instead packaged_task<R()>. See BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK and BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKAGED_TASK
+
+New Features:
+
+
+* [@http://svn.boost.org/trac/boost/ticket/7281 #7281] C++11 compliance: Add ArgTypes to packaged_task template.
+Provided when BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK is defined (Default value from Boost 1.55).
+See BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK and BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKAGED_TASK.
+
+
+* [@http://svn.boost.org/trac/boost/ticket/6270 #6270] c++11 compliance: Add thread constructor from movable callable and movable arguments
+Provided when BOOST_THREAD_PROVIDES_VARIADIC_THREAD is defined (Default value from Boost 1.55):
+See BOOST_THREAD_PROVIDES_VARIADIC_THREAD and BOOST_THREAD_DONT_PROVIDE_VARIADIC_THREAD.
+
+* [@http://svn.boost.org/trac/boost/ticket/7412 #7412] c++11 compliance: Add async from movable callable and movable arguments
+Provided when BOOST_THREAD_PROVIDES_VARIADIC_THREAD and BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK are defined (Default value from Boost 1.55):
+See BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK and BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKAGED_TASK, BOOST_THREAD_PROVIDES_VARIADIC_THREAD and BOOST_THREAD_DONT_PROVIDE_VARIADIC_THREAD.
+
+* [@http://svn.boost.org/trac/boost/ticket/7414 #7414] c++11 compliance: future::get post-condition should be valid()==false
+
+[/* [@http://svn.boost.org/trac/boost/ticket/7413 #7413] c++11 compliance: Add async when the launch policy is deferred.]
+
+Fixed Bugs:
+
+
[heading Version 3.1.0 - boost 1.52]
Deprecated Features:
@@ -268,10 +303,21 @@
The following features will be included in next releases.
# Complete the C++11 missing features, in particular
-
- * async with deferred and variadic rvalue reference args.
+ * [@http://svn.boost.org/trac/boost/ticket/7413 #7413] c++11 compliance: Add async when the launch policy is deferred.
+ * [@http://svn.boost.org/trac/boost/ticket/7280 #7280] C++11 compliance: Add promise::...at_thread_exit functions.
+ * [@http://svn.boost.org/trac/boost/ticket/7282 #7282] C++11 compliance: Add packaged_task::make_ready_at_thread_exit function.
+ * [@http://svn.boost.org/trac/boost/ticket/7285 #7285] Allow to pass movable arguments for call_once.
* [@http://svn.boost.org/trac/boost/ticket/6227 #6227] Use of variadic templates on Generic Locking Algorithms on compilers providing them.
- * [@http://svn.boost.org/trac/boost/ticket/6270 #6270] Add thread constructor from movable callable and movable arguments following C++11.
+
+
+# Add some of the extension proposed in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3428.pdf A Standardized Representation of Asynchronous Operations], in particular
+
+ * make_future/make_shared_future,
+ * future<T>.then,
+ * when_any/when_all,
+ * scheduler (in the form of an asynchronous executor as defined in Boost.Async).
+
+# Add a synchronized value class following the design in [@http://www.drdobbs.com/cpp/enforcing-correct-mutex-usage-with-synch/225200269 Enforcing Correct Mutex Usage with Synchronized Values]
Modified: trunk/libs/thread/doc/future_ref.qbk
==============================================================================
--- trunk/libs/thread/doc/future_ref.qbk (original)
+++ trunk/libs/thread/doc/future_ref.qbk 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -69,12 +69,12 @@
template <typename R>
class shared_future;
- template <typename R>
+ template <typename S>
class packaged_task;
- template <class R> void swap(packaged_task<R>&, packaged_task<R>&) noexcept;
+ template <class S> void swap(packaged_task<S>&, packaged_task<S>&) noexcept;
- template <class R, class Alloc>
- struct uses_allocator<packaged_task <R>, Alloc>;
+ template <class S, class Alloc>
+ struct uses_allocator<packaged_task <S>, Alloc>;
template <class F>
future<typename result_of<typename decay<F>::type()>::type>
@@ -119,12 +119,15 @@
enum class future_errc
{
- broken_promise,
- future_already_retrieved,
- promise_already_satisfied,
- no_state
+ broken_promise = implementation defined,
+ future_already_retrieved = implementation defined,
+ promise_already_satisfied = implementation defined,
+ no_state = implementation defined
}
+
+ The enum values of future_errc are distinct and not zero.
+
[endsect]
[section:launch Enumeration `launch `]
@@ -1141,25 +1144,27 @@
[section:packaged_task `packaged_task` class template]
+ template<typename S>
+ class packaged_task;
template<typename R
- // , class... ArgTypes // NOT YET IMPLEMENTED
+ , class... ArgTypes
>
- class packaged_task
+ class packaged_task<R(ArgTypes)>
{
public:
- typedef R result_type;
-
packaged_task(packaged_task&);// = delete;
packaged_task& operator=(packaged_task&);// = delete;
// construction and destruction
packaged_task() noexcept;
- explicit packaged_task(R(*f)());
+ explicit packaged_task(R(*f)(ArgTypes...));
template <class F>
explicit packaged_task(F&& f);
+ template <class Allocator>
+ packaged_task(allocator_arg_t, Allocator a, R(*f)(ArgTypes...));
template <class F, class Allocator>
packaged_task(allocator_arg_t, Allocator a, F&& f);
@@ -1177,8 +1182,7 @@
__unique_future__<R> get_future();
// execution
- void operator()();
- // void operator()(ArgTypes... ); // NOT YET IMPLEMENTED
+ void operator()(ArgTypes... );
// void make_ready_at_thread_exit(ArgTypes...); // NOT YET IMPLEMENTED
void reset();
@@ -1188,14 +1192,14 @@
[section:task_constructor Task Constructor]
- packaged_task(R(*f)());
+ packaged_task(R(*f)(ArgTypes...));
template<typename F>
packaged_task(F&&f);
[variablelist
-[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same
+[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` must behave the same
as invoking `f`.]]
[[Effects:] [Constructs a new __packaged_task__ with `boost::forward<F>(f)` stored as the associated task.]]
@@ -1203,7 +1207,10 @@
[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data
structures could not be allocated.]]
-[[Notes:] [The R(*f)()) overload to allow passing a function without needing to use `&`.]]
+[[Notes:] [The R(*f)(ArgTypes...)) overload to allow passing a function without needing to use `&`.]]
+
+[[Remark:] [This constructor doesn't participate in overload resolution if decay<F>::type is the same type as boost::packaged_task<R>.]]
+
]
@@ -1212,7 +1219,7 @@
[section:alloc_constructor Allocator Constructor]
template <class Allocator>
- packaged_task(allocator_arg_t, Allocator a, R(*f)());
+ packaged_task(allocator_arg_t, Allocator a, R(*f)(ArgTypes...));
template <class F, class Allocator>
packaged_task(allocator_arg_t, Allocator a, F&& f);
@@ -1227,7 +1234,7 @@
structures could not be allocated.]]
[[Notes:] [Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.]]
-[[Notes:] [The R(*f)()) overload to allow passing a function without needing to use `&`.]]
+[[Notes:] [The R(*f)(ArgTypes...)) overload to allow passing a function without needing to use `&`.]]
]
@@ -1414,7 +1421,7 @@
If the implementation chooses the `launch::async` policy,
-- a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined;
+- a call to a non-timed waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined;
- the associated thread completion synchronizes with the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.
]]
@@ -1437,12 +1444,12 @@
[variablelist
-[[Requires:] [F and each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE (DECAY_- COPY (boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) shall be a valid expression.
+[[Requires:] [F and each Ti in Args shall satisfy the MoveConstructible requirements. invoke (decay_copy (boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) shall be a valid expression.
]]
[[Effects:] [The first function behaves the same as a call to the second function with a policy argument of launch::async | launch::deferred and the same arguments for F and Args. The second function creates a shared state that is associated with the returned future object. The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):
-- if policy & launch::async is non-zero - calls INVOKE (decay_copy (boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) (20.8.2, 30.3.1.2) as if in a new thread of exe- cution represented by a thread object with the calls to decay_copy() being evaluated in the thread that called async. Any return value is stored as the result in the shared state. Any excep- tion propagated from the execution of INVOKE(decay_copy(boost::forward<F>(f)), DECAY_- COPY (boost::forward<Args>(args))...) is stored as the exceptional result in the shared state. The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.
-- if policy & launch::deferred is non-zero - Stores decay_copy (boost::forward<F>(f)) and decay_copy (boost::forward<Args>(args))... in the shared state. These copies of f and args constitute a deferred function. Invocation of the deferred function evaluates INVOKE (boost::move(g), boost::move(xyz)) where g is the stored value of decay_copy (boost::forward<F>(f)) and xyz is the stored copy of decay_copy (boost::forward<Args>(args)).... The shared state is not made ready until the function has completed. The first call to a non-timed waiting function (30.6.4) on an asynchronous return object referring to this shared state shall invoke the deferred func- tion in the thread that called the waiting function. Once evaluation of INVOKE (boost::move(g), boost::move(xyz)) begins, the function is no longer considered deferred.
+- if policy & launch::async is non-zero - calls invoke (decay_copy (boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) (20.8.2, 30.3.1.2) as if in a new thread of exe- cution represented by a thread object with the calls to decay_copy() being evaluated in the thread that called async. Any return value is stored as the result in the shared state. Any excep- tion propagated from the execution of invoke(decay_copy(boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) is stored as the exceptional result in the shared state. The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.
+- if policy & launch::deferred is non-zero - Stores decay_copy (boost::forward<F>(f)) and decay_copy (boost::forward<Args>(args))... in the shared state. These copies of f and args constitute a deferred function. Invocation of the deferred function evaluates invoke (boost::move(g), boost::move(xyz)) where g is the stored value of decay_copy (boost::forward<F>(f)) and xyz is the stored copy of decay_copy (boost::forward<Args>(args)).... The shared state is not made ready until the function has completed. The first call to a non-timed waiting function (30.6.4) on an asynchronous return object referring to this shared state shall invoke the deferred func- tion in the thread that called the waiting function. Once evaluation of invoke (boost::move(g), boost::move(xyz)) begins, the function is no longer considered deferred.
]]
Modified: trunk/libs/thread/doc/mutex_concepts.qbk
==============================================================================
--- trunk/libs/thread/doc/mutex_concepts.qbk (original)
+++ trunk/libs/thread/doc/mutex_concepts.qbk 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -59,14 +59,12 @@
[variablelist
-[[Precondition:] [The current thread owns `m`.]]
+[[Requires:] [The current thread owns `m`.]]
-[[Effects:] [Releases ownership by the current thread.]]
+[[Effects:] [Releases a lock on `m` by the current thread.]]
[[Return type:] [`void`.]]
-[[Postcondition:] [The current thread no longer owns `m`.]]
-
[[Throws:] [Nothing.]]
]
[endsect]
Modified: trunk/libs/thread/doc/thread.qbk
==============================================================================
--- trunk/libs/thread/doc/thread.qbk (original)
+++ trunk/libs/thread/doc/thread.qbk 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -8,7 +8,7 @@
[library Thread
[quickbook 1.5]
- [version 3.1.0]
+ [version 4.0.0]
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
[copyright 2007-11 Anthony Williams]
[copyright 2011-12 Vicente J. Botet Escriba]
Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 (original)
+++ trunk/libs/thread/test/Jamfile.v2 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -245,6 +245,11 @@
[ thread-run2 ./sync/futures/promise/get_future_pass.cpp : promise__get_future_p ]
[ thread-run2 ./sync/futures/promise/move_ctor_pass.cpp : promise__move_ctor_p ]
[ thread-run2 ./sync/futures/promise/move_assign_pass.cpp : promise__move_asign_p ]
+ [ thread-run2 ./sync/futures/promise/set_exception_pass.cpp : promise__set_exception_p ]
+ [ thread-run2 ./sync/futures/promise/set_lvalue_pass.cpp : promise__set_lvalue_p ]
+ [ thread-run2 ./sync/futures/promise/set_rvalue_pass.cpp : promise__set_rvalue_p ]
+ [ thread-run2 ./sync/futures/promise/set_value_const_pass.cpp : promise__set_value_const_p ]
+ [ thread-run2 ./sync/futures/promise/set_value_void_pass.cpp : promise__set_value_void_p ]
[ thread-run2 ./sync/futures/promise/use_allocator_pass.cpp : promise__use_allocator_p ]
;
@@ -255,7 +260,7 @@
[ thread-compile-fail ./sync/futures/future/copy_ctor_fail.cpp : : future__copy_ctor_f ]
[ thread-run2 ./sync/futures/future/default_pass.cpp : future__default_p ]
[ thread-run2 ./sync/futures/future/dtor_pass.cpp : future__dtor_p ]
- #[ thread-run2 ./sync/futures/future/get_pass.cpp : future__get_p ]
+ [ thread-run2 ./sync/futures/future/get_pass.cpp : future__get_p ]
[ thread-run2 ./sync/futures/future/move_ctor_pass.cpp : future__move_ctor_p ]
[ thread-run2 ./sync/futures/future/move_assign_pass.cpp : future__move_asign_p ]
[ thread-run2 ./sync/futures/future/share_pass.cpp : future__share_p ]
@@ -269,11 +274,11 @@
[ thread-compile-fail ./sync/futures/packaged_task/copy_ctor_fail.cpp : : packaged_task__copy_ctor_f ]
[ thread-run2 ./sync/futures/packaged_task/default_ctor_pass.cpp : packaged_task__default_ctor_p ]
[ thread-run2 ./sync/futures/packaged_task/func_ctor_pass.cpp : packaged_task__func_ctor_p ]
- #[ thread-run2 ./sync/futures/packaged_task/dtor_pass.cpp : packaged_task__dtor_p ]
+ [ thread-run2 ./sync/futures/packaged_task/dtor_pass.cpp : packaged_task__dtor_p ]
[ thread-run2 ./sync/futures/packaged_task/get_future_pass.cpp : packaged_task__get_future_p ]
[ thread-run2 ./sync/futures/packaged_task/move_ctor_pass.cpp : packaged_task__move_ctor_p ]
[ thread-run2 ./sync/futures/packaged_task/move_assign_pass.cpp : packaged_task__move_asign_p ]
- #[ thread-run2 ./sync/futures/packaged_task/operator_pass.cpp : packaged_task__operator_p ]
+ [ thread-run2 ./sync/futures/packaged_task/operator_pass.cpp : packaged_task__operator_p ]
[ thread-run2 ./sync/futures/packaged_task/reset_pass.cpp : packaged_task__reset_p ]
[ thread-run2 ./sync/futures/packaged_task/use_allocator_pass.cpp : packaged_task__use_allocator_p ]
[ thread-run2 ./sync/futures/packaged_task/types_pass.cpp : packaged_task__types_p ]
@@ -463,7 +468,7 @@
[ thread-run-lib2 ./threads/thread/constr/F_pass.cpp : thread__constr__F_p ]
[ thread-run-lib2 ./threads/thread/constr/FArgs_pass.cpp : thread__constr__FArgs_p ]
[ thread-run2 ./threads/thread/constr/Frvalue_pass.cpp : thread__constr__Frvalue_p ]
- #[ thread-run2 ./threads/thread/constr/FrvalueArgs_pass.cpp : thread__constr__FrvalueArgs_p ]
+ [ thread-run2 ./threads/thread/constr/FrvalueArgs_pass.cpp : thread__constr__FrvalueArgs_p ]
[ thread-run2 ./threads/thread/constr/move_pass.cpp : thread__constr__move_p ]
[ thread-run2 ./threads/thread/destr/dtor_pass.cpp : thread__destr__dtor_p ]
[ thread-run2 ./threads/thread/id/hash_pass.cpp : thread__id__hash_p ]
@@ -538,4 +543,14 @@
[ thread-run2 ./sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp : reverse_lock__types_p ]
;
+ explicit ts_ ;
+ test-suite ts_
+ :
+ [ thread-run ../example/unwrap.cpp ]
+ [ thread-run ../example/make_future.cpp ]
+ [ thread-run2 ./sync/futures/packaged_task/dtor_pass.cpp : packaged_task__dtor_p2 ]
+ [ thread-run2 ./sync/futures/future/get_pass.cpp : future__get_p2 ]
+ [ thread-run2 ./sync/futures/packaged_task/operator_pass.cpp : packaged_task__operator_p2 ]
+ ;
+
}
Modified: trunk/libs/thread/test/sync/futures/async/async_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/async/async_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/async/async_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -22,7 +22,8 @@
// future<typename result_of<F(Args...)>::type>
// async(launch policy, F&& f, Args&&... args);
-#define BOOST_THREAD_VERSION 3
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
@@ -93,13 +94,13 @@
return boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(i));
}
-typedef boost::interprocess::unique_ptr<int, boost::default_delete<int> > XXT;
-boost::interprocess::unique_ptr<int, boost::default_delete<int> > f4(
- BOOST_THREAD_RV_REF(boost::interprocess::unique_ptr<int, boost::default_delete<int> > ) p)
-{
- boost::this_thread::sleep_for(ms(200));
- return boost::move(p);
-}
+//typedef boost::interprocess::unique_ptr<int, boost::default_delete<int> > XXT;
+//boost::interprocess::unique_ptr<int, boost::default_delete<int> > f4(
+// BOOST_THREAD_RV_REF(boost::interprocess::unique_ptr<int, boost::default_delete<int> > ) p)
+//{
+// boost::this_thread::sleep_for(ms(200));
+// return boost::move(p);
+//}
int main()
Modified: trunk/libs/thread/test/sync/futures/future/get_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/future/get_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/future/get_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,8 @@
// future<R> get_future();
-#define BOOST_THREAD_VERSION 3
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
@@ -76,7 +77,7 @@
void func6(boost::promise<void> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
- p.set_exception(boost::make_exception_ptr('c'));
+ p.set_exception(boost::make_exception_ptr(4));
}
@@ -87,84 +88,126 @@
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
- boost::thread(func1, boost::move(p)).detach();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#else
+ p.set_value(3);
+#endif
BOOST_TEST(f.valid());
BOOST_TEST(f.get() == 3);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
BOOST_TEST(!f.valid());
+#endif
}
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func2, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3));
+#endif
try
{
BOOST_TEST(f.valid());
BOOST_TEST(f.get() == 3);
BOOST_TEST(false);
}
- catch (int i)
+ catch (boost::wrap<int> const& i)
{
- BOOST_TEST(i == 3);
+ BOOST_TEST(i.value == 3);
}
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
BOOST_TEST(!f.valid());
+#endif
+ }
+ }
+ {
+ typedef int& T;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#else
+ int j=5;
+ p.set_value(j);
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 5);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func4, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3.5));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<double> const& i)
+ {
+ BOOST_TEST(i.value == 3.5);
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
}
}
-// {
-// typedef int& T;
-// {
-// boost::promise<T> p;
-// boost::future<T> f = p.get_future();
-// boost::thread(func3, boost::move(p)).detach();
-// BOOST_TEST(f.valid());
-// BOOST_TEST(f.get() == 5);
-// BOOST_TEST(!f.valid());
-// }
-// {
-// boost::promise<T> p;
-// boost::future<T> f = p.get_future();
-// boost::thread(func4, boost::move(p)).detach();
-// try
-// {
-// BOOST_TEST(f.valid());
-// BOOST_TEST(f.get() == 3);
-// BOOST_TEST(false);
-// }
-// catch (double i)
-// {
-// BOOST_TEST(i == 3.5);
-// }
-// BOOST_TEST(!f.valid());
-// }
-// }
-// {
-// typedef void T;
-// {
-// boost::promise<T> p;
-// boost::future<T> f = p.get_future();
-// boost::thread(func5, boost::move(p)).detach();
-// BOOST_TEST(f.valid());
-// f.get();
-// BOOST_TEST(!f.valid());
-// }
-// {
-// boost::promise<T> p;
-// boost::future<T> f = p.get_future();
-// boost::thread(func6, boost::move(p)).detach();
-// try
-// {
-// BOOST_TEST(f.valid());
-// f.get();
-// BOOST_TEST(false);
-// }
-// catch (char i)
-// {
-// BOOST_TEST(i == 'c');
-// }
-// BOOST_TEST(!f.valid());
-// }
-// }
-
+ typedef void T;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#else
+ p.set_value();
+#endif
+ BOOST_TEST(f.valid());
+ f.get();
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func6, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(4));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> const& i)
+ {
+ BOOST_TEST(i.value == 4);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
return boost::report_errors();
}
Modified: trunk/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -20,10 +20,18 @@
// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+#include <boost/thread/detail/config.hpp>
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
+
+
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
#include "../test_allocator.hpp"
@@ -81,7 +89,7 @@
int main()
{
{
- boost::packaged_task<double> p(boost::allocator_arg,
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
test_allocator<A>(), BOOST_THREAD_MAKE_RV_REF(A(5)));
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
@@ -99,7 +107,7 @@
A::n_copies = 0;
{
A a(5);
- boost::packaged_task<double> p(boost::allocator_arg,
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
test_allocator<A>(), a);
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
@@ -115,7 +123,7 @@
A::n_copies = 0;
{
const A a(5);
- boost::packaged_task<double> p(boost::allocator_arg,
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
test_allocator<A>(), a);
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
@@ -128,7 +136,7 @@
BOOST_TEST(A::n_moves > 0);
BOOST_TEST(test_alloc_base::count == 0);
{
- boost::packaged_task<double> p(boost::allocator_arg,
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
test_allocator<A>(), fct);
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
@@ -138,7 +146,7 @@
BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p(boost::allocator_arg,
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
test_allocator<A>(), &lfct);
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
Modified: trunk/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,13 @@
// packaged_task& operator=(packaged_task&) = delete;
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -37,8 +43,8 @@
int main()
{
{
- boost::packaged_task<double> p0(A(5));
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
p = p0;
}
Modified: trunk/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,13 @@
// packaged_task(packaged_task&) = delete;
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -37,8 +43,8 @@
int main()
{
{
- boost::packaged_task<double> p0(A(5));
- boost::packaged_task<double> p(p0);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(p0);
}
Modified: trunk/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,13 @@
// packaged_task();
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE int()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE int
+#endif
+
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -26,7 +32,7 @@
int main()
{
{
- boost::packaged_task<int> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
BOOST_TEST(!p.valid());
}
Modified: trunk/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -17,14 +17,34 @@
// class packaged_task<R>
// ~packaged_task();
-;
-#define BOOST_THREAD_VERSION 3
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+
class A
{
long data_;
@@ -36,25 +56,33 @@
long operator()(long i, long j) const {return data_ + i + j;}
};
-void func(boost::packaged_task<double> p)
+void func(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> )
{
}
-void func2(boost::packaged_task<double> p)
+void func2(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
{
- //p(3, 'a');
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
p();
+#endif
}
int main()
{
{
- boost::packaged_task<double> p(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func, boost::move(p)).detach();
+#else
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>* p2=new boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>(boost::move(p));
+ delete p2;
+#endif
try
{
- double i = f.get();
+ f.get();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
@@ -63,13 +91,18 @@
}
}
{
- boost::packaged_task<double> p(A(5));
+ std::cout << __LINE__ << std::endl;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func2, boost::move(p)).detach();
- BOOST_TEST(f.get() == 5.0);
+#else
+ p();
+#endif
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
+ std::cout << __LINE__ << std::endl;
}
-
-
return boost::report_errors();
}
Modified: trunk/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -19,10 +19,30 @@
// explicit packaged_task(F&& f);
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+
double fct()
{
return 5.0;
@@ -69,12 +89,15 @@
int main()
{
{
- boost::packaged_task<double> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
- //p(3, 'a');
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ p(3, 'a');
+#else
p();
- BOOST_TEST(f.get() == 5.0);
+#endif
+ BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
BOOST_TEST(A::n_copies == 0);
BOOST_TEST(A::n_moves > 0);
}
@@ -82,7 +105,7 @@
A::n_copies = 0;
{
A a(5);
- boost::packaged_task<double> p(a);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
@@ -96,7 +119,7 @@
A::n_copies = 0;
{
const A a(5);
- boost::packaged_task<double> p(a);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
@@ -106,7 +129,7 @@
BOOST_TEST(A::n_moves > 0);
}
{
- boost::packaged_task<double> p(fct);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(fct);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
@@ -114,7 +137,7 @@
BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p(&lfct);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(&lfct);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
Modified: trunk/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -19,7 +19,12 @@
// future<R> get_future();
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -38,14 +43,14 @@
int main()
{
{
- boost::packaged_task<double> p(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
p();
BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
try
{
@@ -58,7 +63,7 @@
}
}
{
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
try
{
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
Modified: trunk/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,12 @@
// void swap(packaged_task& other);
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -46,8 +51,8 @@
int main()
{
{
- boost::packaged_task<double> p0(A(5));
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
p.swap(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(p.valid());
@@ -57,8 +62,8 @@
BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p0;
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
p.swap(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(!p.valid());
Modified: trunk/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,12 @@
// promise& operator=(promise&& rhs);
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -39,8 +44,8 @@
{
{
- boost::packaged_task<double> p0(A(5));
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
p = boost::move(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(p.valid());
@@ -50,8 +55,8 @@
BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p0;
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
p = boost::move(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(!p.valid());
Modified: trunk/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,12 @@
// packaged_task(packaged_task&& other);
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -38,8 +43,8 @@
int main()
{
{
- boost::packaged_task<double> p0(A(5));
- boost::packaged_task<double> p = boost::move(p0);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p = boost::move(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
@@ -48,8 +53,8 @@
BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p0;
- boost::packaged_task<double> p = boost::move(p0);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p = boost::move(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(!p.valid());
}
Modified: trunk/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,12 @@
// void
// swap(packaged_task<R>& x, packaged_task<R>& y);
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -37,8 +42,8 @@
int main()
{
{
- boost::packaged_task<double> p0(A(5));
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
p.swap(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(p.valid());
@@ -48,8 +53,8 @@
BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p0;
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
p.swap(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(!p.valid());
Modified: trunk/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,10 +18,44 @@
// void operator()();
-#define BOOST_THREAD_VERSION 3
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+class E : public std::exception
+{
+public:
+ long data;
+ explicit E(long i) :
+ data(i)
+ {
+ }
+
+ const char* what() const throw() { return ""; }
+
+ ~E() throw() {}
+};
+
class A
{
long data_;
@@ -34,91 +68,144 @@
long operator()() const
{
+ if (data_ == 0) BOOST_THROW_EXCEPTION(E(6));
return data_;
}
long operator()(long i, long j) const
{
- if (j == 'z') throw A(6);
+ if (j == 'z') BOOST_THROW_EXCEPTION(E(6));
return data_ + i + j;
}
+ ~A() {}
};
-void func0(boost::packaged_task<double> p)
+void func0(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
- //p(3, 'a');
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
p();
+#endif
}
-void func1(boost::packaged_task<double(int, char)> p)
+void func1(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
- //p(3, 'z');
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'z');
+#else
p();
+#endif
}
-void func2(boost::packaged_task<double(int, char)> p)
+void func2(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
{
- //p(3, 'a');
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
p();
+#endif
try
{
- //p(3, 'c');
- p();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'c');
+#else
+ p();
+#endif
}
catch (const boost::future_error& e)
{
- BOOST_TEST(e.code() == make_error_code(boost::future_errc::promise_already_satisfied));
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
}
}
-void func3(boost::packaged_task<double(int, char)> p)
+void func3(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
{
try
{
- //p(3, 'a');
- p();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
+ p();
+#endif
}
catch (const boost::future_error& e)
{
- BOOST_TEST(e.code() == make_error_code(boost::future_errc::no_state));
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
}
int main()
{
{
- boost::packaged_task<double> p(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func0, boost::move(p)).detach();
- BOOST_TEST(f.get() == 5.0);
+#else
+ //p();
+#endif
+ //BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(0));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func1, boost::move(p)).detach();
+#endif
try
{
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ p();
+#endif
f.get();
BOOST_TEST(false);
}
- catch (const A& e)
+ catch (const E& e)
+ {
+ BOOST_TEST(e.data == 6);
+ }
+ catch (...)
{
- //BOOST_TEST(e(3, 'a') == 106);
- BOOST_TEST(e() == 5);
+ BOOST_TEST(false);
}
}
{
- boost::packaged_task<double> p(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread t(func2, boost::move(p));
- BOOST_TEST(f.get() == 5.0);
+#else
+ p();
+#endif
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ BOOST_TEST(f.get() == 105);
t.join();
+#else
+ BOOST_TEST(f.get() == 5.0);
+#endif
}
{
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread t(func3, boost::move(p));
t.join();
+#else
+ try
+ {
+ #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+ #else
+ p();
+ #endif
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+#endif
}
return boost::report_errors();
Modified: trunk/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -18,7 +18,13 @@
// void operator()();
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -46,7 +52,7 @@
int main()
{
{
- boost::packaged_task<double> p(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
p();
@@ -58,7 +64,7 @@
BOOST_TEST(f.get() == 5.0);
}
{
- boost::packaged_task<double> p;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
try
{
p.reset();
Modified: trunk/libs/thread/test/sync/futures/packaged_task/types_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/types_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/types_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -29,7 +29,7 @@
int main()
{
- BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::packaged_task<A>::result_type, A>::value), "");
+ //BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::packaged_task<A>::result_type, A>::value), "");
return boost::report_errors();
}
Modified: trunk/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -21,7 +21,12 @@
// : true_type { };
-#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -33,7 +38,7 @@
int main()
{
- BOOST_STATIC_ASSERT_MSG((boost::uses_allocator<boost::packaged_task<double>, test_allocator<double> >::value), "");
+ BOOST_STATIC_ASSERT_MSG((boost::uses_allocator<boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>, test_allocator<double> >::value), "");
return boost::report_errors();
}
Added: trunk/libs/thread/test/sync/futures/promise/set_exception_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/promise/set_exception_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void set_exception(exception_ptr p);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost
+{
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+int main()
+{
+
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_exception(boost::make_exception_ptr(3));
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> i)
+ {
+ BOOST_TEST(i.value == 3);
+ }
+ try
+ {
+ p.set_exception(boost::make_exception_ptr(3));
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+
+ return boost::report_errors();
+}
+
Added: trunk/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise<R&>::set_value(R& r);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+int main()
+{
+
+ {
+ typedef int& T;
+ int i = 3;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(i);
+ int& j = f.get();
+ BOOST_TEST(j == 3);
+ ++i;
+ BOOST_TEST(j == 4);
+ try
+ {
+ p.set_value(i);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+
+ return boost::report_errors();
+}
+
Added: trunk/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -0,0 +1,152 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise::set_value(R&& r);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+struct A
+{
+ A() :
+ value(0)
+ {
+ }
+ A(int i) :
+ value(i)
+ {
+ }
+ A(const A&)= delete;
+ A(A&& rhs)
+ {
+ if(rhs.value==0)
+ throw 9;
+ else
+ {
+ value=rhs.value;
+ rhs.value=0;
+ }
+ }
+ int value;
+};
+
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+int main()
+{
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+ {
+ typedef A T;
+ T i;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ try
+ {
+ p.set_value(boost::move(i));
+ BOOST_TEST(false);
+ }
+ catch (int j)
+ {
+ BOOST_TEST(j == 9);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef A T;
+ T i(3);
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(boost::move(i));
+ BOOST_TEST(f.get().value == 3);
+ try
+ {
+ T j(3);
+ p.set_value(boost::move(j));
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+
+ }
+ {
+ typedef A T;
+ T i(3);
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(boost::move(i));
+ BOOST_TEST(i.value == 0);
+ boost::promise<T> p2(boost::move(p));
+ BOOST_TEST(f.get().value == 3);
+
+ }
+ {
+ typedef A T;
+ T i(3);
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(boost::move(i));
+ BOOST_TEST(i.value == 0);
+ boost::promise<T> p2(boost::move(p));
+ boost::future<T> f2(boost::move(f));
+ BOOST_TEST(f2.get().value == 3);
+
+ }
+ {
+ typedef A T;
+ T i(3);
+ boost::promise<T> p;
+ p.set_value(boost::move(i));
+ BOOST_TEST(i.value == 0);
+ boost::promise<T> p2(boost::move(p));
+ boost::future<T> f = p2.get_future();
+ BOOST_TEST(f.get().value == 3);
+
+ }
+
+ {
+ typedef boost::future<int> T;
+ boost::promise<int> pi;
+ T fi=pi.get_future();
+ pi.set_value(3);
+
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(boost::move(fi));
+ boost::future<T> f2(boost::move(f));
+ BOOST_TEST(f2.get().get() == 3);
+ }
+
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+ return boost::report_errors();
+}
+
Added: trunk/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise::set_value(const R& r);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+struct A
+{
+ A()
+ {
+ }
+ A(const A&)
+ {
+ throw 10;
+ }
+};
+
+int main()
+{
+
+ {
+ typedef int T;
+ T i = 3;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(i);
+ ++i;
+ BOOST_TEST(f.get() == 3);
+ --i;
+ try
+ {
+ p.set_value(i);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ try
+ {
+ p.set_value(i);
+ BOOST_TEST(false);
+ }
+ catch (int j)
+ {
+ BOOST_TEST(j == 10);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+
+ return boost::report_errors();
+}
+
Added: trunk/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise<void>::set_value();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+struct A
+{
+ A()
+ {
+ }
+ A(const A&)
+ {
+ throw 10;
+ }
+};
+
+int main()
+{
+
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value();
+ f.get();
+ try
+ {
+ p.set_value();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+
+ return boost::report_errors();
+}
+
Modified: trunk/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp
==============================================================================
--- trunk/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp (original)
+++ trunk/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp 2012-09-29 12:31:27 EDT (Sat, 29 Sep 2012)
@@ -17,6 +17,8 @@
// template <class F, class ...Args> thread(F&& f, Args&&... args);
+#define BOOST_THREAD_VERSION 4
+
#include <boost/thread/thread.hpp>
#include <new>
#include <cstdlib>
@@ -25,6 +27,7 @@
class MoveOnly
{
+public:
BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
MoveOnly()
{
@@ -39,9 +42,11 @@
int main()
{
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
{
- boost::thread t = boost::thread( BOOST_THREAD_MAKE_RV_REF(MoveOnly()), BOOST_THREAD_MAKE_RV_REF(MoveOnly()) );
+ boost::thread t = boost::thread( MoveOnly(), MoveOnly() );
t.join();
}
+#endif
return boost::report_errors();
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk