Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r66223 - sandbox/function/boost/function
From: dsaritz_at_[hidden]
Date: 2010-10-28 05:37:08


Author: psiha
Date: 2010-10-28 05:37:04 EDT (Thu, 28 Oct 2010)
New Revision: 66223
URL: http://svn.boost.org/trac/boost/changeset/66223

Log:
Many compilation error fixes.
Removed the no longer used trivial_heap_storage_atom typedef.
Replaced some SFINAE based dispatch with tag based dispatch.
Fixed assignment of different boost::function<> instantiations as well as empty boost::ref() wrapped function objects.
Minor stylistic changes.
Text files modified:
   sandbox/function/boost/function/function_base.hpp | 149 ++++++++++++++++++++-------------------
   sandbox/function/boost/function/function_template.hpp | 9 +
   2 files changed, 85 insertions(+), 73 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 05:37:04 EDT (Thu, 28 Oct 2010)
@@ -158,29 +158,35 @@
             template <class Other>
             struct rebind { typedef fallocator<Other> other; };
 
+ //...zzz...the two constructors make it non-stateless...
             fallocator() {}
 
- template <class Other>
- fallocator( fallocator<Other> const & ) {}
+ template <class Other> fallocator( fallocator<Other> const & ) {}
 
- static pointer address( reference value ) { return addressof( value ); }
- static const_pointer address( const_reference value ) { return addressof( value ); }
+ template <class Other>
+ fallocator & operator=( fallocator<Other> const & ) { return *this; }
 
             template <class Other>
- fallocator<Other> & operator=( fallocator<Other> const & ) { return *this; }
+ bool operator==( fallocator<Other> const & ) const { return true; }
+
+ static pointer address( reference value ) { return boost::addressof( value ); }
+ static const_pointer address( const_reference value ) { return boost::addressof( value ); }
 
             pointer allocate ( size_type const count, void const * /*p_hint*/ ) { return allocate( count ); }
- pointer allocate ( size_type const count ) { return ::operator new( count * sizeof( T ) ); }
- void deallocate( pointer const ptr , size_type const /*count*/ ) { ::operator delete( ptr ); }
+ pointer allocate ( size_type const count ) { return static_cast<pointer>( ::operator new( count * sizeof( T ) ) ); }
+ void deallocate( pointer const ptr , size_type /*count*/ ) { deallocate( ptr ); }
+ void deallocate( pointer const ptr ) { ::operator delete( ptr ); }
 
             void construct( pointer const ptr, T const & source ) { new ( ptr ) T( source ); }
- void destroy ( pointer const ptr ) { ptr->~T(); }
+ void destroy ( pointer const ptr ) { ptr->~T(); ignore_unused_variable_warning( ptr ); }
 
             static size_type max_size() { return (std::numeric_limits<size_type>::max)() / sizeof( T ); }
         };
 
         typedef fallocator<void *> dummy_allocator;
 
