Boost logo

Boost-Commit :

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() );


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk