$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r85603 - in branches/release: boost/thread boost/thread/pthread libs/thread libs/thread/build libs/thread/doc libs/thread/test libs/thread/test/sync/mutual_exclusion/synchronized_value
From: vicente.botet_at_[hidden]
Date: 2013-09-08 05:50:12
Author: viboes
Date: 2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)
New Revision: 85603
URL: http://svn.boost.org/trac/boost/changeset/85603
Log:
Thread: merge from trunk upgrade_to_unique_lock::mutex() + doc typos + BOOST_THREAD_USES_ATOMIC doc + synchronized _value call + rename wait_until params.
Added:
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp
      - copied unchanged from r85464, trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp
Properties modified: 
   branches/release/boost/thread/   (props changed)
   branches/release/libs/thread/   (props changed)
Text files modified: 
   branches/release/boost/thread/barrier.hpp                                                |    15 ++-                                     
   branches/release/boost/thread/lock_types.hpp                                             |     6 +                                       
   branches/release/boost/thread/pthread/condition_variable.hpp                             |    16 ++--                                    
   branches/release/boost/thread/pthread/condition_variable_fwd.hpp                         |    18 ++--                                    
   branches/release/boost/thread/synchronized_value.hpp                                     |    83 ++++++++++++++++++++--                  
   branches/release/libs/thread/build/Jamfile.v2                                            |    12 +-                                      
   branches/release/libs/thread/doc/configuration.qbk                                       |    12 ++                                      
   branches/release/libs/thread/doc/external_locking.qbk                                    |     4                                         
   branches/release/libs/thread/doc/mutex_concepts.qbk                                      |    10 +-                                      
   branches/release/libs/thread/test/Jamfile.v2                                             |     4                                         
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp |   144 ++++++++++++++++++++++++++++++++++++++++
   11 files changed, 276 insertions(+), 48 deletions(-)
Modified: branches/release/boost/thread/barrier.hpp
==============================================================================
--- branches/release/boost/thread/barrier.hpp	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/boost/thread/barrier.hpp	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -57,7 +57,8 @@
     struct void_functor_barrier_reseter
     {
       unsigned int size_;
-      void_completion_function fct_;template <typename F>
+      void_completion_function fct_;
+      template <typename F>
 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
       void_functor_barrier_reseter(unsigned int size, BOOST_THREAD_RV_REF(F) funct)
       : size_(size), fct_(boost::move(funct))
@@ -90,7 +91,7 @@
   }
   class barrier
   {
-    static inline unsigned int check(unsigned int count)
+    static inline unsigned int check_counter(unsigned int count)
     {
       if (count == 0) boost::throw_exception(
           thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero."));
@@ -104,7 +105,7 @@
     BOOST_THREAD_NO_COPYABLE( barrier)
 
     explicit barrier(unsigned int count) :
-      m_count(check(count)), m_generation(0), fct_(thread_detail::default_barrier_reseter(count))
+      m_count(check_counter(count)), m_generation(0), fct_(thread_detail::default_barrier_reseter(count))
     {
     }
 
@@ -120,7 +121,7 @@
         typename is_void<typename result_of<F>::type>::type, dummy*
         >::type=0
     )
-    : m_count(check(count)),
+    : m_count(check_counter(count)),
     m_generation(0),
     fct_(thread_detail::void_functor_barrier_reseter(count,
 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
@@ -145,7 +146,7 @@
         typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
         >::type=0
     )
-    : m_count(check(count)),
+    : m_count(check_counter(count)),
     m_generation(0),
     fct_(
 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
@@ -158,7 +159,7 @@
     }
 
     barrier(unsigned int count, void(*funct)()) :
-      m_count(check(count)), m_generation(0),
+      m_count(check_counter(count)), m_generation(0),
       fct_(funct
           ? thread_detail::size_completion_function(thread_detail::void_fct_ptr_barrier_reseter(count, funct))
           : thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count))
@@ -166,7 +167,7 @@
     {
     }
     barrier(unsigned int count, unsigned int(*funct)()) :
-      m_count(check(count)), m_generation(0),
+      m_count(check_counter(count)), m_generation(0),
       fct_(funct
           ? thread_detail::size_completion_function(funct)
           : thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count))
Modified: branches/release/boost/thread/lock_types.hpp
==============================================================================
--- branches/release/boost/thread/lock_types.hpp	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/boost/thread/lock_types.hpp	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -1112,6 +1112,10 @@
     {
       return exclusive.owns_lock();
     }
+    Mutex* mutex() const BOOST_NOEXCEPT
+    {
+      return exclusive.mutex();
+    }
   };
 
 BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