+ //...zzz...BOOST_STATIC_ASSERT( is_stateless<dummy_allocator>::value );
+
         struct thiscall_optimization_available_helper
         {
             static void free_function () {}
@@ -210,10 +216,10 @@
           template <typename Functor>
           typed_functor( Functor & functor )
               :
- pFunctor ( addressof ( functor ) ),
- type_id ( BOOST_SP_TYPEID( Functor ) ),
- const_qualified ( is_const <Functor>::value ),
- volatile_qualified( is_volatile<Functor>::value )
+ pFunctor ( boost::addressof( functor ) ),
+ type_id ( BOOST_SP_TYPEID( Functor ) ),
+ const_qualified ( is_const <Functor>::value ),
+ volatile_qualified( is_volatile<Functor>::value )
           {
               BOOST_ASSERT( pFunctor );
           }
@@ -288,7 +294,7 @@
         struct trivial_heap_obj_t
         {
             void * ptr;
- std::size_t size; // in number of allocation atoms
+ std::size_t size; // in number of bytes
         } trivial_heap_obj;
 
         // For function pointers of all kinds
@@ -380,7 +386,7 @@
>
       {};
 
- template<typename F>
+ template <typename F>
       class get_function_tag
       {
         typedef typename mpl::if_c<(is_pointer<F>::value || is_msvc_exception_specified_function_pointer<F>::value),
@@ -405,14 +411,13 @@
       {
         functor_and_allocator( F const & f, A a ) : F( f ), A( a ) {}
 
- F & functor () { return *this; }
- A & allocator() { return *this; }
+ F & functor () { return *this; }
+ F const & functor () const { return *this; }
+ A & allocator() { return *this; }
+ A const & allocator() const { return *this; }
       };
 
-
- typedef boost::aligned_storage<sizeof( void * ) * 2, sizeof( void * ) * 2>::type trivial_heap_storage_atom;
-
- template<typename Functor>
+ template <typename Functor>
       struct functor_traits
       {
           BOOST_STATIC_CONSTANT
@@ -447,7 +452,7 @@
           BOOST_STATIC_CONSTANT
           (bool,
           hasDefaultAlignement =
- alignment_of<Functor>::value == alignment_of<trivial_heap_storage_atom>::value);
+ alignment_of<Functor>::value <= alignment_of<double>::value);
       };
 
 
@@ -525,8 +530,8 @@
       struct manager_ptr
       {
       public:
- static void * * functor_ptr( function_buffer & buffer ) { return &buffer.obj_ptr; }
- static void const * const * functor_ptr( function_buffer const & buffer ) { BF_ASSUME( buffer.obj_ptr ); return functor_ptr( const_cast<function_buffer &>( buffer ) ); }
+ static void * * functor_ptr( function_buffer & buffer ) { return &buffer.obj_ptr; }
+ static void const * const * functor_ptr( function_buffer const & buffer ) { BF_ASSUME( buffer.obj_ptr ); return &buffer.obj_ptr; }
 
           template <typename Functor, typename Allocator>
           static void assign( Functor const & functor, function_buffer & out_buffer, Allocator )
@@ -537,7 +542,9 @@
 
           static void BF_FASTCALL_WORKAROUND clone( function_buffer const & in_buffer, function_buffer & out_buffer )
           {
- return assign( *functor_ptr( in_buffer ), out_buffer, dummy_allocator() );
+ //...zzz...even with BF_ASSUME MSVC still generates branching code...
+ //return assign( *functor_ptr( in_buffer ), out_buffer, dummy_allocator() );
+ out_buffer.obj_ptr = in_buffer.obj_ptr;
           }
 
           static void BF_FASTCALL_WORKAROUND move( function_buffer & in_buffer, function_buffer & out_buffer )
@@ -633,8 +640,11 @@
 
           static void BF_FASTCALL_WORKAROUND destroy( function_buffer & buffer )
           {
+ BOOST_ASSERT( buffer.trivial_heap_obj.ptr );
+ BOOST_ASSERT( buffer.trivial_heap_obj.size );
+
               trivial_allocator a;
- a.deallocate( functor_ptr( buffer ) );
+ a.deallocate( static_cast<typename trivial_allocator::pointer>( functor_ptr( buffer ) ), buffer.trivial_heap_obj.size );
               //functor_ptr( buffer ) = 0;
           }
       };
@@ -722,18 +732,18 @@
               assign_aux<guard_t>( functor, out_buffer, source_allocator );
           }
 
- static void clone( function_buffer const & in_buffer, function_buffer & out_buffer )
+ static void BF_FASTCALL_WORKAROUND clone( function_buffer const & in_buffer, function_buffer & out_buffer )
           {
               functor_and_allocator_t const & in_functor_and_allocator( *functor_ptr( in_buffer ) );
               return assign( in_functor_and_allocator.functor(), out_buffer, in_functor_and_allocator.allocator() );
           }
 
- static void move( function_buffer & in_buffer, function_buffer & out_buffer )
+ static void BF_FASTCALL_WORKAROUND move( function_buffer & in_buffer, function_buffer & out_buffer )
           {
               manager_trivial_heap<OriginalAllocator>::move( in_buffer, out_buffer );
           }
 
