$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;
         }