|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r83950 - in trunk/boost/thread: detail pthread
From: vicente.botet_at_[hidden]
Date: 2013-04-18 02:44:10
Author: viboes
Date: 2013-04-18 02:44:09 EDT (Thu, 18 Apr 2013)
New Revision: 83950
URL: http://svn.boost.org/trac/boost/changeset/83950
Log:
Thread: make invoke/async_tuple/tuple_indices more portable.
Added:
trunk/boost/thread/pthread/shared_mutex_assert.hpp
- copied, changed from r83403, /trunk/boost/thread/pthread/shared_mutex.hpp
Text files modified:
trunk/boost/thread/detail/async_func.hpp | 501 ++++++++++++++++
trunk/boost/thread/detail/invoke.hpp | 1202 ++++++++++++++++++++++++++++++++++++++-
trunk/boost/thread/detail/make_tuple_indices.hpp | 174 +++++
trunk/boost/thread/pthread/shared_mutex_assert.hpp | 353 ++++++++---
4 files changed, 2058 insertions(+), 172 deletions(-)
Modified: trunk/boost/thread/detail/async_func.hpp
==============================================================================
--- trunk/boost/thread/detail/async_func.hpp (original)
+++ trunk/boost/thread/detail/async_func.hpp 2013-04-18 02:44:09 EDT (Thu, 18 Apr 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: trunk/boost/thread/detail/invoke.hpp
==============================================================================
--- trunk/boost/thread/detail/invoke.hpp (original)
+++ trunk/boost/thread/detail/invoke.hpp 2013-04-18 02:44:09 EDT (Thu, 18 Apr 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 //! 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
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
- // // bullets 1 and 2
+ // bullets 1 and 2
template <class Fp, class A0>
inline
@@ -211,41 +197,1153 @@
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
+//
+// template <class Ret, class Fp>
+// inline
+// Ret invoke(BOOST_THREAD_RV_REF(Fp) f)
+// {
+// return f();
+// }
+// template <class Ret, class Fp, class A1>
+// inline
+// Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+// {
+// return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1))();
+// }
+// template <class Ret, class Fp, class A1, class A2>
+// inline
+// Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+// {
+// return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2))();
+// }
+// template <class Ret, class Fp, class A1, class A2, class A3>
+// inline
+// Ret 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 std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3))();
+// }
+//
+//#define BOOST_THREAD_PROVIDES_INVOKE_RET
+
+#else // all
+//!!!!! 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;
+// }
-#elif ! defined(BOOST_NO_SFINAE_EXPR) && \
- ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL
+ // bullet 5
+ // f(t1, t2, ..., tN) in all other cases.
template <class Ret, class Fp>
inline
- Ret invoke(BOOST_THREAD_RV_REF(Fp) f)
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f)
{
- return 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
- Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ typename enable_if_c
+ <
+ ! is_member_function_pointer<Fp>::value,
+ Ret
+ >::type
+ invoke(BOOST_THREAD_RV_REF(Fp) f, A1 a1)
{
- return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1))();
+ return boost::forward<Fp>(f)(a1);
}
template <class Ret, class Fp, class A1, class A2>
inline
- Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ 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 std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<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
- Ret 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)
+ 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 std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<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);
}
-#define BOOST_THREAD_PROVIDES_INVOKE_RET
-
-#endif
-
+ ///
+ 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: trunk/boost/thread/detail/make_tuple_indices.hpp
==============================================================================
--- trunk/boost/thread/detail/make_tuple_indices.hpp (original)
+++ trunk/boost/thread/detail/make_tuple_indices.hpp 2013-04-18 02:44:09 EDT (Thu, 18 Apr 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
}
}
Copied: trunk/boost/thread/pthread/shared_mutex_assert.hpp (from r83403, /trunk/boost/thread/pthread/shared_mutex.hpp)
==============================================================================
--- /trunk/boost/thread/pthread/shared_mutex.hpp (original)
+++ trunk/boost/thread/pthread/shared_mutex_assert.hpp 2013-04-18 02:44:09 EDT (Thu, 18 Apr 2013)
@@ -20,6 +20,7 @@
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
+#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -28,8 +29,125 @@
class shared_mutex
{
private:
- struct state_data
+ class state_data
{
+ public:
+ state_data () :
+ shared_count(0),
+ exclusive(false),
+ upgrade(false),
+ exclusive_waiting_blocked(false)
+ {}
+
+ void assert_free() const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( ! upgrade );
+ BOOST_ASSERT( shared_count==0 );
+ }
+
+ void assert_locked() const
+ {
+ BOOST_ASSERT( exclusive );
+ BOOST_ASSERT( shared_count==0 );
+ BOOST_ASSERT( ! upgrade );
+ }
+
+ void assert_lock_shared () const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( shared_count>0 );
+ //BOOST_ASSERT( (! upgrade) || (shared_count>1));
+ // if upgraded there are at least 2 threads sharing the mutex,
+ // except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
+ }
+
+ void assert_lock_upgraded () const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( upgrade );
+ BOOST_ASSERT( shared_count>0 );
+ }
+
+ void assert_lock_not_upgraded () const
+ {
+ BOOST_ASSERT( ! upgrade );
+ }
+
+ bool can_lock () const
+ {
+ return ! (shared_count || exclusive);
+ }
+
+ void exclusive_blocked (bool blocked)
+ {
+ exclusive_waiting_blocked = blocked;
+ }
+
+ void lock ()
+ {
+ exclusive = true;
+ }
+
+ void unlock ()
+ {
+ exclusive = false;
+ exclusive_waiting_blocked = false;
+ }
+
+ bool can_lock_shared () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked);
+ }
+
+ bool is_last_shared () const
+ {
+ return !shared_count ;
+ }
+ unsigned get_shared_count () const
+ {
+ return shared_count ;
+ }
+ unsigned lock_shared ()
+ {
+ return ++shared_count;
+ }
+
+
+ void unlock_shared ()
+ {
+ --shared_count;
+ }
+
+ bool unlock_shared_downgrades()
+ {
+ if (upgrade) {
+ upgrade=false;
+ exclusive=true;
+ return true;
+ } else {
+ exclusive_waiting_blocked=false;
+ return false;
+ }
+ }
+
+ void lock_upgrade ()
+ {
+ lock_shared ();
+ upgrade=true;
+ }
+ bool can_lock_upgrade () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked || upgrade);
+ }
+
+ void unlock_upgrade ()
+ {
+ upgrade=false;
+ unlock_shared();
+ }
+
+ //private:
unsigned shared_count;
bool exclusive;
bool upgrade;
@@ -55,8 +173,6 @@
shared_mutex()
{
- state_data state_={0,0,0,0};
- state=state_;
}
~shared_mutex()
@@ -70,24 +186,23 @@
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked)
+ while(!state.can_lock_shared())
{
shared_cond.wait(lk);
}
- ++state.shared_count;
+ state.lock_shared();
}
bool try_lock_shared()
{
boost::unique_lock<boost::mutex> lk(state_change);
-
- if(state.exclusive || state.exclusive_waiting_blocked)
+ if(!state.can_lock_shared())
{
return false;
}
else
{
- ++state.shared_count;
+ state.lock_shared();
return true;
}
}
@@ -100,14 +215,14 @@
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked)
+ while(!state.can_lock_shared())
{
if(!shared_cond.timed_wait(lk,timeout))
{
return false;
}
}
- ++state.shared_count;
+ state.lock_shared();
return true;
}
@@ -131,35 +246,32 @@
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked)
+ while(!state.can_lock_shared())
{
if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
{
return false;
}
}
- ++state.shared_count;
+ state.lock_shared();
return true;
}
#endif
void unlock_shared()
{
boost::unique_lock<boost::mutex> lk(state_change);
- bool const last_reader=!--state.shared_count;
-
- if(last_reader)
+ state.assert_lock_shared();
+ state.unlock_shared();
+ if (state.get_shared_count () == 0)
{
- if(state.upgrade)
- {
- state.upgrade=false;
- state.exclusive=true;
- upgrade_cond.notify_one();
- }
- else
- {
- state.exclusive_waiting_blocked=false;
- }
- release_waiters();
+ if (state.unlock_shared_downgrades())
+ {
+ lk.unlock();
+ upgrade_cond.notify_one();
+ } else {
+ lk.unlock();
+ }
+ release_waiters();
}
}
@@ -170,12 +282,12 @@
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.shared_count || state.exclusive)
+ while(!state.can_lock())
{
- state.exclusive_waiting_blocked=true;
+ state.exclusive_blocked(true);
exclusive_cond.wait(lk);
}
- state.exclusive=true;
+ state.lock();
}
#if defined BOOST_THREAD_USES_DATETIME
@@ -186,14 +298,14 @@
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.shared_count || state.exclusive)
+ while(!state.can_lock())
{
- state.exclusive_waiting_blocked=true;
+ state.exclusive_blocked(true);
if(!exclusive_cond.timed_wait(lk,timeout))
{
- if(state.shared_count || state.exclusive)
+ if(!state.can_lock())
{
- state.exclusive_waiting_blocked=false;
+ state.exclusive_blocked(false);
release_waiters();
return false;
}
@@ -201,6 +313,7 @@
}
}
state.exclusive=true;
+ //state.lock();
return true;
}
@@ -224,14 +337,14 @@
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.shared_count || state.exclusive)
+ while(!state.can_lock())
{
- state.exclusive_waiting_blocked=true;
+ state.exclusive_blocked(true);
if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
{
- if(state.shared_count || state.exclusive)
+ if(!state.can_lock())
{
- state.exclusive_waiting_blocked=false;
+ state.exclusive_blocked(false);
release_waiters();
return false;
}
@@ -239,6 +352,7 @@
}
}
state.exclusive=true;
+ //state.lock();
return true;
}
#endif
@@ -247,13 +361,13 @@
{
boost::unique_lock<boost::mutex> lk(state_change);
- if(state.shared_count || state.exclusive)
+ if(!state.can_lock())
{
return false;
}
else
{
- state.exclusive=true;
+ state.lock();
return true;
}
@@ -262,8 +376,9 @@
void unlock()
{
boost::unique_lock<boost::mutex> lk(state_change);
- state.exclusive=false;
- state.exclusive_waiting_blocked=false;
+ state.assert_locked();
+ state.unlock();
+ state.assert_free();
release_waiters();
}
@@ -273,12 +388,11 @@
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ while(!state.can_lock_upgrade())
{
shared_cond.wait(lk);
}
- ++state.shared_count;
- state.upgrade=true;
+ state.lock_upgrade();
}
#if defined BOOST_THREAD_USES_DATETIME
@@ -288,19 +402,18 @@
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ while(!state.can_lock_upgrade())
{
if(!shared_cond.timed_wait(lk,timeout))
{
- if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ if(!state.can_lock_upgrade())
{
return false;
}
break;
}
}
- ++state.shared_count;
- state.upgrade=true;
+ state.lock_upgrade();
return true;
}
@@ -323,33 +436,32 @@
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ while(!state.can_lock_upgrade())
{
if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
{
- if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ if(!state.can_lock_upgrade())
{
return false;
}
break;
}
}
- ++state.shared_count;
- state.upgrade=true;
+ state.lock_upgrade();
return true;
}
#endif
bool try_lock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
- if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ if(!state.can_lock_upgrade())
{
return false;
}
else
{
- ++state.shared_count;
- state.upgrade=true;
+ state.lock_upgrade();
+ state.assert_lock_upgraded();
return true;
}
}
@@ -357,15 +469,17 @@
void unlock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
- state.upgrade=false;
- bool const last_reader=!--state.shared_count;
-
- if(last_reader)
+ state.assert_lock_upgraded();
+ state.unlock_upgrade();
+ state.assert_lock_not_upgraded ();
+ if(state.get_shared_count () == 0)
{
- state.exclusive_waiting_blocked=false;
+ state.exclusive_blocked(false);
+ lk.unlock();
release_waiters();
} else {
- shared_cond.notify_all();
+ lk.unlock();
+ shared_cond.notify_all();
}
}
@@ -376,36 +490,42 @@
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- --state.shared_count;
- while(state.shared_count)
+ state.assert_lock_upgraded();
+ // assert state.get_shared_count() >=1
+ while(
+ //! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&&
+ state.get_shared_count()!=1)
{
upgrade_cond.wait(lk);
}
- state.upgrade=false;
- state.exclusive=true;
+ state.unlock_upgrade();
+ state.lock();
+ state.assert_locked();
}
void unlock_and_lock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
- state.exclusive=false;
- state.upgrade=true;
- ++state.shared_count;
- state.exclusive_waiting_blocked=false;
+ state.assert_locked();
+ state.unlock();
+ state.lock_upgrade();
+ state.assert_lock_upgraded();
release_waiters();
}
bool try_unlock_upgrade_and_lock()
{
boost::unique_lock<boost::mutex> lk(state_change);
- if( !state.exclusive
- && !state.exclusive_waiting_blocked
- && state.upgrade
- && state.shared_count==1)
+ state.assert_lock_upgraded();
+ if( //!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: why this is needed?
+ //&& state.upgrade // this should be removed once the assertion work
+ && state.get_shared_count()==1)
{
- state.shared_count=0;
- state.exclusive=true;
- state.upgrade=false;
+ state.unlock_upgrade();
+ state.lock();
+ state.assert_locked();
return true;
}
return false;
@@ -428,21 +548,27 @@
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- if (state.shared_count != 1)
+ state.assert_lock_upgraded();
+ if (//state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
+ //|| ! state.upgrade // this should be removed once the assertion work
+ || state.get_shared_count() != 1)
{
for (;;)
{
- cv_status status = shared_cond.wait_until(lk,abs_time);
- if (state.shared_count == 1)
+ //cv_status status = shared_cond.wait_until(lk,abs_time);
+ cv_status status = upgrade_cond.wait_until(lk,abs_time);
+ if (//!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&& ! state.upgrade // this should be removed once the assertion work
+ && state.get_shared_count() == 1)
break;
if(status == cv_status::timeout)
return false;
}
}
- state.upgrade=false;
- state.exclusive=true;
- state.exclusive_waiting_blocked=false;
- state.shared_count=0;
+ state.unlock_upgrade();
+ state.lock();
return true;
}
#endif
@@ -451,9 +577,9 @@
void unlock_and_lock_shared()
{
boost::unique_lock<boost::mutex> lk(state_change);
- state.exclusive=false;
- ++state.shared_count;
- state.exclusive_waiting_blocked=false;
+ state.assert_locked();
+ state.unlock();
+ state.lock_shared();
release_waiters();
}
@@ -461,13 +587,14 @@
bool try_unlock_shared_and_lock()
{
boost::unique_lock<boost::mutex> lk(state_change);
- if( !state.exclusive
- && !state.exclusive_waiting_blocked
- && !state.upgrade
- && state.shared_count==1)
+ state.assert_lock_shared();
+ if( //!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: why this is needed?
+ //&& ! state.upgrade // Fixme: why this is needed if state.get_shared_count()==1?
+ && state.get_shared_count()==1)
{
- state.shared_count=0;
- state.exclusive=true;
+ state.unlock_shared();
+ state.lock();
return true;
}
return false;
@@ -490,21 +617,28 @@
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- if (state.shared_count != 1)
+ state.assert_lock_shared();
+ if ( // !state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
+ //|| state.upgrade // Fixme: why this is needed if state.get_shared_count()==1?
+ || state.get_shared_count() != 1)
{
for (;;)
{
cv_status status = shared_cond.wait_until(lk,abs_time);
- if (state.shared_count == 1)
+ if ( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&& ! state.upgrade
+ && state.get_shared_count() == 1)
break;
if(status == cv_status::timeout)
return false;
}
}
- state.upgrade=false;
- state.exclusive=true;
- state.exclusive_waiting_blocked=false;
- state.shared_count=0;
+ state.unlock_shared();
+ state.lock();
+ state.upgrade=false; // Is this absolutely needed?
+ state.exclusive_waiting_blocked=false; // Is this absolutely needed?
return true;
}
#endif
@@ -514,8 +648,11 @@
void unlock_upgrade_and_lock_shared()
{
boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ //state.unlock_upgrade();
+ //state.lock_shared(); // less efficient
state.upgrade=false;
- state.exclusive_waiting_blocked=false;
+ state.exclusive_waiting_blocked=false; // Is this absolutely needed?
release_waiters();
}
@@ -523,9 +660,10 @@
bool try_unlock_shared_and_lock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
- if( !state.exclusive
- && !state.exclusive_waiting_blocked
- && !state.upgrade
+ state.assert_lock_shared();
+ if( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ && ! state.upgrade
)
{
state.upgrade=true;
@@ -551,16 +689,17 @@
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- if( state.exclusive
- || state.exclusive_waiting_blocked
+ state.assert_lock_shared();
+ if( //state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
|| state.upgrade
)
{
for (;;)
{
cv_status status = exclusive_cond.wait_until(lk,abs_time);
- if( ! state.exclusive
- && ! state.exclusive_waiting_blocked
+ if( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
&& ! state.upgrade
)
break;
@@ -568,6 +707,8 @@
return false;
}
}
+ //state.unlock_shared();
+ //state.lock_upgrade(); // less efficient
state.upgrade=true;
return true;
}
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