Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84101 - in branches/release: boost/thread boost/thread/detail boost/thread/pthread libs/thread libs/thread/doc libs/thread/test libs/thread/test/sync/futures/async libs/thread/test/sync/mutual_exclusion/once/call_once
From: vicente.botet_at_[hidden]
Date: 2013-05-01 12:40:34


Author: viboes
Date: 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
New Revision: 84101
URL: http://svn.boost.org/trac/boost/changeset/84101

Log:
Thread: merge latch; invoke.
Added:
   branches/release/boost/thread/completion_latch.hpp
      - copied unchanged from r84088, /trunk/boost/thread/completion_latch.hpp
   branches/release/boost/thread/detail/counter.hpp
      - copied unchanged from r84088, /trunk/boost/thread/detail/counter.hpp
   branches/release/boost/thread/latch.hpp
      - copied unchanged from r84088, /trunk/boost/thread/latch.hpp
   branches/release/boost/thread/pthread/shared_mutex_assert.hpp
      - copied unchanged from r83951, /trunk/boost/thread/pthread/shared_mutex_assert.hpp
   branches/release/libs/thread/doc/latch.qbk
      - copied unchanged from r84096, /trunk/libs/thread/doc/latch.qbk
   branches/release/libs/thread/test/test_completion_latch.cpp
      - copied unchanged from r84096, /trunk/libs/thread/test/test_completion_latch.cpp
   branches/release/libs/thread/test/test_latch.cpp
      - copied unchanged from r84096, /trunk/libs/thread/test/test_latch.cpp
Properties modified:
   branches/release/boost/thread/ (props changed)
   branches/release/libs/thread/ (props changed)
Text files modified:
   branches/release/boost/thread/barrier.hpp | 5
   branches/release/boost/thread/detail/async_func.hpp | 501 ++++++++++++++++
   branches/release/boost/thread/detail/invoke.hpp | 1179 ++++++++++++++++++++++++++++++++++++++-
   branches/release/boost/thread/detail/make_tuple_indices.hpp | 174 +++++
   branches/release/boost/thread/externally_locked.hpp | 84 ++
   branches/release/boost/thread/pthread/thread_data.hpp | 2
   branches/release/libs/thread/doc/barrier.qbk | 3
   branches/release/libs/thread/doc/changes.qbk | 25
   branches/release/libs/thread/doc/mutex_concepts.qbk | 231 +++++++
   branches/release/libs/thread/doc/thread.qbk | 3
   branches/release/libs/thread/test/Jamfile.v2 | 4
   branches/release/libs/thread/test/sync/futures/async/async_pass.cpp | 2
   branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp | 32 +
   branches/release/libs/thread/test/test_barrier.cpp | 9
   14 files changed, 2160 insertions(+), 94 deletions(-)

Modified: branches/release/boost/thread/barrier.hpp
==============================================================================
--- branches/release/boost/thread/barrier.hpp (original)
+++ branches/release/boost/thread/barrier.hpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -9,8 +9,9 @@
 #define BOOST_BARRIER_JDM030602_HPP
 
 #include <boost/thread/detail/config.hpp>
-#include <boost/throw_exception.hpp>
+#include <boost/thread/detail/delete.hpp>
 
+#include <boost/throw_exception.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/lock_types.hpp>
 #include <boost/thread/condition_variable.hpp>
@@ -25,6 +26,8 @@
     class barrier
     {
     public:
+ BOOST_THREAD_NO_COPYABLE( barrier )
+
         barrier(unsigned int count)
             : m_threshold(count), m_count(count), m_generation(0)
         {

Modified: branches/release/boost/thread/detail/async_func.hpp
==============================================================================
--- branches/release/boost/thread/detail/async_func.hpp (original)
+++ branches/release/boost/thread/detail/async_func.hpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -3,6 +3,13 @@
 // 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)
 
+// 2013/04 Vicente J. Botet Escriba
+// Provide implementation up to 9 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
+// Make use of Boost.Move
+// Make use of Boost.Tuple (movable)
+// 2012/11 Vicente J. Botet Escriba
+// Adapt to boost libc++ implementation
+
 //===----------------------------------------------------------------------===//
 //
 // The LLVM Compiler Infrastructure
@@ -23,8 +30,12 @@
 #include <boost/thread/detail/invoke.hpp>
 #include <boost/thread/detail/make_tuple_indices.hpp>
 
-#if ! defined(BOOST_NO_CXX11_HDR_TUPLE)
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ ! defined(BOOST_NO_CXX11_HDR_TUPLE)
 #include <tuple>
+#else
+#include <boost/tuple/tuple.hpp>
 #endif
 
 namespace boost
@@ -33,7 +44,6 @@
   {
 
 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
- ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
     ! defined(BOOST_NO_CXX11_HDR_TUPLE)
 
     template <class Fp, class... Args>
@@ -42,15 +52,16 @@
         std::tuple<Fp, Args...> f_;
 
     public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
         //typedef typename invoke_of<_Fp, _Args...>::type Rp;
         typedef typename result_of<Fp(Args...)>::type result_type;
 
         BOOST_SYMBOL_VISIBLE
- explicit async_func(Fp&& f, Args&&... args)
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args)... args)
             : f_(boost::move(f), boost::move(args)...) {}
 
         BOOST_SYMBOL_VISIBLE
- async_func(async_func&& f) : f_(boost::move(f.f_)) {}
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
 
         result_type operator()()
         {
@@ -65,24 +76,468 @@
             return invoke(boost::move(std::get<0>(f_)), boost::move(std::get<Indices>(f_))...);
         }
     };
+ //BOOST_THREAD_DCL_MOVABLE_BEG(X) async_func<Fp> BOOST_THREAD_DCL_MOVABLE_END
 #else
