$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r65002 - in branches/release: boost boost/signals2 boost/signals2/detail libs/signals2 libs/signals2/doc libs/signals2/doc/reference libs/signals2/test
From: fmhess_at_[hidden]
Date: 2010-08-25 15:01:07
Author: fmhess
Date: 2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
New Revision: 65002
URL: http://svn.boost.org/trac/boost/changeset/65002
Log:
Merged signals2 from trunk to release.
Added:
   branches/release/boost/signals2/detail/foreign_ptr.hpp
      - copied unchanged from r56650, /trunk/boost/signals2/detail/foreign_ptr.hpp
Properties modified: 
   branches/release/boost/signals2/   (props changed)
   branches/release/boost/signals2.hpp   (contents, props changed)
   branches/release/libs/signals2/   (props changed)
Text files modified: 
   branches/release/boost/signals2.hpp                              |     5 +++++                                   
   branches/release/boost/signals2/connection.hpp                   |    30 ++++++++++++++++++------------          
   branches/release/boost/signals2/deconstruct.hpp                  |     4 ++--                                    
   branches/release/boost/signals2/detail/auto_buffer.hpp           |     2 --                                      
   branches/release/boost/signals2/detail/replace_slot_function.hpp |     7 +------                                 
   branches/release/boost/signals2/detail/slot_call_iterator.hpp    |     2 +-                                      
   branches/release/boost/signals2/detail/slot_template.hpp         |    25 ++++++++++++++++++++++---               
   branches/release/boost/signals2/slot_base.hpp                    |    40 ++++++++++++++++++++++++++++++++--------
   branches/release/libs/signals2/doc/reference/signal_type.xml     |     6 +++---                                  
   branches/release/libs/signals2/doc/snippet_extractor.cpp         |     1 +                                       
   branches/release/libs/signals2/test/track_test.cpp               |    32 ++++++++++++++++++++++++++++++++        
   11 files changed, 117 insertions(+), 37 deletions(-)
Modified: branches/release/boost/signals2.hpp
==============================================================================
--- branches/release/boost/signals2.hpp	(original)
+++ branches/release/boost/signals2.hpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -7,6 +7,9 @@
 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
+#ifndef BOOST_SIGNALS2_HPP
+#define BOOST_SIGNALS2_HPP
+
 // For documentation, see http://www.boost.org/libs/signals2/
 
 #include <boost/signals2/deconstruct.hpp>
@@ -16,3 +19,5 @@
 #include <boost/signals2/signal.hpp>
 #include <boost/signals2/signal_type.hpp>
 #include <boost/signals2/shared_connection_block.hpp>
+
+#endif
Modified: branches/release/boost/signals2/connection.hpp
==============================================================================
--- branches/release/boost/signals2/connection.hpp	(original)
+++ branches/release/boost/signals2/connection.hpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -108,19 +108,25 @@
         template<typename OutputIterator>
           void nolock_grab_tracked_objects(OutputIterator inserter) const
         {
-            slot_base::tracked_container_type::const_iterator it;
-            for(it = slot.tracked_objects().begin();
-              it != slot.tracked_objects().end();
-              ++it)
+          slot_base::tracked_container_type::const_iterator it;
+          for(it = slot.tracked_objects().begin();
+            it != slot.tracked_objects().end();
+            ++it)
+          {
+            void_shared_ptr_variant locked_object
+            (
+              apply_visitor
+              (
+                detail::lock_weak_ptr_visitor(),
+                *it
+              )
+            );
+            if(apply_visitor(detail::expired_weak_ptr_visitor(), *it))
             {
-              boost::shared_ptr<void> locked_object = it->lock();
-              boost::shared_ptr<void> empty;
-              if(!(empty < locked_object) && !(locked_object < empty))
-              {
-                _connected = false;
-                return;
-              }
-              *inserter++ = locked_object;
+              _connected = false;
+              return;
+            }
+            *inserter++ = locked_object;
           }
         }
         // expose Lockable concept of mutex
Modified: branches/release/boost/signals2/deconstruct.hpp
==============================================================================
--- branches/release/boost/signals2/deconstruct.hpp	(original)
+++ branches/release/boost/signals2/deconstruct.hpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -45,9 +45,9 @@
 {
 
 #if !defined(BOOST_NO_RVALUE_REFERENCES)
-  template< class T > T&& forward( T &&t )
+  template< class T > T&& forward( T & t )
   {
-      return t;
+    return static_cast< T&& >( t );
   }
 #endif
 
Modified: branches/release/boost/signals2/detail/auto_buffer.hpp
==============================================================================
--- branches/release/boost/signals2/detail/auto_buffer.hpp	(original)
+++ branches/release/boost/signals2/detail/auto_buffer.hpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -993,8 +993,6 @@
                 uninitialized_grow( n - size() );
             else if( n < size() )
                 uninitialized_shrink( size() - n );
-            else
-                ;
 
            BOOST_ASSERT( size() == n );
         }
