$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66236 - sandbox/function/boost/function
From: dsaritz_at_[hidden]
Date: 2010-10-28 14:05:39
Author: psiha
Date: 2010-10-28 14:05:36 EDT (Thu, 28 Oct 2010)
New Revision: 66236
URL: http://svn.boost.org/trac/boost/changeset/66236
Log:
Changed initial empty construction to support non-stateless empty handlers (in effect to support broken/ancient compilers that cannot detect that the empty handlers are actually trivial empty classes and resort to complex assignment paths).
Text files modified: 
   sandbox/function/boost/function/function_base.hpp     |    24 ++++++++++++++++++------                
   sandbox/function/boost/function/function_template.hpp |    16 ++++++++--------                        
   2 files changed, 26 insertions(+), 14 deletions(-)
Modified: sandbox/function/boost/function/function_base.hpp
==============================================================================
--- sandbox/function/boost/function/function_base.hpp	(original)
+++ sandbox/function/boost/function/function_base.hpp	2010-10-28 14:05:36 EDT (Thu, 28 Oct 2010)
@@ -470,7 +470,7 @@
       };
 
 
-      #ifdef _DEBUG
+      #ifndef NDEBUG
         template <typename T>
         void debug_clear( T & target )
         {    
@@ -1115,7 +1115,12 @@
   class safe_mover;
 
 public:
-    function_base( detail::function::vtable const & vtable ) : p_vtable_( &vtable ) { detail::function::debug_clear( this->functor_ ); }
+    template <class EmptyHandler>
+    function_base( detail::function::vtable const & empty_handler_vtable, EmptyHandler )
+    {
+        detail::function::debug_clear( *this );
+        this->clear<true, EmptyHandler>( empty_handler_vtable );
+    }
     ~function_base() { destroy(); }
 
   template <class EmptyHandler>
@@ -1192,7 +1197,7 @@
       return *p_vtable_;
   }
 
-  template <class EmptyHandler>
+  template <bool direct, class EmptyHandler>
   BF_NOTHROW
   void clear( detail::function::vtable const & empty_handler_vtable )
   {
@@ -1200,7 +1205,7 @@
       // is not necessary here but a simple
       // this->p_vtable_ = &empty_handler_vtable...
       EmptyHandler /*const*/ emptyHandler;
-      assign<false, EmptyHandler>
+      assign<direct, EmptyHandler>
       (
         emptyHandler,
         empty_handler_vtable,
@@ -1666,11 +1671,18 @@
     using namespace detail::function;
 
     if ( has_empty_target( boost::addressof( f ) ) )
-        this->clear<EmptyHandler>( empty_handler_vtable );
+        this->clear<direct, EmptyHandler>( empty_handler_vtable );
     else
     if ( direct )
     {
-        BOOST_ASSERT( this->p_vtable_ == &empty_handler_vtable );
+        BOOST_ASSERT
+        (
+            ( this->p_vtable_ == &empty_handler_vtable ) ||
+            (
+                is_same<EmptyHandler, FunctionObj>::value &&
+                this->p_vtable_ == NULL
+            )
+        );
         typedef typename get_functor_manager<FunctionObj, Allocator>::type functor_manager;
         functor_manager::assign( f, this->functor_, a );
         this->p_vtable_ = &functor_vtable;
Modified: sandbox/function/boost/function/function_template.hpp
==============================================================================
--- sandbox/function/boost/function/function_template.hpp	(original)
+++ sandbox/function/boost/function/function_template.hpp	2010-10-28 14:05:36 EDT (Thu, 28 Oct 2010)
@@ -246,7 +246,7 @@
 
   public: // Public function interface.
 
-    BOOST_FUNCTION_FUNCTION() : function_base( empty_handler_vtable() )
+    BOOST_FUNCTION_FUNCTION() : function_base( empty_handler_vtable(), base_empty_handler() )
     {
         // Implementation note:
         //   The condition is relaxed for Clang and older GCC that simply seem
@@ -275,7 +275,7 @@
         #endif // BOOST_NO_SFINAE
     )
       :
-      function_base( empty_handler_vtable() )
+      function_base( empty_handler_vtable(), base_empty_handler() )
     {
       this->do_assign<true, Functor>( f );
     }
@@ -293,22 +293,22 @@
         #endif // BOOST_NO_SFINAE
     )
       :
-      function_base( empty_handler_vtable() )
+      function_base( empty_handler_vtable(), base_empty_handler() )
     {
       this->do_assign<true, Functor>( f, a );
     }
 
 
 #ifndef BOOST_NO_SFINAE
-    BOOST_FUNCTION_FUNCTION(clear_type*) : function_base( empty_handler_vtable() ) { }
+    BOOST_FUNCTION_FUNCTION(clear_type*) : function_base( empty_handler_vtable(), base_empty_handler() ) { }
 #else
-    BOOST_FUNCTION_FUNCTION(int zero) : function_base( empty_handler_vtable() )
+    BOOST_FUNCTION_FUNCTION(int zero) : function_base( empty_handler_vtable(), base_empty_handler() )
     {
       BOOST_ASSERT(zero == 0);
     }
 #endif
 
-    BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base( empty_handler_vtable() )
+    BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base( empty_handler_vtable(), base_empty_handler() )
     {
       this->do_assign<true>( f );
     }
@@ -319,7 +319,7 @@
     /// Clear out a target (replace it with an empty handler), if there is one.
     void clear()
     {
-        function_base::clear<base_empty_handler>( empty_handler_vtable() );
+        function_base::clear<false, base_empty_handler>( empty_handler_vtable() );
     }
 
     template<typename FunctionObj>
@@ -424,7 +424,7 @@
     }
 #endif
 
-    void swap(BOOST_FUNCTION_FUNCTION& other)
+    void swap( BOOST_FUNCTION_FUNCTION & other )
     {
         BOOST_STATIC_ASSERT( sizeof( BOOST_FUNCTION_FUNCTION ) == sizeof( function_base ) );
         return function_base::swap<base_empty_handler>( other, empty_handler_vtable() );