+ template <class Fp,
+ class T0 = tuples::null_type, class T1 = tuples::null_type, class T2 = tuples::null_type,
+ class T3 = tuples::null_type, class T4 = tuples::null_type, class T5 = tuples::null_type,
+ class T6 = tuples::null_type, class T7 = tuples::null_type, class T8 = tuples::null_type
+ , class T9 = tuples::null_type>
+ class async_func;
+
+ template <class Fp,
+ class T0 , class T1 , class T2 ,
+ class T3 , class T4 , class T5 ,
+ class T6 , class T7 , class T8 >
+ class async_func<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8>
+ {
+ ::boost::tuple<Fp, T0, T1, T2, T3, T4, T5, T6, T7, T8> f_;
+
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7, T8)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ , BOOST_THREAD_RV_REF(T5) a5
+ , BOOST_THREAD_RV_REF(T6) a6
+ , BOOST_THREAD_RV_REF(T7) a7
+ , BOOST_THREAD_RV_REF(T8) a8
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ , boost::move(a1)
+ , boost::move(a2)
+ , boost::move(a3)
+ , boost::move(a4)
+ , boost::move(a5)
+ , boost::move(a6)
+ , boost::move(a7)
+ , boost::move(a8)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<10, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0, std::size_t I1, std::size_t I2,
+ std::size_t I3, std::size_t I4, std::size_t I5,
+ std::size_t I6, std::size_t I7, std::size_t I8
+ >
+ result_type
+ execute(tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ , boost::move(boost::get<I1>(f_))
+ , boost::move(boost::get<I2>(f_))
+ , boost::move(boost::get<I3>(f_))
+ , boost::move(boost::get<I4>(f_))
+ , boost::move(boost::get<I5>(f_))
+ , boost::move(boost::get<I6>(f_))
+ , boost::move(boost::get<I7>(f_))
+ , boost::move(boost::get<I8>(f_))
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7 >
+ class async_func<Fp, T0, T1, T2, T3, T4, T5, T6, T7>
+ {
+ ::boost::tuple<Fp, T0, T1, T2, T3, T4, T5, T6, T7> f_;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6, T7)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ , BOOST_THREAD_RV_REF(T5) a5
+ , BOOST_THREAD_RV_REF(T6) a6
+ , BOOST_THREAD_RV_REF(T7) a7
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ , boost::move(a1)
+ , boost::move(a2)
+ , boost::move(a3)
+ , boost::move(a4)
+ , boost::move(a5)
+ , boost::move(a6)
+ , boost::move(a7)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<9, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0, std::size_t I1, std::size_t I2,
+ std::size_t I3, std::size_t I4, std::size_t I5,
+ std::size_t I6, std::size_t I7
+ >
+ result_type
+ execute(tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ , boost::move(boost::get<I1>(f_))
+ , boost::move(boost::get<I2>(f_))
+ , boost::move(boost::get<I3>(f_))
+ , boost::move(boost::get<I4>(f_))
+ , boost::move(boost::get<I5>(f_))
+ , boost::move(boost::get<I6>(f_))
+ , boost::move(boost::get<I7>(f_))
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5, class T6>
+ class async_func<Fp, T0, T1, T2, T3, T4, T5, T6>
+ {
+ ::boost::tuple<Fp, T0, T1, T2, T3, T4, T5, T6> f_;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5, T6)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ , BOOST_THREAD_RV_REF(T5) a5
+ , BOOST_THREAD_RV_REF(T6) a6
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ , boost::move(a1)
+ , boost::move(a2)
+ , boost::move(a3)
+ , boost::move(a4)
+ , boost::move(a5)
+ , boost::move(a6)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<8, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5, std::size_t I6
+ >
+ result_type
+ execute(tuple_indices<I0, I1, I2, I3, I4, I5, I6>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ , boost::move(boost::get<I1>(f_))
+ , boost::move(boost::get<I2>(f_))
+ , boost::move(boost::get<I3>(f_))
+ , boost::move(boost::get<I4>(f_))
+ , boost::move(boost::get<I5>(f_))
+ , boost::move(boost::get<I6>(f_))
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3, class T4, class T5>
+ class async_func<Fp, T0, T1, T2, T3, T4, T5>
+ {
+ ::boost::tuple<Fp, T0, T1, T2, T3, T4, T5> f_;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4, T5)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ , BOOST_THREAD_RV_REF(T5) a5
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ , boost::move(a1)
+ , boost::move(a2)
+ , boost::move(a3)
+ , boost::move(a4)
+ , boost::move(a5)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<7, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ >
+ result_type
+ execute(tuple_indices<I0, I1, I2, I3, I4, I5>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ , boost::move(boost::get<I1>(f_))
+ , boost::move(boost::get<I2>(f_))
+ , boost::move(boost::get<I3>(f_))
+ , boost::move(boost::get<I4>(f_))
+ , boost::move(boost::get<I5>(f_))
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3, class T4>
+ class async_func<Fp, T0, T1, T2, T3, T4>
+ {
+ ::boost::tuple<Fp, T0, T1, T2, T3, T4> f_;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0, T1, T2, T3, T4)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ , BOOST_THREAD_RV_REF(T4) a4
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ , boost::move(a1)
+ , boost::move(a2)
+ , boost::move(a3)
+ , boost::move(a4)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<6, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4
+ >
+ result_type
+ execute(tuple_indices<I0, I1, I2, I3, I4>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ , boost::move(boost::get<I1>(f_))
+ , boost::move(boost::get<I2>(f_))
+ , boost::move(boost::get<I3>(f_))
+ , boost::move(boost::get<I4>(f_))
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2, class T3>
+ class async_func<Fp, T0, T1, T2, T3>
+ {
+ ::boost::tuple<Fp, T0, T1, T2, T3> f_;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0, T1, T2, T3)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ , BOOST_THREAD_RV_REF(T3) a3
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ , boost::move(a1)
+ , boost::move(a2)
+ , boost::move(a3)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<5, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3
+ >
+ result_type
+ execute(tuple_indices<I0, I1, I2, I3>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ , boost::move(boost::get<I1>(f_))
+ , boost::move(boost::get<I2>(f_))
+ , boost::move(boost::get<I3>(f_))
+ );
+ }
+ };
+ template <class Fp, class T0, class T1, class T2>
+ class async_func<Fp, T0, T1, T2>
+ {
+ ::boost::tuple<Fp, T0, T1, T2> f_;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0, T1, T2)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ , BOOST_THREAD_RV_REF(T2) a2
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ , boost::move(a1)
+ , boost::move(a2)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<4, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0, std::size_t I1, std::size_t I2
+ >
+ result_type
+ execute(tuple_indices<I0, I1, I2>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ , boost::move(boost::get<I1>(f_))
+ , boost::move(boost::get<I2>(f_))
+ );
+ }
+ };
+ template <class Fp, class T0, class T1>
+ class async_func<Fp, T0, T1>
+ {
+ ::boost::tuple<Fp, T0, T1> f_;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0, T1)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ , BOOST_THREAD_RV_REF(T1) a1
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ , boost::move(a1)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<3, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0, std::size_t I1
+ >
+ result_type
+ execute(tuple_indices<I0, I1>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ , boost::move(boost::get<I1>(f_))
+ );
+ }
+ };
+ template <class Fp, class T0>
+ class async_func<Fp, T0>
+ {
+ ::boost::tuple<Fp, T0> f_;
+ public:
+ BOOST_THREAD_MOVABLE_ONLY(async_func)
+ typedef typename result_of<Fp(T0)>::type result_type;
+
+ BOOST_SYMBOL_VISIBLE
+ explicit async_func(BOOST_THREAD_RV_REF(Fp) f
+ , BOOST_THREAD_RV_REF(T0) a0
+ )
+ : f_(boost::move(f)
+ , boost::move(a0)
+ ) {}
+
+ BOOST_SYMBOL_VISIBLE
+ async_func(BOOST_THREAD_RV_REF(async_func) f) : f_(boost::move(f.f_)) {}
+
+ result_type operator()()
+ {
+ typedef typename make_tuple_indices<2, 1>::type Index;
+ return execute(Index());
+ }
+ private:
+ template <
+ std::size_t I0
+ >
+ result_type
+ execute(tuple_indices<I0>)
+ {
+ return invoke(boost::move(boost::get<0>(f_))
+ , boost::move(boost::get<I0>(f_))
+ );
+ }
+ };
     template <class Fp>