Modified: branches/release/boost/signals2/detail/replace_slot_function.hpp
==============================================================================
--- branches/release/boost/signals2/detail/replace_slot_function.hpp	(original)
+++ branches/release/boost/signals2/detail/replace_slot_function.hpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -22,12 +22,7 @@
         ResultSlot replace_slot_function(const SlotIn &slot_in, const SlotFunction &fun)
       {
         ResultSlot slot(fun);
-        slot_base::tracked_container_type tracked_objects = slot_in.tracked_objects();
-        slot_base::tracked_container_type::const_iterator it;
-        for(it = tracked_objects.begin(); it != tracked_objects.end(); ++it)
-        {
-          slot.track(*it);
-        }
+        slot.track(slot_in);
         return slot;
       }
     } // namespace detail
Modified: branches/release/boost/signals2/detail/slot_call_iterator.hpp
==============================================================================
--- branches/release/boost/signals2/detail/slot_call_iterator.hpp	(original)
+++ branches/release/boost/signals2/detail/slot_call_iterator.hpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -36,7 +36,7 @@
           disconnected_slot_count(0)
         {}
         optional<ResultType> result;
-        typedef auto_buffer<boost::shared_ptr<void>, store_n_objects<10> > tracked_ptrs_type;
+        typedef auto_buffer<void_shared_ptr_variant, store_n_objects<10> > tracked_ptrs_type;
         tracked_ptrs_type tracked_ptrs;
         Function f;
         unsigned connected_slot_count;
Modified: branches/release/boost/signals2/detail/slot_template.hpp
==============================================================================
--- branches/release/boost/signals2/detail/slot_template.hpp	(original)
+++ branches/release/boost/signals2/detail/slot_template.hpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -108,8 +108,7 @@
         return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
       }
       // tracking
-      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const weak_ptr<void> &tracked)
-      {
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const weak_ptr<void> &tracked)      {
         _tracked_objects.push_back(tracked);
         return *this;
       }
@@ -123,10 +122,30 @@
         tracked_container_type::const_iterator it;
         for(it = slot.tracked_objects().begin(); it != slot.tracked_objects().end(); ++it)
         {
-          track(*it);
+          _tracked_objects.push_back(*it);
         }
         return *this;
       }
+      template<typename ForeignWeakPtr>
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignWeakPtr &tracked,
+        typename weak_ptr_traits<ForeignWeakPtr>::shared_type * /*SFINAE*/ = 0)
+      {
+        _tracked_objects.push_back(detail::foreign_void_weak_ptr(tracked));
+        return *this;
+      }
+      template<typename ForeignSharedPtr>
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignSharedPtr &tracked,
+        typename shared_ptr_traits<ForeignSharedPtr>::weak_type * /*SFINAE*/ = 0)
+      {
+        _tracked_objects.push_back
+        (
+          detail::foreign_void_weak_ptr
+          (
+            typename shared_ptr_traits<ForeignSharedPtr>::weak_type(tracked)
+          )
+        );
+        return *this;
+      }
 
       const slot_function_type& slot_function() const {return _slot_function;}
       slot_function_type& slot_function() {return _slot_function;}
Modified: branches/release/boost/signals2/slot_base.hpp
==============================================================================
--- branches/release/boost/signals2/slot_base.hpp	(original)
+++ branches/release/boost/signals2/slot_base.hpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -12,11 +12,15 @@
 #ifndef BOOST_SIGNALS2_SLOT_BASE_HPP
 #define BOOST_SIGNALS2_SLOT_BASE_HPP
 
+#include <boost/any.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
+#include <boost/signals2/detail/foreign_ptr.hpp>
 #include <boost/signals2/expired_slot.hpp>
 #include <boost/signals2/signal_base.hpp>
 #include <boost/throw_exception.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/variant.hpp>
 #include <vector>
 
 namespace boost