- static void destroy( function_buffer & buffer )
+ static void BF_FASTCALL_WORKAROUND destroy( function_buffer & buffer )
           {
               functor_and_allocator_t & in_functor_and_allocator( *functor_ptr( buffer ) );
 
@@ -741,10 +751,10 @@
               allocator_allocator_t allocator_allocator( in_functor_and_allocator.allocator() );
               wrapper_allocator_t full_allocator ( in_functor_and_allocator.allocator() );
 
- original_allocator .destroy( &in_functor_and_allocator.functor () );
- allocator_allocator.destroy( &in_functor_and_allocator.allocator() );
+ original_allocator .destroy( original_allocator .address( in_functor_and_allocator.functor () ) );
+ allocator_allocator.destroy( allocator_allocator.address( in_functor_and_allocator.allocator() ) );
 
- full_allocator.deallocate( &in_functor_and_allocator );
+ full_allocator.deallocate( full_allocator.address( in_functor_and_allocator ) );
               //functor_ptr( buffer ) = 0;
           }
 
@@ -760,8 +770,8 @@
               allocator_allocator_t allocator_allocator( source_allocator );
 
               Guard p_placeholder ( full_allocator.allocate( 1 ) );
- Functor * const p_functor_placeholder ( p_placeholder );
- OriginalAllocator * const p_allocator_placeholder( p_placeholder );
+ Functor * const p_functor_placeholder ( get_pointer( p_placeholder ) );
+ OriginalAllocator * const p_allocator_placeholder( get_pointer( p_placeholder ) );
 
               source_allocator .construct( p_functor_placeholder , functor );
               allocator_allocator.construct( p_allocator_placeholder, source_allocator );
@@ -788,7 +798,13 @@
       template <typename Functor, typename Allocator>
       struct functor_manager<Functor, Allocator, true, false, false, true>
       {
- typedef manager_trivial_heap<Allocator> type;
+ typedef typename mpl::if_
+ <
+ //...zzz...is_stateless<Allocator>,
+ is_empty<Allocator>,
+ manager_trivial_heap< Allocator>,
+ manager_generic <Functor, Allocator>
+ >::type type;
       };
 
       template <typename Functor, typename Allocator, bool defaultAligned>
@@ -955,23 +971,6 @@
 
       #endif // BOOST_FUNCTION_NO_RTTI
 
-
-/* ALLOCATOR SUPPORT TEMPORARILY COMMENTED OUT
- template<typename FunctionObj,typename Allocator>
- void
- assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const
- {
- typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
- typedef typename Allocator::template rebind<functor_wrapper_type>::other
- wrapper_allocator_type;
- typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
- wrapper_allocator_type wrapper_allocator(a);
- wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
- wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
- functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
- functor.obj_ptr = new_f;
- }
-*/
       };
 
       template <class Invoker, class Manager>
@@ -1070,7 +1069,12 @@
   class safe_mover;
 
 public:
- function_base( detail::function::vtable const & vtable ) : pVTable( &vtable ) { }
+ function_base( detail::function::vtable const & vtable ) : pVTable( &vtable )
+ {
+ #ifdef _DEBUG
+ std::memset( &this->functor, 0, sizeof( this->functor ) );
+ #endif // _DEBUG
+ }
     ~function_base() { destroy(); }
 
   template <class EmptyHandler>
@@ -1157,13 +1161,14 @@
         emptyHandler,
         empty_handler_vtable,
         empty_handler_vtable,
- detail::function::fallocator<EmptyHandler>()
+ detail::function::fallocator<EmptyHandler>(),
+ mpl::false_()
       );
   }
 
 private: // Assignment from another boost function helpers.
   BF_NOINLINE
- void assign_direct( function_base const & source )
+ void assign_boost_function_direct( function_base const & source )
   {
       source.pVTable->clone( source.functor, this->functor );
       pVTable = source.pVTable;
@@ -1171,24 +1176,24 @@
 
   template <class EmptyHandler>
   BF_NOINLINE
- void assign_guarded( function_base const & source, detail::function::vtable const & empty_handler_vtable )
+ void assign_boost_function_guarded( function_base const & source, detail::function::vtable const & empty_handler_vtable )
   {
       this->destroy();
       cleaner<EmptyHandler> guard( *this, empty_handler_vtable );
- assign_direct( source );
+ assign_boost_function_direct( source );
       guard.cancel();
   }
 
 protected:
   // Assignment from another boost function.
   template <bool direct, typename EmptyHandler, typename FunctionObj, typename Allocator>
- typename enable_if<is_base_of<function_base, FunctionObj> >::type
- assign
+ void assign
   (
- FunctionObj const & f,
+ FunctionObj const & f,
     detail::function::vtable const & functor_vtable,
     detail::function::vtable const & empty_handler_vtable,
- Allocator
+ Allocator,
+ mpl::true_ /*assignment of an instance of the same boost::function<> instantiation*/
   )
   {
     BOOST_ASSERT( &functor_vtable == f.pVTable );
@@ -1197,23 +1202,23 @@
     {
         BOOST_ASSERT( &static_cast<function_base const &>( f ) != this );
         BOOST_ASSERT( this->pVTable == &empty_handler_vtable );
- assign_direct( f );
+ assign_boost_function_direct( f );
     }
     else if( &static_cast<function_base const &>( f ) != this )
     {
- assign_guarded<EmptyHandler>( f, empty_handler_vtable );
+ assign_boost_function_guarded<EmptyHandler>( f, empty_handler_vtable );
     }
   }
 
   // General actual assignment.
   template <bool direct, typename EmptyHandler, typename FunctionObj, typename Allocator>
- typename disable_if<is_base_of<function_base, FunctionObj> >::type
- assign
+ void assign
   (
- FunctionObj const & f,
+ FunctionObj const & f,
     detail::function::vtable const & functor_vtable,
     detail::function::vtable const & empty_handler_vtable,
- Allocator
+ Allocator,
+ mpl::false_ /*generic assign*/
   );
 
   template <typename EmptyHandler, typename FunctionObj, typename Allocator>
@@ -1549,7 +1554,9 @@
     template <class FunctionPtr>
     inline bool has_empty_target( reference_wrapper<FunctionPtr> const * const f )
     {
- return has_empty_target( f->get_pointer() );
+ //...zzz...return has_empty_target( f->get_pointer() );
+ BF_ASSUME( f->get_pointer() != 0 );
+ return f == 0;
     }
 
     template <class FunctionPtr>
@@ -1566,7 +1573,7 @@
     }
 
 #ifdef BOOST_MSVC // MSVC (9.0 SP1 and prior) cannot inline vararg functions
- inline bool has_empty_target(const void*)
+ inline bool has_empty_target( void const * )
 #else
     inline bool has_empty_target(...)
 #endif
@@ -1599,13 +1606,13 @@
 
 //...zzz...here because of has_empty_target()...GCC & Clang are not lazy enough
 template <bool direct, typename EmptyHandler, typename FunctionObj, typename Allocator>
-typename disable_if<is_base_of<function_base, FunctionObj> >::type
-function_base::assign
+void function_base::assign
 (
     FunctionObj const & f,
     detail::function::vtable const & functor_vtable,
     detail::function::vtable const & empty_handler_vtable,
- Allocator const a
+ Allocator const a,
+ mpl::false_ /*generic assign*/
 )
 {
     using namespace detail::function;

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 05:37:04 EDT (Thu, 28 Oct 2010)
@@ -137,6 +137,9 @@
   <
     typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
     class PolicyList
+ #if ( BOOST_FUNCTION_MAX_ARGS > 10 )
+ = default_policies //...zzz...this causes hoards of warnings...
+ #endif // BOOST_FUNCTION_MAX_ARGS > 10
>
   class BOOST_FUNCTION_FUNCTION : public function_base
 
@@ -598,7 +601,8 @@
                 emptyHandler,
                 empty_handler_vtable(),
                 empty_handler_vtable(),
- detail::function::fallocator<base_empty_handler>()
+ detail::function::fallocator<base_empty_handler>(),
+ mpl::false_() /*not assigning another boost::function*/
             );
             emptyHandler. BOOST_NESTED_TEMPLATE handle_empty_invoke<R>();
         }
@@ -610,7 +614,8 @@
                 stored_functor,
                 vtable_for_functor<StoredFunctorAllocator, ActualFunctor>( stored_functor ),
                 empty_handler_vtable(),
- StoredFunctorAllocator( a )
+ StoredFunctorAllocator( a ),
+ is_base_of<BOOST_FUNCTION_FUNCTION, StoredFunctor>() /*are we assigning another boost::function*/
             );
         }
     }


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