- class async_func
+ class async_func<Fp>
     {
         Fp f_;
-
     public:
         BOOST_THREAD_COPYABLE_AND_MOVABLE(async_func)
-
         typedef typename result_of<Fp()>::type result_type;
-
         BOOST_SYMBOL_VISIBLE
         explicit async_func(BOOST_THREAD_FWD_REF(Fp) f)
             : f_(boost::move(f)) {}
 
         BOOST_SYMBOL_VISIBLE
         async_func(BOOST_THREAD_FWD_REF(async_func) f) : f_(boost::move(f.f_)) {}
-
         result_type operator()()
         {
             return execute();
@@ -95,6 +550,34 @@
         }
     };
 #endif
+//#else
+// template <class Fp>
+// class async_func
+// {
+// Fp f_;
+// public:
+// BOOST_THREAD_COPYABLE_AND_MOVABLE(async_func)
+// typedef typename result_of<Fp()>::type result_type;
+// BOOST_SYMBOL_VISIBLE
+// explicit async_func(BOOST_THREAD_FWD_REF(Fp) f)
+// : f_(boost::move(f)) {}
+//
+// BOOST_SYMBOL_VISIBLE
+// async_func(BOOST_THREAD_FWD_REF(async_func) f) : f_(boost::move(f.f_)) {}
+// result_type operator()()
+// {
+// return execute();
+// }
+// private:
+// result_type
+// execute()
+// {
+// return f_();
+// }
+// };
+// //BOOST_THREAD_DCL_MOVABLE_BEG(Fp) async_func<Fp> BOOST_THREAD_DCL_MOVABLE_END
+//#endif
+
   }
 }
 

Modified: branches/release/boost/thread/detail/invoke.hpp
==============================================================================
--- branches/release/boost/thread/detail/invoke.hpp (original)
+++ branches/release/boost/thread/detail/invoke.hpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -1,8 +1,17 @@
-// Copyright (C) 2012 Vicente J. Botet Escriba
+// Copyright (C) 2012-2013 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)
 
+// 2013/04 Vicente J. Botet Escriba
+// Provide implementation up to 9 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
+// Make use of Boost.Move
+// Make use of Boost.Tuple (movable)
+// 2012 Vicente J. Botet Escriba
+// Provide implementation _RET using bind when BOOST_NO_CXX11_HDR_FUNCTIONAL and BOOST_NO_SFINAE_EXPR are not defined
+// 2012 Vicente J. Botet Escriba
+// Adapt to boost libc++ implementation
+
 //===----------------------------------------------------------------------===//
 //
 // The LLVM Compiler Infrastructure
@@ -19,6 +28,8 @@
 #include <boost/config.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/thread/detail/move.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/remove_reference.hpp>
 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
 #include <functional>
 #endif
@@ -28,20 +39,20 @@
   namespace detail
   {
 
-#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
 
-#if ! defined(BOOST_NO_SFINAE_EXPR) && \
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ ! defined(BOOST_NO_SFINAE_EXPR) && \
     ! defined(BOOST_NO_CXX11_DECLTYPE) && \
     ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
     ! defined(BOOST_NO_CXX11_AUTO)
 
 #define BOOST_THREAD_PROVIDES_INVOKE
 
- // // bullets 1 and 2
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ // bullets 1 and 2
 
     template <class Fp, class A0, class ...Args>
- inline
- auto
+ inline auto
     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
         -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...))
     {
@@ -49,8 +60,7 @@
     }
 
     template <class Fp, class A0, class ...Args>
- inline
- auto
+ inline auto
     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
         -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...))
     {
@@ -60,8 +70,7 @@
     // bullets 3 and 4
 
     template <class Fp, class A0>
- inline
- auto
+ inline auto
     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
         -> decltype(boost::forward<A0>(a0).*f)
     {
@@ -69,8 +78,7 @@
     }
 
     template <class Fp, class A0>
- inline
- auto
+ inline auto
     invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
         -> decltype((*boost::forward<A0>(a0)).*f)
     {
@@ -80,36 +88,14 @@
     // bullet 5
 
     template <class Fp, class ...Args>
- inline
- auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
+ inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
     -> decltype(boost::forward<Fp>(f)(boost::forward<Args>(args)...))
     {
       return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
     }
-#elif ! defined(BOOST_NO_SFINAE_EXPR) && \
- ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL
-
- template <class Ret, class Fp, class ...Args>
- inline
- Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
- {
- return std::bind(boost::forward<Fp>(f), boost::forward<Args>(args)...)();
- }
-
-#define BOOST_THREAD_PROVIDES_INVOKE_RET
-
-#endif
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
 
-#else //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
-#if ! defined(BOOST_NO_SFINAE_EXPR) && \
- ! defined(BOOST_NO_CXX11_DECLTYPE) && \
- ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
- ! defined(BOOST_NO_CXX11_AUTO)
-
-#define BOOST_THREAD_PROVIDES_INVOKE
-
- // // bullets 1 and 2
+ // bullets 1 and 2
 
     template <class Fp, class A0>
     inline
@@ -211,9 +197,11 @@
       return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
     }
 
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
 
 #elif ! defined(BOOST_NO_SFINAE_EXPR) && \
- ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL
+ ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL && \
+ defined BOOST_MSVC
 
     template <class Ret, class Fp>
     inline
@@ -242,10 +230,1121 @@
 
 #define BOOST_THREAD_PROVIDES_INVOKE_RET
 
-#endif
+#elif ! defined BOOST_MSVC
+//!!!!! WARNING !!!!! THIS DOESN'T WORKS YET
+#define BOOST_THREAD_PROVIDES_INVOKE_RET
+
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ // bullet 1
+ // (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of
+ // type T or a reference to an object of type T or a reference to an object of a type derived from T
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
+ }
+
+ // bullet 2
+ // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of
+ // the types described in the previous item;
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ template <class Ret, class A, class A0, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(Args...) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
+ }
+
+ // bullet 3
+ // t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a
+ // reference to an object of type T or a reference to an object of a type derived from T;
+// template <class Ret, class A, class A0>
+// inline
+// typename enable_if_c
+// <
+// is_base_of<A, typename remove_reference<A0>::type>::value,
+// typename detail::apply_cv<A0, A>::type&
+// >::type
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return boost::forward<A0>(a0).*f;
+// }
+
+ // bullet 4
+ // (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types
+ //described in the previous item;
+
+// template <class A0, class Ret, bool>
+// struct d4th_helper
+// {
+// };
+//
+// template <class A0, class Ret>
+// struct d4th_helper<A0, Ret, true>
+// {
+// typedef typename apply_cv<decltype(*declval<A0>()), Ret>::type type;
+// };
+//
+// template <class Ret, class A, class A0>
+// inline
+// typename detail::4th_helper<A, Ret,
+// !is_base_of<A,
+// typename remove_reference<A0>::type
+// >::value
+// >::type&
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+// template <class Ret, class A, class A0>
+// inline
+// typename enable_if_c
+// <
+// !is_base_of<A, typename remove_reference<A0>::type>::value,
+// typename detail::ref_return1<Ret A::*, A0>::type
+// >::type
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+ // bullet 5
+ // f(t1, t2, ..., tN) in all other cases.
 