@@ -26,13 +30,36 @@
     namespace detail
     {
       class tracked_objects_visitor;
+
+      typedef boost::variant<boost::weak_ptr<void>, detail::foreign_void_weak_ptr > void_weak_ptr_variant;
+      typedef boost::variant<boost::shared_ptr<void>, detail::foreign_void_shared_ptr > void_shared_ptr_variant;
+      class lock_weak_ptr_visitor
+      {
+      public:
+        typedef void_shared_ptr_variant result_type;
+        template<typename WeakPtr>
+        result_type operator()(const WeakPtr &wp) const
+        {
+          return wp.lock();
+        }
+      };
+      class expired_weak_ptr_visitor
+      {
+      public:
+        typedef bool result_type;
+        template<typename WeakPtr>
+        bool operator()(const WeakPtr &wp) const
+        {
+          return wp.expired();
+        }
+      };
     }
 
     class slot_base
     {
     public:
-      typedef std::vector<boost::weak_ptr<void> > tracked_container_type;
-      typedef std::vector<boost::shared_ptr<void> > locked_container_type;
+      typedef std::vector<detail::void_weak_ptr_variant> tracked_container_type;
+      typedef std::vector<detail::void_shared_ptr_variant> locked_container_type;
 
       const tracked_container_type& tracked_objects() const {return _tracked_objects;}
       locked_container_type lock() const
@@ -41,11 +68,8 @@
         tracked_container_type::const_iterator it;
         for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
         {
-          try
-          {
-            locked_objects.push_back(shared_ptr<void>(*it));
-          }
-          catch(const bad_weak_ptr &)
+          locked_objects.push_back(apply_visitor(detail::lock_weak_ptr_visitor(), *it));
+          if(apply_visitor(detail::expired_weak_ptr_visitor(), *it))
           {
             boost::throw_exception(expired_slot());
           }
@@ -57,7 +81,7 @@
         tracked_container_type::const_iterator it;
         for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
         {
-          if(it->expired()) return true;
+          if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) return true;
         }
         return false;
       }
Modified: branches/release/libs/signals2/doc/reference/signal_type.xml
==============================================================================
--- branches/release/libs/signals2/doc/reference/signal_type.xml	(original)
+++ branches/release/libs/signals2/doc/reference/signal_type.xml	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -153,17 +153,17 @@
             <default>boost::parameter::void_</default>
           </template-type-parameter>
         </template>
-        <purpose>Specify a the template type parameters of a boost::signals2::signal using named parameters.</purpose>
+        <purpose>Specify a the template type parameters of a <classname>boost::signals2::signal</classname> using named parameters.</purpose>
         <description>
           <para>The <code>signal_type</code> metafunction employs the Boost.Parameter library to
-            allow users to specify the template type parameters of a <classname>signal</classname>
+            allow users to specify the template type parameters of a <classname>signals2::signal</classname>
             using named parameters.  The resulting signal type is provided through the
             <code>signal_type::type</code> typedef.  Named template type parameters
             can enhance readability of code, and provide convenience for specifying classes
             which have a large number of template parameters.
           </para>
           <para>The template type parameters may be passed positionally, similarly to passing them
-            to the <classname>signal</classname> class directly.  Or, they may be passed as named template parameters
+            to the <classname>signals2::signal</classname> class directly.  Or, they may be passed as named template parameters
             by wrapping them in one of the template keyword classes provided in the
             <code>boost::signals2::keywords</code> namespace.  The supported template keywords are:
             <classname>keywords::signature_type</classname>, <classname>keywords::combiner_type</classname>,
Modified: branches/release/libs/signals2/doc/snippet_extractor.cpp
==============================================================================
--- branches/release/libs/signals2/doc/snippet_extractor.cpp	(original)
+++ branches/release/libs/signals2/doc/snippet_extractor.cpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -65,6 +65,7 @@
             throw std::runtime_error("failed to obtain snippet name");
           }
           snippet_out_file.close();
+          snippet_out_file.clear();
           snippet_out_file.open(std::string(output_directory + "/" + snippet_name + ".xml").c_str());
           snippet_out_file << "<!-- Code snippet \"" << snippet_name <<
             "\" extracted from \"" << file_name << "\" by snippet_extractor.\n" <<
Modified: branches/release/libs/signals2/test/track_test.cpp
==============================================================================
--- branches/release/libs/signals2/test/track_test.cpp	(original)
+++ branches/release/libs/signals2/test/track_test.cpp	2010-08-25 15:01:06 EDT (Wed, 25 Aug 2010)
@@ -9,6 +9,7 @@
 
 // For more information, see http://www.boost.org
 
+#include <memory>
 #include <boost/optional.hpp>
 #include <boost/ref.hpp>
 #include <boost/shared_ptr.hpp>
@@ -108,5 +109,36 @@
     BOOST_CHECK(s1(2) == 2);
   }
   BOOST_CHECK(s1(2) == 0);
+
+// there isn't a boost config macro that detects the existance of std::shared_ptr or std::weak_ptr,
+// so we rely on BOOST_NO_VARIADIC_TEMPLATES as a hack
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+  // Test tracking through std::shared_ptr/weak_ptr
+  BOOST_CHECK(s1(5) == 0);
+  {
+    std::shared_ptr<int> shorty(new int());
+    s1.connect(sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(shorty));
+    BOOST_CHECK(s1(5) == 5);
+  }
+  BOOST_CHECK(s1(5) == 0);
+  {
+    std::shared_ptr<int> shorty(new int());
+    s1.connect
+    (
+      sig_type::slot_type
+      (
+        swallow(),
+        shorty.get(),
+        _1
+      ).track_foreign
+      (
+        std::weak_ptr<int>(shorty)
+      )
+    );
+    BOOST_CHECK(s1(5) == 5);
+  }
+  BOOST_CHECK(s1(5) == 0);
+#endif
+
   return 0;
 }