@@ -1187,7 +1191,7 @@
     {
       return base::owns_lock();
     }
-    Mutex* mutex() const
+    Mutex* mutex() const BOOST_NOEXCEPT
     {
       return base::mutex();
     }
Modified: branches/release/boost/thread/pthread/condition_variable.hpp
==============================================================================
--- branches/release/boost/thread/pthread/condition_variable.hpp	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/boost/thread/pthread/condition_variable.hpp	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -200,15 +200,15 @@
 
 #if defined BOOST_THREAD_USES_DATETIME
         template<typename lock_type>
-        bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+        bool timed_wait(lock_type& m,boost::system_time const& abs_time)
         {
-            struct timespec const timeout=detail::to_timespec(wait_until);
+            struct timespec const timeout=detail::to_timespec(abs_time);
             return do_wait_until(m, timeout);
         }
         template<typename lock_type>
-        bool timed_wait(lock_type& m,xtime const& wait_until)
+        bool timed_wait(lock_type& m,xtime const& abs_time)
         {
-            return timed_wait(m,system_time(wait_until));
+            return timed_wait(m,system_time(abs_time));
         }
 
         template<typename lock_type,typename duration_type>
@@ -218,20 +218,20 @@
         }
 
         template<typename lock_type,typename predicate_type>
-        bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+        bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
         {
             while (!pred())
             {
-                if(!timed_wait(m, wait_until))
+                if(!timed_wait(m, abs_time))
                     return pred();
             }
             return true;
         }
 
         template<typename lock_type,typename predicate_type>
-        bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred)
+        bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred)
         {
-            return timed_wait(m,system_time(wait_until),pred);
+            return timed_wait(m,system_time(abs_time),pred);
         }
 
         template<typename lock_type,typename duration_type,typename predicate_type>
Modified: branches/release/boost/thread/pthread/condition_variable_fwd.hpp
==============================================================================
--- branches/release/boost/thread/pthread/condition_variable_fwd.hpp	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/boost/thread/pthread/condition_variable_fwd.hpp	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -98,21 +98,21 @@
 #if defined BOOST_THREAD_USES_DATETIME
         inline bool timed_wait(
             unique_lock<mutex>& m,
-            boost::system_time const& wait_until)
+            boost::system_time const& abs_time)
         {
 #if defined BOOST_THREAD_WAIT_BUG
-            struct timespec const timeout=detail::to_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
+            struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG);
             return do_wait_until(m, timeout);
 #else
-            struct timespec const timeout=detail::to_timespec(wait_until);
+            struct timespec const timeout=detail::to_timespec(abs_time);
             return do_wait_until(m, timeout);
 #endif
         }
         bool timed_wait(
             unique_lock<mutex>& m,
-            xtime const& wait_until)
+            xtime const& abs_time)
         {
-            return timed_wait(m,system_time(wait_until));
+            return timed_wait(m,system_time(abs_time));
         }
 
         template<typename duration_type>
@@ -126,11 +126,11 @@
         template<typename predicate_type>
         bool timed_wait(
             unique_lock<mutex>& m,
-            boost::system_time const& wait_until,predicate_type pred)
+            boost::system_time const& abs_time,predicate_type pred)
         {
             while (!pred())
             {
-                if(!timed_wait(m, wait_until))
+                if(!timed_wait(m, abs_time))
                     return pred();
             }
             return true;
@@ -139,9 +139,9 @@
         template<typename predicate_type>
         bool timed_wait(
             unique_lock<mutex>& m,
-            xtime const& wait_until,predicate_type pred)
+            xtime const& abs_time,predicate_type pred)
         {
-            return timed_wait(m,system_time(wait_until),pred);
+            return timed_wait(m,system_time(abs_time),pred);
         }
 
         template<typename duration_type,typename predicate_type>
Modified: branches/release/boost/thread/synchronized_value.hpp
==============================================================================
--- branches/release/boost/thread/synchronized_value.hpp	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/boost/thread/synchronized_value.hpp	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -26,10 +26,12 @@
 //#endif
 
 #if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
-#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics.
+#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics on C++98 compilers.
 #include <functional>
 #endif
 
+#include <boost/utility/result_of.hpp>
+
 #include <boost/config/abi_prefix.hpp>
 
 namespace boost
@@ -593,8 +595,6 @@
       boost::swap(value_, rhs);
     }
 
-
-
     /**
      * Essentially calling a method obj->foo(x, y, z) calls the method foo(x, y, z) inside a critical section as
      * long-lived as the call itself.
@@ -614,13 +614,80 @@
     }
 
     /**
+     * Call function on a locked block.
+     *
+     * @requires fct(value_) is well formed.
+     *
+     * Example
+     *   void fun(synchronized_value<vector<int>> & v) {
+     *     v ( [](vector<int>> & vec)
+     *     {
+     *       vec.push_back(42);
+     *       assert(vec.back() == 42);
+     *     } );
+     *   }
+     */
+    template <typename F>
+    inline
+    typename boost::result_of<F(value_type&)>::type
+    operator()(BOOST_THREAD_RV_REF(F) fct)
+    {
+      strict_lock<mutex_type> lk(mtx_);
+      return fct(value_);
+    }
+    template <typename F>
+    inline
+    typename boost::result_of<F(value_type const&)>::type
+    operator()(BOOST_THREAD_RV_REF(F) fct) const
+    {
+      strict_lock<mutex_type> lk(mtx_);
+      return fct(value_);
+    }
+
+
+#if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
+    template <typename F>
+    inline
+    typename boost::result_of<F(value_type&)>::type
+    operator()(F const & fct)
+    {
+      strict_lock<mutex_type> lk(mtx_);
+      return fct(value_);
+    }
+    template <typename F>
+    inline
+    typename boost::result_of<F(value_type const&)>::type
+    operator()(F const & fct) const
+    {
+      strict_lock<mutex_type> lk(mtx_);
+      return fct(value_);
+    }
+
+    template <typename R>
+    inline
+    R operator()(R(*fct)(value_type&))
+    {
+      strict_lock<mutex_type> lk(mtx_);
+      return fct(value_);
+    }
+    template <typename R>
+    inline
+    R operator()(R(*fct)(value_type const&)) const
+    {
+      strict_lock<mutex_type> lk(mtx_);
+      return fct(value_);
+    }
+#endif
+
+
+    /**
      * The synchronize() factory make easier to lock on a scope.
      * As discussed, operator-> can only lock over the duration of a call, so it is insufficient for complex operations.
      * With synchronize() you get to lock the object in a scoped and to directly access the object inside that scope.
      *
      * Example
-     *   void fun(synchronized_value<vector<int>> & vec) {
-     *     auto&& vec=vec.synchronize();
+     *   void fun(synchronized_value<vector<int>> & v) {
+     *     auto&& vec=v.synchronize();
      *     vec.push_back(42);
      *     assert(vec.back() == 42);
      *   }
@@ -880,9 +947,9 @@
 
   //Hash support
 
-  template <class T> struct hash;
-  template <typename T, typename L>
-  struct hash<synchronized_value<T,L> >;
+//  template <class T> struct hash;
+//  template <typename T, typename L>
+//  struct hash<synchronized_value<T,L> >;
 
   // Comparison with T
   template <typename T, typename L>
Modified: branches/release/libs/thread/build/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/build/Jamfile.v2	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/libs/thread/build/Jamfile.v2	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -236,10 +236,10 @@
         }
     }
 
-    if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties)  || <toolset-vacpp:version>12.1 in $(properties)
-    {
+    #if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties)  || <toolset-vacpp:version>12.1 in $(properties)
+    #{
       result += <library>/boost/chrono//boost_chrono ;
-    }
+    #}
 
     return $(result) ;
 }
@@ -269,10 +269,10 @@
         result += <library>/boost/chrono//boost_chrono ;
     }
 
-    if <toolset>pgi in $(properties)  || <toolset>vacpp in $(properties)
-    {
+    #if <toolset>pgi in $(properties)  || <toolset>vacpp in $(properties)
+    #{
       result += <library>/boost/atomic//boost_atomic ;
-    }
+    #}
 
     return $(result) ;
 }
Modified: branches/release/libs/thread/doc/configuration.qbk
==============================================================================
--- branches/release/libs/thread/doc/configuration.qbk	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/libs/thread/doc/configuration.qbk	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -78,10 +78,18 @@
 
 [endsect]
 
+[section:move  Boost.Atomic]
 
-[section:thread_eq `boost::thread::oprator==` deprecated]
+Boost.Thread uses by default an Boost.Atomic in POSIX platforms to implement call_once..
 
-The following nested typedefs are deprecated: 
+Define `BOOST_THREAD_USES_ATOMIC ` if you want to use Boost.Atomic.
+Define `BOOST_THREAD_DONT_USE_ATOMIC ` if you don't want to use Boost.Atomic or if it is not supported in your platform.
+
+[endsect]
+ 
+[section:thread_eq `boost::thread::operator==` deprecated]
+
+The following operators are deprecated: 
 
 * `boost::thread::oprator==`
 * `boost::thread::oprator!=`
Modified: branches/release/libs/thread/doc/external_locking.qbk
==============================================================================
--- branches/release/libs/thread/doc/external_locking.qbk	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/libs/thread/doc/external_locking.qbk	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -217,7 +217,7 @@
 * You can create a `strict_lock<T>` only starting from a valid T object. Notice that there is no other way you can create a `strict_lock<T>`.
 
     BankAccount myAccount("John Doe", "123-45-6789");
-    strict_locerk<BankAccount> myLock(myAccount); // ok
+    strict_lock<BankAccount> myLock(myAccount); // ok
 
 * You cannot copy `strict_lock`s to one another. In particular, you cannot pass `strict_lock`s by value to functions or have them returned by functions:
 
@@ -468,7 +468,7 @@
 We need a way to transfer the ownership from the `unique_lock` to a `strict_lock` the time we are working with `savingsAcct_` and then restore the ownership on `unique_lock`.
 
   void AccountManager::AMoreComplicatedChecking2Savings(int amount) {
-      unique_lock<AccountManager> guard(*this, defer_lock);
+      unique_lock<AccountManager> guard1(*this, defer_lock);
       if (some_condition()) {
           guard1.lock();
       }
Modified: branches/release/libs/thread/doc/mutex_concepts.qbk
==============================================================================
--- branches/release/libs/thread/doc/mutex_concepts.qbk	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/libs/thread/doc/mutex_concepts.qbk	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -1273,7 +1273,7 @@
         explicit operator bool() const noexcept;
         bool owns_lock() const noexcept;
 
-        Lockable* mutex() const noexcept;
+        mutex_type* mutex() const noexcept;
 
     #if defined BOOST_THREAD_USE_DATE_TIME || defined BOOST_THREAD_DONT_USE_CHRONO
         unique_lock(Lockable& m_,system_time const& target_time);
@@ -1535,7 +1535,7 @@
 
 [endsect]
 
-[section:mutex `Lockable* mutex() const`]
+[section:mutex `Lockable* mutex() const noexcept`]
 
 [variablelist
 
@@ -1907,7 +1907,7 @@
 
 [endsect]
 
-[section:upgrade_to_unique_lock Class template `upgrade_to_unique_lock`]
+[section:upgrade_to_unique_lock Class template `upgrade_to_unique_lock` -- EXTENSION]
 
     // #include <boost/thread/locks.hpp>
     // #include <boost/thread/lock_types.hpp> 
@@ -1930,6 +1930,8 @@
 
         explicit operator bool() const;
         bool owns_lock() const;
+        mutex_type* mutex() const;
+
     };
 
 __upgrade_to_unique_lock__ allows for a temporary upgrade of an __upgrade_lock__ to exclusive ownership. When constructed with a
@@ -1939,7 +1941,7 @@
 
 [endsect]
 
-[section:scoped_try_lock Mutex-specific class `scoped_try_lock`]
+[section:scoped_try_lock Mutex-specific class `scoped_try_lock` -- DEPRECATED]
 
     class MutexType::scoped_try_lock
     {
Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2	Sun Sep  8 04:53:01 2013	(r85602)
+++ branches/release/libs/thread/test/Jamfile.v2	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603)
@@ -768,6 +768,7 @@
           [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/swap_pass.cpp : synchronized_value__swap_p ]
           [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp : synchronized_value__swap_T_p ]
           [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp : synchronized_value__synchronize_p ]
+          [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/call_pass.cpp : synchronized_value__call_p ]
 
     ;
 
@@ -789,7 +790,8 @@
           #[ thread-run test_8586.cpp ]
           #[ thread-run test_8596.cpp ]
           #[ thread-run test_8600.cpp ]
-          #[ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp : sync_bounded_queue__multi_thread_p ]
+          #[ thread-run test_8943.cpp ]
+          #[ thread-run test_8960.cpp ]
           
     ;
 
Copied: branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp (from r85464, trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp	2013-09-08 05:50:12 EDT (Sun, 08 Sep 2013)	(r85603, copy of r85464, trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp)
@@ -0,0 +1,144 @@
+// Copyright (C) 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)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+//    template <typename F>
+//    inline typename boost::result_of<F(value_type&)>::type
+//    operator()(BOOST_THREAD_RV_REF(F) fct);
+//    template <typename F>
+//    inline typename boost::result_of<F(value_type const&)>::type
+//    operator()(BOOST_THREAD_RV_REF(F) fct) const;
+
+#include <boost/config.hpp>
+#if ! defined  BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+struct S {
+  int f() const {return 1;}
+  int g() {return 1;}
+};
+
+void c(S const& s)
+{
+  BOOST_TEST(s.f()==1);
+}
+
+void nc(S & s)
+{
+  BOOST_TEST(s.f()==1);
+  BOOST_TEST(s.g()==1);
+}
+
+struct cfctr {
+  typedef void result_type;
+  void operator()(S const& s) const {
+    BOOST_TEST(s.f()==1);
+  }
+};
+struct ncfctr {
+  typedef void result_type;
+  void operator()(S& s) const {
+    BOOST_TEST(s.f()==1);
+    BOOST_TEST(s.g()==1);
+  }
+};
+
+struct cfctr3 {
+  typedef void result_type;
+  BOOST_THREAD_MOVABLE_ONLY(cfctr3)
+  cfctr3()
+  {}
+  cfctr3(BOOST_THREAD_RV_REF(cfctr3))
+  {}
+  void operator()(S const& s) const {
+    BOOST_TEST(s.f()==1);
+  }
+};
+struct ncfctr3 {
+  typedef void result_type;
+  BOOST_THREAD_MOVABLE_ONLY(ncfctr3)
+  ncfctr3()
+  {}
+  ncfctr3(BOOST_THREAD_RV_REF(ncfctr3))
+  {}
+  void operator()(S& s) const {
+    BOOST_TEST(s.f()==1);
+    BOOST_TEST(s.g()==1);
+  }
+};
+
+cfctr3 make_cfctr3() {
+  return BOOST_THREAD_MAKE_RV_REF(cfctr3());
+}
+
+ncfctr3 make_ncfctr3() {
+  return BOOST_THREAD_MAKE_RV_REF(ncfctr3());
+}
+
+int main()
+{
+  {
+      boost::synchronized_value<S> v;
+      v(&nc);
+      //v(&c);
+  }
+  {
+      const boost::synchronized_value<S> v;
+      v(&c);
+  }
+  {
+      boost::synchronized_value<S> v;
+      v(ncfctr());
+  }
+  {
+      const boost::synchronized_value<S> v;
+      v(cfctr());
+  }
+  {
+      boost::synchronized_value<S> v;
+      ncfctr fct;
+      v(fct);
+  }
+  {
+      const boost::synchronized_value<S> v;
+      cfctr fct;
+      v(fct);
+  }
+  {
+      boost::synchronized_value<S> v;
+      v(make_ncfctr3());
+  }
+  {
+      const boost::synchronized_value<S> v;
+      v(make_cfctr3());
+  }
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+  {
+      boost::synchronized_value<S> v;
+      v([](S& s) {
+        BOOST_TEST(s.f()==1);
+        BOOST_TEST(s.g()==1);
+      });
+  }
+  {
+      const boost::synchronized_value<S> v;
+      v([](S const& s) {
+        BOOST_TEST(s.f()==1);
+      });
+  }
+#endif
+  return boost::report_errors();
+}
+