+ template <class Ret, class Fp, class ...Args>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
+ }
+ template <class Ret, class ...Args>
+ inline Ret
+ invoke(Ret(*f)(Args... ), BOOST_THREAD_RV_REF(Args) ...args)
+ {
+ return f(boost::forward<Args>(args)...);
+ }
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ // bullet 1
+ // (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of
+ // type T or a reference to an object of type T or a reference to an object of a type derived from T
+
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(), BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), A0 a0, A1 a1)
+ {
+ return (a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2),
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2), A0 a0, A1 a1, A2 a2)
+ {
+ return (a0.*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3),
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return (a0.*f)(a1, a2, a3);
+ }
+
+///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, A0 a0, A1 a1)
+ {
+ return (a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2)
+ );
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const, A0 a0, A1 a1, A2 a2)
+ {
+ return (a0.*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return (a0.*f)(a1, a2, a3);
+ }
+ ///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() volatile, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) volatile, A0 a0, A1 a1)
+ {
+ return (a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) volatile, A0 a0, A1 a1, A2 a2 )
+ {
+ return (a0.*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return (a0.*f)(a1, a2, a3);
+ }
+ ///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const volatile, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const volatile, A0 a0, A1 a1)
+ {
+ return (a0.*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const volatile,
+ A0 a0, A1 a1, A2 a2
+ )
+ {
+ return (a0.*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3
+ )
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const volatile,
+ A0 a0, A1 a1, A2 a2, A3 a3
+ )
+ {
+ return (a0.*f)(a1, a2, a3);
+ }
+
+ // bullet 2
+ // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of
+ // the types described in the previous item;
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(), BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1), A0 a0, A1 a1)
+ {
+ return ((*a0).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, BOOST_THREAD_RV_REF(A2)),
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2), A0 a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, BOOST_THREAD_RV_REF(A2), BOOST_THREAD_RV_REF(A3)),
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)
+ );
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+
+///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, BOOST_THREAD_RV_REF(A0) a0, A1 a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const, A0 a0, A1 a1)
+ {
+ return ((*a0).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const, A0 a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const,
+ A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+ ///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() volatile, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) volatile, A0 a0, A1 a1)
+ {
+ return ((*a0).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) volatile, A0 a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+ ///
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const volatile, BOOST_THREAD_RV_REF(A0) a0)
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Ret, class A, class A0>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)() const volatile, A0 a0)
+ {
+ return ((*a0).*f)();
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A, class A0, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1) const volatile, A0 a0, A1 a1)
+ {
+ return ((*a0).*f)(a1);
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A, class A0, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2) const volatile,
+ A0 a0, A1 a1, A2 a2)
+ {
+ return ((*a0).*f)(a1, a2);
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const volatile,
+ BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class A, class A0, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_base_of<A, typename remove_reference<A0>::type>::value,
+ Ret
+ >::type
+ invoke(Ret (A::*f)(A1, A2, A3) const volatile,
+ A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ return ((*a0).*f)(a1, a2, a3);
+ }
+ // bullet 3
+ // t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a
+ // reference to an object of type T or a reference to an object of a type derived from T;
+// template <class Ret, class A, class A0>
+// inline
+// typename enable_if_c
+// <
+// is_base_of<A, typename remove_reference<A0>::type>::value,
+// typename detail::apply_cv<A0, A>::type&
+// >::type
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return boost::forward<A0>(a0).*f;
+// }
+
+ // bullet 4
+ // (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types
+ //described in the previous item;
+
+// template <class A0, class Ret, bool>
+// struct d4th_helper
+// {
+// };
+//
+// template <class A0, class Ret>
+// struct d4th_helper<A0, Ret, true>
+// {
+// typedef typename apply_cv<decltype(*declval<A0>()), Ret>::type type;
+// };
+//
+// template <class Ret, class A, class A0>
+// inline
+// typename detail::4th_helper<A, Ret,
+// !is_base_of<A,
+// typename remove_reference<A0>::type
+// >::value
+// >::type&
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+// template <class Ret, class A, class A0>
+// inline
+// typename enable_if_c
+// <
+// !is_base_of<A, typename remove_reference<A0>::type>::value,
+// typename detail::ref_return1<Ret A::*, A0>::type
+// >::type
+// invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0)
+// {
+// return (*boost::forward<A0>(a0)).*f;
+// }
+
+ // bullet 5
+ // f(t1, t2, ..., tN) in all other cases.
+
+ template <class Ret, class Fp>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f)
+ {
+ return boost::forward<Fp>(f)();
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1));
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, A1 a1)
+ {
+ return boost::forward<Fp>(f)(a1);
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, A1 a1, A2 a2)
+ {
+ return boost::forward<Fp>(f)(a1, a2);
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, A1 a1, A2 a2, A3 a3)
+ {
+ return boost::forward<Fp>(f)(a1, a2, a3);
+ }
+
+ ///
+ template <class Ret, class Fp>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp const &f)
+ {
+ return f();
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp const &f, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return f(boost::forward<A1>(a1));
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp const &f, A1 a1)
+ {
+ return f(a1);
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp const &f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp const &f, A1 a1, A2 a2)
+ {
+ return f(a1, a2);
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp const &f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(Fp const &f, A1 a1, A2 a2, A3 a3)
+ {
+ return f(a1, a2, a3);
+ }
+ ///
+
+ template <class Ret>
+ inline Ret
+ invoke(Ret(*f)())
+ {
+ return f();
+ }
+ template <class Ret, class A1>
+ inline Ret
+ invoke(Ret(*f)(A1), BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return f(boost::forward<A1>(a1));
+ }
+ template <class Ret, class A1, class A2>
+ inline Ret
+ invoke(Ret(*f)(A1, A2),
+ BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Ret, class A1, class A2, class A3>
+ inline Ret
+ invoke(Ret(*f)(A1, A2, A3),
+ BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
 
-#endif // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#endif // all
       }
     }
 

Modified: branches/release/boost/thread/detail/make_tuple_indices.hpp
==============================================================================
--- branches/release/boost/thread/detail/make_tuple_indices.hpp (original)
+++ branches/release/boost/thread/detail/make_tuple_indices.hpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -1,8 +1,13 @@
-// Copyright (C) 2012 Vicente J. Botet Escriba
+// Copyright (C) 2012-2013 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)
 
+// 2013/04 Vicente J. Botet Escriba
+// Provide implementation up to 10 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
+// 2012/11 Vicente J. Botet Escriba
+// Adapt to boost libc++ implementation
+
 //===----------------------------------------------------------------------===//
 //
 // The LLVM Compiler Infrastructure
@@ -10,7 +15,7 @@
 // This file is dual licensed under the MIT and the University of Illinois Open
 // Source Licenses. See LICENSE.TXT for details.
 //
-// The make_tuple_indices code is based on the one from libcxx.
+// The make_tuple_indices C++11 code is based on the one from libcxx.
 //===----------------------------------------------------------------------===//
 
 #ifndef BOOST_THREAD_DETAIL_MAKE_TUPLE_INDICES_HPP
@@ -24,9 +29,7 @@
   namespace detail
   {
 
-#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
- ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
-
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
     // make_tuple_indices
 
     template <std::size_t...> struct tuple_indices
@@ -53,6 +56,167 @@
       BOOST_STATIC_ASSERT_MSG(Sp <= Ep, "make_tuple_indices input error");
       typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
     };
+#else
+
+ // - tuple forward declaration -----------------------------------------------
+ template <
+ std::size_t T0 = 0, std::size_t T1 = 0, std::size_t T2 = 0,
+ std::size_t T3 = 0, std::size_t T4 = 0, std::size_t T5 = 0,
+ std::size_t T6 = 0, std::size_t T7 = 0, std::size_t T8 = 0,
+ std::size_t T9 = 0>
+ class 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 Ep>
+ struct make_indices_imp<Sp, tuple_indices<>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5, std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ , std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, Sp>, Ep>::type type;
+ };
+ template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ , std::size_t I8
+ , std::size_t Ep>
+ struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7, I8>, Ep>
+ {
+ typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, Sp>, Ep>::type type;
+ };
+// template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+// , std::size_t I6
+// , std::size_t I7
+// , std::size_t I8
+// , std::size_t I9
+// , std::size_t Ep>
+// struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7, I8, I9>, Ep>
+// {
+// typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, Sp>, Ep>::type type;
+// };
+
+ template <std::size_t Ep>
+ struct make_indices_imp<Ep, tuple_indices<>, Ep>
+ {
+ typedef tuple_indices<> type;
+ };
+ template <std::size_t Ep, std::size_t I0>
+ struct make_indices_imp<Ep, tuple_indices<I0>, Ep>
+ {
+ typedef tuple_indices<I0> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1>, Ep>
+ {
+ typedef tuple_indices<I0, I1> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5>
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ >
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ >
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7> type;
+ };
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ , std::size_t I8
+ >
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8> type;
+ };
+
+ template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
+ , std::size_t I6
+ , std::size_t I7
+ , std::size_t I8
+ , std::size_t I9
+ >
+ struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9>, Ep>
+ {
+ typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9> type;
+ };
+
+ template <std::size_t Ep, std::size_t Sp = 0>
+ struct make_tuple_indices
+ {
+ BOOST_STATIC_ASSERT_MSG(Sp <= Ep, "make_tuple_indices input error");
+ typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
+ };
+
 #endif
   }
 }

Modified: branches/release/boost/thread/externally_locked.hpp
==============================================================================
--- branches/release/boost/thread/externally_locked.hpp (original)
+++ branches/release/boost/thread/externally_locked.hpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -33,6 +33,8 @@
 
   //[externally_locked
   template <typename T, typename MutexType = boost::mutex>
+ class externally_locked;
+ template <typename T, typename MutexType>
   class externally_locked
   {
     //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
@@ -46,7 +48,7 @@
      * Requires: T is a model of CopyConstructible.
      * Effects: Constructs an externally locked object copying the cloaked type.
      */
- BOOST_CONSTEXPR externally_locked(mutex_type& mtx, const T& obj) :
+ externally_locked(mutex_type& mtx, const T& obj) :
       obj_(obj), mtx_(&mtx)
     {
     }
@@ -55,7 +57,7 @@
      * Requires: T is a model of Movable.
      * Effects: Constructs an externally locked object by moving the cloaked type.
      */
- BOOST_CONSTEXPR externally_locked(mutex_type& mtx, BOOST_THREAD_RV_REF(T) obj) :
+ externally_locked(mutex_type& mtx, BOOST_THREAD_RV_REF(T) obj) :
       obj_(move(obj)), mtx_(&mtx)
     {
     }
@@ -64,18 +66,46 @@
      * Requires: T is a model of DefaultConstructible.
      * Effects: Constructs an externally locked object initializing the cloaked type with the default constructor.
      */
- externally_locked(mutex_type& mtx) :
- obj_(), mtx_(&mtx)
+ externally_locked(mutex_type& mtx) // BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T()))
+ : obj_(), mtx_(&mtx)
     {
     }
 
     /**
+ * Copy constructor
+ */
+ externally_locked(externally_locked const& rhs) //BOOST_NOEXCEPT
+ : obj_(rhs.obj_), mtx_(rhs.mtx_)
+ {
+ }
+ /**
      * Move constructor
      */
- externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) :
- obj_(move(rhs.obj_)), mtx_(rhs.mtx_)
+ externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) //BOOST_NOEXCEPT
+ : obj_(move(rhs.obj_)), mtx_(rhs.mtx_)
+ {
+ }
+
+ /// assignment
+ externally_locked& operator=(externally_locked const& rhs) //BOOST_NOEXCEPT
+ {
+ obj_=rhs.obj_;
+ mtx_=rhs.mtx_;
+ return *this;
+ }
+
+ /// move assignment
+ externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) // BOOST_NOEXCEPT
+ {
+ obj_=move(rhs.obj_);
+ mtx_=rhs.mtx_;
+ return *this;
+ }
+
+ void swap(externally_locked& rhs) //BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR)
     {
- rhs.mtx_=0;
+ swap(obj_, rhs.obj_);
+ swap(mtx_, rhs.mtx_);
     }
 
     /**
@@ -126,13 +156,13 @@
       BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value)); /*< lk is a strict lock "sur parolle" >*/
       BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value)); /*< that locks the same type >*/
 
- BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(), lock_error() ); /*< run time check throw if no locked >*/
+ //BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(), lock_error() ); /*< run time check throw if no locked >*/
       BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
 
       return obj_;
     }
 
- mutex_type* mutex()
+ mutex_type* mutex() const BOOST_NOEXCEPT
     {
       return mtx_;
     }
@@ -175,25 +205,45 @@
   public:
     typedef MutexType mutex_type;
 
- BOOST_THREAD_MOVABLE_ONLY( externally_locked )
+ BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
 
     /**
      * Effects: Constructs an externally locked object storing the cloaked reference object.
      */
- externally_locked(T& obj, mutex_type& mtx) :
+ externally_locked(T& obj, mutex_type& mtx) BOOST_NOEXCEPT :
       obj_(&obj), mtx_(&mtx)
     {
     }
 
+ /// copy constructor
+ externally_locked(externally_locked const& rhs) BOOST_NOEXCEPT :
+ obj_(rhs.obj_), mtx_(rhs.mtx_)
+ {
+ }
+
     /// move constructor
- externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) :
+ externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT :
     obj_(rhs.obj_), mtx_(rhs.mtx_)
     {
- rhs.obj_=0;
- rhs.mtx_=0;
     }
 
- void swap(externally_locked& rhs)
+ /// assignment
+ externally_locked& operator=(externally_locked const& rhs) BOOST_NOEXCEPT
+ {
+ obj_=rhs.obj_;
+ mtx_=rhs.mtx_;
+ return *this;
+ }
+
+ /// move assignment
+ externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT
+ {
+ obj_=rhs.obj_;
+ mtx_=rhs.mtx_;
+ return *this;
+ }
+
+ void swap(externally_locked& rhs) BOOST_NOEXCEPT
     {
       swap(obj_, rhs.obj_);
       swap(mtx_, rhs.mtx_);
@@ -266,7 +316,7 @@
       BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() ); /*< run time check throw if not locks the same >*/
       return *obj_;
     }
- mutex_type* mutex()
+ mutex_type* mutex() const BOOST_NOEXCEPT
     {
       return mtx_;
     }
@@ -292,7 +342,7 @@
   //]
 
   template <typename T, typename MutexType>
- void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs)
+ void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs) // BOOST_NOEXCEPT
   {
     lhs.swap(rhs);
   }

Modified: branches/release/boost/thread/pthread/thread_data.hpp
==============================================================================
--- branches/release/boost/thread/pthread/thread_data.hpp (original)
+++ branches/release/boost/thread/pthread/thread_data.hpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -132,8 +132,10 @@
             bool interrupt_requested;
 //#endif
             thread_data_base():
+ thread_handle(0),
                 done(false),join_started(false),joined(false),
                 thread_exit_callbacks(0),
+ cond_mutex(0),
                 current_cond(0),
                 notify(),
                 async_states_()

Modified: branches/release/libs/thread/doc/barrier.qbk
==============================================================================
--- branches/release/libs/thread/doc/barrier.qbk (original)
+++ branches/release/libs/thread/doc/barrier.qbk 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -18,6 +18,9 @@
     class barrier
     {
     public:
+ barrier(barrier const&) = delete;
+ barrier& operator=(barrier const&) = delete;
+
         barrier(unsigned int count);
         ~barrier();
 

Modified: branches/release/libs/thread/doc/changes.qbk
==============================================================================
--- branches/release/libs/thread/doc/changes.qbk (original)
+++ branches/release/libs/thread/doc/changes.qbk 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -15,6 +15,7 @@
 
 * [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Add externally locked streams
 * [@http://svn.boost.org/trac/boost/ticket/8274 #8274] Add concurrent queue
+* [@http://svn.boost.org/trac/boost/ticket/8518 #8518] Sync: Add a latch class
 
 [*Fixed Bugs:]
 
@@ -50,7 +51,8 @@
 * [@http://svn.boost.org/trac/boost/ticket/8337 #8337] The internal representation of "std::string(this->code()->message())" escapes, but is destroyed when it exits scope.
 * [@http://svn.boost.org/trac/boost/ticket/8371 #8371] C++11 once_flag enabled when constexpr is not available
 * [@http://svn.boost.org/trac/boost/ticket/8443 #8443] Header file inclusion order may cause crashes
-* [@http://svn.boost.org/trac/boost/ticket/8451 #8451] Mmissing documented function 'boost::scoped_thread::joinable'
+* [@http://svn.boost.org/trac/boost/ticket/8451 #8451] Missing documented function 'boost::scoped_thread::joinable'
+* [@http://svn.boost.org/trac/boost/ticket/8451 #8530] [Coverity] Unused variable thread_handle, uninitialized variable cond_mutex in thread/pthread/thread_data.hpp
 
 
 [heading Version 4.0.0 - boost 1.53]
@@ -394,18 +396,29 @@
 The following features will be included in next releases.
 
 # Complete the C++11 missing features, in particular
- * [@http://svn.boost.org/trac/boost/ticket/7285 #7285] C++11 compliance: Allow to pass movable arguments for call_once.
   * [@http://svn.boost.org/trac/boost/ticket/6227 #6227] C++11 compliance: Use of variadic templates on Generic Locking Algorithms on compilers providing them.
 
+# Add some minor features, in particular
+ * [@http://svn.boost.org/trac/boost/ticket/7589 #7589] Synchro: Add polymorphic lockables.
 
-# 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
+# Add some features based on C++ proposals, in particular
+ * [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Add externally locked streams
+ * [@http://svn.boost.org/trac/boost/ticket/8274 #8274] Add concurrent queue
+ * [@http://svn.boost.org/trac/boost/ticket/8518 #8518] Sync: Add a latch class
+ * [@http://svn.boost.org/trac/boost/ticket/XXXX #XXXX] Sync: Add a completion_latch class
+ * [@http://svn.boost.org/trac/boost/ticket/8513 #8513] Async: Add a basic thread_pool executor.
+ * [@http://svn.boost.org/trac/boost/ticket/8514 #8514] Async: Add a thread_pool executor with work stealing.
+
+# 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] or extension to them, in particular
 
- * [@http://svn.boost.org/trac/boost/ticket/7589 #7589] Synchro: Add polymorphic lockables.
- * [@http://svn.boost.org/trac/boost/ticket/7449 #7449] Synchro: Add a synchronized value class.
- * [@http://svn.boost.org/trac/boost/ticket/7445 #7445] Async: Add future<>.then.
   * [@http://svn.boost.org/trac/boost/ticket/7446 #7446] Async: Add when_any.
   * [@http://svn.boost.org/trac/boost/ticket/7447 #7447] Async: Add when_all.
   * [@http://svn.boost.org/trac/boost/ticket/7448 #7448] Async: Add async taking a scheduler parameter.
+ * [@http://svn.boost.org/trac/boost/ticket/8515 #8515] Async: Add shared_future::then
+ * [@http://svn.boost.org/trac/boost/ticket/8516 #8516] Async: Add future/shared_future::then taking a scheduler as parameter.
+ * [@http://svn.boost.org/trac/boost/ticket/8517 #8517] Async: Add a variadic future/shared_future::then
+
+
 
 
 [endsect]

Modified: branches/release/libs/thread/doc/mutex_concepts.qbk
==============================================================================
--- branches/release/libs/thread/doc/mutex_concepts.qbk (original)
+++ branches/release/libs/thread/doc/mutex_concepts.qbk 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -2441,10 +2441,13 @@
   // #include <boost/thread/externally_locked.hpp>
   template <class T, typename MutexType = boost::mutex>
   class externally_locked;
+ template <class T, typename MutexType>
+ class externally_locked<T&, MutexType>;
+
   template <typename T, typename MutexType>
   void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs);
 
-[section Template Class `externally_locked`]
+[section:externally_locked Template Class `externally_locked`]
 
   // #include <boost/thread/externally_locked.hpp>
 
@@ -2460,8 +2463,11 @@
     externally_locked(mutex_type& mtx, const T& obj);
     externally_locked(mutex_type& mtx,T&& obj);
     explicit externally_locked(mutex_type& mtx);
+ externally_locked(externally_locked const& rhs);
     externally_locked(externally_locked&& rhs);
-
+ externally_locked& operator=(externally_locked const& rhs);
+ externally_locked& operator=(externally_locked&& rhs);
+
     // observers
     T& get(strict_lock<mutex_type>& lk);
     const T& get(strict_lock<mutex_type>& lk) const;
@@ -2476,7 +2482,7 @@
     template <class Lock>
     T const& get(Lock& lk) const;
 
- mutex_type* mutex();
+ mutex_type* mutex() const noexcept;
 
     // modifiers
     void lock();
@@ -2540,7 +2546,7 @@
 
 [endsect]
 [///////////////////////////////]
-[section:constructor4 `externally_locked(externally_locked&)`]
+[section:constructor4 `externally_locked(externally_locked&&)`]
 
     externally_locked(externally_locked&& rhs);
 
@@ -2548,7 +2554,7 @@
 
 [[Requires:] [T is a model of Movable.]]
 
-[[Effects:] [Moves an externally locked object by moving the the cloaked type and copying the mutex reference ]]
+[[Effects:] [Move constructs an externally locked object by moving the cloaked type and copying the mutex reference ]]
 
 [[Throws:] [Any exception thrown by the call to `T(T&&)`.]]
 
@@ -2556,6 +2562,55 @@
 
 [endsect]
 [///////////////////////////////]
+[section:constructor5 `externally_locked(externally_locked&)`]
+
+ externally_locked(externally_locked& rhs);
+
+[variablelist
+
+[[Requires:] [T is a model of Copyable.]]
+
+[[Effects:] [Copy constructs an externally locked object by copying the cloaked type and copying the mutex reference ]]
+
+[[Throws:] [Any exception thrown by the call to `T(T&)`.]]
+
+]
+
+[endsect]
+[///////////////////////////////]
+[section:assign4 `externally_locked(externally_locked&&)`]
+
+ externally_locked& operator=(externally_locked&& rhs);
+
+[variablelist
+
+[[Requires:] [T is a model of Movable.]]
+
+[[Effects:] [Move assigns an externally locked object by moving the cloaked type and copying the mutex reference ]]
+
+[[Throws:] [Any exception thrown by the call to `T::operator=(T&&)`.]]
+
+]
+
+[endsect]
+[///////////////////////////////]
+[section:assign5 `externally_locked(externally_locked&)`]
+
+ externally_locked& operator=(externally_locked const& rhs);
+
+[variablelist
+
+[[Requires:] [T is a model of Copyable.]]
+
+[[Effects:] [Copy assigns an externally locked object by copying the cloaked type and copying the mutex reference ]]
+
+[[Throws:] [Any exception thrown by the call to `T::operator=(T&)`.]]
+
+]
+
+[endsect]
+
+[///////////////////////////////]
 [section:get1 `get(strict_lock<mutex_type>&)`]
 
     T& get(strict_lock<mutex_type>& lk);
@@ -2613,8 +2668,172 @@
 [endsect]
 
 [endsect]
+[section:externally_locked_ref Template Class `externally_locked<T&>`]
+
+ // #include <boost/thread/externally_locked.hpp>
+
+ template <class T, typename MutexType>
+ class externally_locked<T&, MutexType>
+ {
+ //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
+ BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
+
+ public:
+ typedef MutexType mutex_type;
+
+ externally_locked(mutex_type& mtx, T& obj);
+ explicit externally_locked(mutex_type& mtx);
+ externally_locked(externally_locked const& rhs) noexcept;
+ externally_locked(externally_locked&& rhs) noexcept;
+ externally_locked& operator=(externally_locked const& rhs) noexcept;
+ externally_locked& operator=(externally_locked&& rhs) noexcept;
+
+ // observers
+ T& get(strict_lock<mutex_type>& lk);
+ const T& get(strict_lock<mutex_type>& lk) const;
+
+ template <class Lock>
+ T& get(nested_strict_lock<Lock>& lk);
+ template <class Lock>
+ const T& get(nested_strict_lock<Lock>& lk) const;
+
+ template <class Lock>
+ T& get(Lock& lk);
+ template <class Lock>
+ T const& get(Lock& lk) const;
+
+ mutex_type* mutex() const noexcept;
+
+ // modifiers
+ void lock();
+ void unlock();
+ bool try_lock();
+ void swap(externally_locked&) noexcept;
+ };
+
+`externally_locked` is a model of __Lockable, it cloaks an object of type `T`, and actually provides full
+access to that object through the get and set member functions, provided you
+pass a reference to a strict lock object.
+
+Only the specificities respect to __Lockable are described here.
+
+[///////////////////////////////]
+[section:constructor1 `externally_locked<T&>(mutex_type&, T&)`]
+
+ externally_locked<T&>(mutex_type& mtx, T& obj) noexcept;
+
+[variablelist
+
+
+[[Effects:] [Constructs an externally locked object copying the cloaked reference.]]
+
+]
+
+[endsect]
+[///////////////////////////////]
+[section:constructor4 `externally_locked<T&>(externally_locked&&)`]
+
+ externally_locked(externally_locked&& rhs) noexcept;
+
+[variablelist
+
+[[Effects:] [Moves an externally locked object by moving the cloaked type and copying the mutex reference ]]
+
+
+]
+
+[endsect]
+[///////////////////////////////]
+[section:assign4 `externally_locked(externally_locked&&)`]
+
+ externally_locked& operator=(externally_locked&& rhs);
+
+[variablelist
+
+[[Effects:] [Move assigns an externally locked object by copying the cloaked reference and copying the mutex reference ]]
+
+]
+
+[endsect]
+[///////////////////////////////]
+[section:assign5 `externally_locked(externally_locked&)`]
+
+ externally_locked& operator=(externally_locked const& rhs);
+
+[variablelist
+
+[[Requires:] [T is a model of Copyable.]]
+
+[[Effects:] [Copy assigns an externally locked object by copying the cloaked reference and copying the mutex reference ]]
+
+[[Throws:] [Any exception thrown by the call to `T::operator=(T&)`.]]
+
+]
+
+[endsect]
+
+[///////////////////////////////]
+[section:get1 `get(strict_lock<mutex_type>&)`]
+
+ T& get(strict_lock<mutex_type>& lk);
+ const T& get(strict_lock<mutex_type>& lk) const;
+
+[variablelist
+
+[[Requires:] [The `lk` parameter must be locking the associated mutex.]]
+
+[[Returns:] [A reference to the cloaked object ]]
+
+[[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
+
+]
+
+[endsect]
+[///////////////////////////////]
+[section:get2 `get(strict_lock<nested_strict_lock<Lock>>&)`]
+
+ template <class Lock>
+ T& get(nested_strict_lock<Lock>& lk);
+ template <class Lock>
+ const T& get(nested_strict_lock<Lock>& lk) const;
+
+[variablelist
+
+[[Requires:] [`is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
+
+[[Returns:] [A reference to the cloaked object ]]
+
+[[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
+
+]
+
+[endsect]
+
+[///////////////////////////////]
+[section:get3 `get(strict_lock<nested_strict_lock<Lock>>&)`]
+
+ template <class Lock>
+ T& get(Lock& lk);
+ template <class Lock>
+ T const& get(Lock& lk) const;
+
+[variablelist
+
+[[Requires:] [`Lock` is a model of __StrictLock, `is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
+
+[[Returns:] [A reference to the cloaked object ]]
+
+[[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
+
+]
+
+[endsect]
+
+[endsect]
+
+
 [///////////////////////////////]
-[section:swap `swap(externally_locked, externally_locked&)`]
+[section:swap `swap(externally_locked&, externally_locked&)`]
 
   template <typename T, typename MutexType>
   void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs)

Modified: branches/release/libs/thread/doc/thread.qbk
==============================================================================
--- branches/release/libs/thread/doc/thread.qbk (original)
+++ branches/release/libs/thread/doc/thread.qbk 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -203,6 +203,7 @@
 [def __thread_resource_error__ `boost::thread_resource_error`]
 [def __thread_interrupted__ `boost::thread_interrupted`]
 [def __barrier__ [link thread.synchronization.barriers.barrier `boost::barrier`]]
+[def __latch__ [link thread.synchronization.latches.latch `latch`]]
 
 [template cond_wait_link[link_text] [link thread.synchronization.condvar_ref.condition_variable.wait [link_text]]]
 [def __cond_wait__ [cond_wait_link `wait()`]]
@@ -238,7 +239,9 @@
 [include condition_variables.qbk]
 [include once.qbk]
 [include barrier.qbk]
+[/include latch.qbk]
 [include futures.qbk]
+[/include async_executors.qbk]
 [endsect]
 
 

Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2 (original)
+++ branches/release/libs/thread/test/Jamfile.v2 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -220,9 +220,11 @@
           [ thread-test test_condition_notify_all.cpp ]
           [ thread-test test_condition.cpp ]
           [ thread-test test_once.cpp ]
- [ thread-test test_barrier.cpp ]
+ [ thread-run test_barrier.cpp ]
           [ thread-test test_lock_concept.cpp ]
           [ thread-test test_generic_locks.cpp ]
+ [ thread-run test_latch.cpp ]
+ [ thread-run test_completion_latch.cpp ]
     ;
 
     test-suite t_shared

Modified: branches/release/libs/thread/test/sync/futures/async/async_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/async/async_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/async/async_pass.cpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -147,7 +147,7 @@
     Clock::time_point t0 = Clock::now();
     BOOST_TEST(f.get() == 3);
     Clock::time_point t1 = Clock::now();
- BOOST_TEST(t1 - t0 < ms(200));
+ BOOST_TEST(t1 - t0 < ms(300));
     } catch (std::exception& ex) {
       std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
       BOOST_TEST(false && "exception thrown");

Modified: branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -190,8 +190,40 @@
   }
 };
 
+
+struct id_string
+{
+ static boost::once_flag flag;
+ static void do_init(id_string & )
+ {}
+ void operator()()
+ {
+ boost::call_once(flag, &id_string::do_init, boost::ref(*this));
+ }
+// void operator()(int,int)
+// {
+// // This should fail but works with gcc-4.6.3
+// //std::bind(&id_string::do_init, *this)();
+// std::bind(&id_string::do_init, std::ref(*this))();
+// }
+// void operator()(int) const
+// {
+// //std::bind(&id_string::do_init, *this)();
+// }
+};
+
+
+boost::once_flag id_string::flag BOOST_INIT_ONCE_INIT;
+
 int main()
 {
+
+ //
+ {
+ id_string id;
+ id();
+ //id(1,1);
+ }
     // check basic functionality
     {
         boost::thread t0(f0);

Modified: branches/release/libs/thread/test/test_barrier.cpp
==============================================================================
--- branches/release/libs/thread/test/test_barrier.cpp (original)
+++ branches/release/libs/thread/test/test_barrier.cpp 2013-05-01 12:40:32 EDT (Wed, 01 May 2013)
@@ -1,5 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
+// (C) Copyright 2013 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)
@@ -12,7 +13,6 @@
 #include <boost/thread/barrier.hpp>
 
 #include <boost/detail/lightweight_test.hpp>
-//#include <boost/test/unit_test.hpp>
 #include <vector>
 
 namespace {
@@ -55,21 +55,14 @@
         throw;
     }
 
- //BOOST_CHECK_EQUAL(global_parameter,5);
     BOOST_TEST(global_parameter==5);
 
 }
 
-//boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
 int main()
 {
-// boost::unit_test::test_suite* test =
-// BOOST_TEST_SUITE("Boost.Threads: barrier test suite");
-//
-// test->add(BOOST_TEST_CASE(&test_barrier));
 
     test_barrier();
     return boost::report_errors();
- //return test;
 }
 


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