Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r66202 - in sandbox/function/boost/function: . detail
From: dsaritz_at_[hidden]
Date: 2010-10-26 14:09:53


Author: psiha
Date: 2010-10-26 14:09:51 EDT (Tue, 26 Oct 2010)
New Revision: 66202
URL: http://svn.boost.org/trac/boost/changeset/66202

Log:
Added the platform_specifics.hpp header and extracted all compiler specifics into it.
Fixed funnction_base.hpp and function_template.hpp to compile with GCC 4.2.1, GCC 4.5.1, GCC 4.6 and Clang 2.8.
Added:
   sandbox/function/boost/function/detail/platform_specifics.hpp (contents, props changed)
Text files modified:
   sandbox/function/boost/function/function_base.hpp | 358 ++++++++++++++++++++++-----------------
   sandbox/function/boost/function/function_template.hpp | 29 +-
   2 files changed, 214 insertions(+), 173 deletions(-)

Added: sandbox/function/boost/function/detail/platform_specifics.hpp
==============================================================================
--- (empty file)
+++ sandbox/function/boost/function/detail/platform_specifics.hpp 2010-10-26 14:09:51 EDT (Tue, 26 Oct 2010)
@@ -0,0 +1,163 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \file platform_specifics.hpp
+/// ----------------------------
+///
+/// A collection of macros that wrap platform specific details/non standard
+/// extensions.
+///
+/// Copyright (c) Domagoj Saric 2010.
+///
+/// Use, modification and distribution is subject to 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)
+///
+/// For more information, see http://www.boost.org
+////////////////////////////////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+#pragma once
+#ifndef platform_specifics_hpp__37C4B042_4214_41C5_96C9_814CF5243FD1
+#define platform_specifics_hpp__37C4B042_4214_41C5_96C9_814CF5243FD1
+//------------------------------------------------------------------------------
+#include "boost/assert.hpp"
+#include "boost/config.hpp"
+//------------------------------------------------------------------------------
+namespace boost
+{
+//------------------------------------------------------------------------------
+namespace detail
+{
+//------------------------------------------------------------------------------
+
+#if defined( BOOST_MSVC )
+
+ #define BF_NOVTABLE __declspec( novtable )
+ #define BF_NOTHROW __declspec( nothrow )
+ #define BF_NOALIAS __declspec( noalias )
+ #define BF_NOTHROWNOALIAS __declspec( nothrow noalias )
+ #define BF_NOTHROWNORESTRICTNOALIAS __declspec( nothrow restrict noalias )
+
+ #define BF_SELECTANY __declspec( selectany )
+
+ #define BF_CDECL __cdecl
+ #define BF_FASTCALL __fastcall
+
+ #define BF_RESTRICT __restrict
+
+ #define BF_FORCEINLINE __forceinline
+ #define BF_NOINLINE __declspec( noinline )
+
+ #define BF_OVERRIDE override
+ #define BF_SEALED sealed
+
+ #define BF_UNREACHABLE_CODE BOOST_ASSERT( !"This code should not be reached." ); __assume( false );
+ #define BF_ASSUME( condition ) BOOST_ASSERT( condition ); __assume( condition )
+
+ #define BF_GNU_SPECIFIC( expression )
+ #define BF_MSVC_SPECIFIC( expression ) expression
+
+#elif defined( __clang__ ) || defined( __GNUC__ )
+
+ #define BF_NOVTABLE
+ #define BF_NOTHROW __attribute__(( nothrow ))
+ #define BF_NOALIAS
+ #define BF_NOTHROWNOALIAS NOTHROW
+ #define BF_NOTHROWNORESTRICTNOALIAS NOTHROW
+
+ #ifdef _WIN32
+ #define BF_SELECTANY __declspec( selectany )
+ #else
+ #define BF_SELECTANY
+ #endif
+
+ #define BF_CDECL __attribute__(( cdecl ))
+ #define BF_FASTCALL __attribute__(( fastcall ))
+
+ #define BF_RESTRICT
+
+ #ifdef _DEBUG
+ #define BF_FORCEINLINE
+ #else
+ #define BF_FORCEINLINE __attribute__(( always_inline ))
+ #endif
+ #define BF_NOINLINE __attribute__(( noinline ))
+
+ #define BF_OVERRIDE
+ #define BF_SEALED
+
+ // http://en.chys.info/2010/07/counterpart-of-assume-in-gcc
+ #if ( __clang__ >= 2 ) || ( ( ( __GNUC__ * 10 ) + __GNUC_MINOR__ ) >= 45 )
+ #define BF_UNREACHABLE_CODE BOOST_ASSERT( !"This code should not be reached." ); __builtin_unreachable();
+ #define BF_ASSUME( condition ) BOOST_ASSERT( condition ); do { if ( !(condition) ) __builtin_unreachable(); } while ( 0 )
+ #else
+ #define BF_UNREACHABLE_CODE BOOST_ASSERT( !"This code should not be reached." );
+ #define BF_ASSUME( condition ) BOOST_ASSERT( condition )
+ #endif
+
+ #define BF_GNU_SPECIFIC( expression ) expression
+ #define BF_MSVC_SPECIFIC( expression )
+
+#elif defined( __BORLANDC__ )
+
+ #define BF_NOVTABLE
+ #define BF_NOTHROW
+ #define BF_NOALIAS
+ #define BF_NOTHROWNOALIAS NOTHROW
+ #define BF_NOTHROWNORESTRICTNOALIAS NOTHROW
+
+ #define BF_SELECTANY
+
+ #define BF_CDECL __cdecl
+ #define BF_FASTCALL __fastcall
+
+ #define BF_RESTRICT
+
+ #define BF_FORCEINLINE inline
+
+ #define BF_OVERRIDE
+ #define BF_SEALED
+
+ #define BF_UNREACHABLE_CODE BOOST_ASSERT( !"This code should not be reached." );
+
+ #define BF_ASSUME( condition ) BOOST_ASSERT( condition )
+
+ #define BF_GNU_SPECIFIC( expression )
+ #define BF_MSVC_SPECIFIC( expression )
+
+#else
+
+ #define BF_NOVTABLE
+ #define BF_NOTHROW
+ #define BF_NOALIAS
+ #define BF_NOTHROWNOALIAS NOTHROW
+ #define BF_NOTHROWNORESTRICTNOALIAS NOTHROW
+
+ #define BF_SELECTANY
+
+ #define BF_CDECL
+ #define BF_FASTCALL
+
+ #define BF_RESTRICT
+
+ #define BF_FORCEINLINE inline
+
+ #define BF_OVERRIDE
+ #define BF_SEALED
+
+ #define BF_UNREACHABLE_CODE BOOST_ASSERT( !"This code should not be reached." );
+
+ #define BF_ASSUME( condition ) BOOST_ASSERT( condition )
+
+ #define BF_GNU_SPECIFIC( expression )
+ #define BF_MSVC_SPECIFIC( expression )
+
+#endif
+
+#define BF_DEFAULT_CASE_UNREACHABLE default: UNREACHABLE_CODE break;
+
+//------------------------------------------------------------------------------
+} // namespace detail
+//------------------------------------------------------------------------------
+} // namespace boost
+//------------------------------------------------------------------------------
+#endif // platform_specifics_hpp

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-26 14:09:51 EDT (Tue, 26 Oct 2010)
@@ -11,6 +11,9 @@
 #ifndef BOOST_FUNCTION_BASE_HEADER
 #define BOOST_FUNCTION_BASE_HEADER
 
+#include "detail/platform_specifics.hpp"
+#include "detail/safe_bool.hpp"
+
 #include <stdexcept>
 #include <stddef.h>
 #include <string>
@@ -61,8 +64,6 @@
 #include <boost/function_equal.hpp>
 #include <boost/function/function_fwd.hpp>
 
-#include <boost/function/detail/safe_bool.hpp>
-
 #if defined(BOOST_MSVC)
 # pragma warning( push )
 # pragma warning( disable : 4127 ) // "conditional expression is constant"
@@ -82,12 +83,6 @@
 #endif
 #endif // BOOST_NO_TYPEID
 
-#if defined( BOOST_MSVC ) || defined( __GNUC__ ) || defined( __BORLANDC__ )
- #define BOOST_FUNCTION_FASTCALL __fastcall
-#else
- #define BOOST_FUNCTION_FASTCALL
-#endif
-
 
 // Borrowed from Boost.Python library: determines the cases where we
 // need to use std::type_info::name to compare instead of operator==.
@@ -124,6 +119,24 @@
                        Type>::type
 #endif
 
+
+#if defined( __clang__ ) || ( defined( __GNUC__ ) && ( ( ( __GNUC__ * 10 ) + __GNUC_MINOR__ ) < 45 ) )
+ #define BOOST_FUNCTION_CLANG_AND_OLD_GCC_BROKEN_STATIC_ASSERT BOOST_ASSERT
+#else
+ #define BOOST_FUNCTION_CLANG_AND_OLD_GCC_BROKEN_STATIC_ASSERT BOOST_STATIC_ASSERT
+#endif // __clang__
+
+#if defined( BOOST_MSVC ) || defined( __clang__ ) || ( defined( __GNUC__ ) && ( ( ( __GNUC__ * 10 ) + __GNUC_MINOR__ ) >= 45 ) )
+ #define BF_VT_REF &
+ #define BF_VT_DEREF *
+ #define BF_FASTCALL_WORKAROUND BF_FASTCALL
+#else
+ #define BF_VT_REF * const
+ #define BF_VT_DEREF
+ #define BF_FASTCALL_WORKAROUND // GCC 4.2.1 just doesn't seem happy with decorated function pointers...
+#endif
+
+
 namespace boost {
   namespace detail {
     namespace function {
@@ -148,7 +161,10 @@
     #ifndef BOOST_FUNCTION_NO_RTTI
       // For transferring stored function object type information back to the
       // interface side.
- class typed_functor : noncopyable
+ class typed_functor
+ #ifndef __GNUC__ //...zzz...GCC and Clang have serious RVO problems...
+ : noncopyable
+ #endif // __GNUC__
       {
       public:
           template <typename Functor>
@@ -314,7 +330,7 @@
           :
           public mpl::bool_
           <
- #ifdef BOOST_MSVC
+ #ifdef _MSC_VER
               !is_class <T>::value &&
               !is_fundamental<T>::value &&
               ( sizeof( T ) == sizeof( void (*) (void) ) )
@@ -361,6 +377,8 @@
       };
 */
 
+ typedef boost::aligned_storage<sizeof( void * ) * 2, sizeof( void * ) * 2>::type trivial_heap_storage_atom;
+
       template<typename Functor>
       struct functor_traits
       {
@@ -396,7 +414,7 @@
           BOOST_STATIC_CONSTANT
           (bool,
           hasDefaultAlignement =
- alignment_of<Functor>::value == alignment_of<manager_trivial_heap::storage_atom>::value);
+ alignment_of<Functor>::value == alignment_of<trivial_heap_storage_atom>::value);
       };
 
 
@@ -412,28 +430,24 @@
       {
       #ifndef BOOST_FUNCTION_NO_RTTI
       private:
- template <bool is_ref_wrapper, bool is_member_pointer>
- static ActualFunctor * actual_functor_ptr( StoredFunctor * storedFunctor );
-
- template <>
- static ActualFunctor * actual_functor_ptr<true, false>( StoredFunctor * pStoredFunctor )
+ static ActualFunctor * actual_functor_ptr( StoredFunctor * pStoredFunctor, mpl::true_ /*is_ref_wrapper*/, mpl::false_ /*is_member_pointer*/ )
           {
               // needed when StoredFunctor is a static reference
               ignore_unused_variable_warning( pStoredFunctor );
               return pStoredFunctor->get_pointer();
           }
- template <>
- static ActualFunctor * actual_functor_ptr<false, true>( StoredFunctor * pStoredFunctor )
+
+ static ActualFunctor * actual_functor_ptr( StoredFunctor * pStoredFunctor, mpl::false_ /*is_ref_wrapper*/, mpl::true_ /*is_member_pointer*/ )
           {
               BOOST_STATIC_ASSERT( sizeof( StoredFunctor ) == sizeof( ActualFunctor ) );
               return static_cast<ActualFunctor *>( static_cast<void *>( pStoredFunctor ) );
           }
- template <>
- static ActualFunctor * actual_functor_ptr<false, false>( StoredFunctor * pStoredFunctor )
+
+ static ActualFunctor * actual_functor_ptr( StoredFunctor * pStoredFunctor, mpl::false_ /*is_ref_wrapper*/, mpl::false_ /*is_member_pointer*/ )
           {
               BOOST_STATIC_ASSERT
               ((
- ( is_same<remove_cv<ActualFunctor>::type, StoredFunctor>::value ) ||
+ ( is_same<typename remove_cv<ActualFunctor>::type, StoredFunctor>::value ) ||
                   (
                     is_msvc_exception_specified_function_pointer<ActualFunctor>::value &&
                     is_msvc_exception_specified_function_pointer<StoredFunctor>::value &&
@@ -443,10 +457,15 @@
               return pStoredFunctor;
           }
       public:
- static typed_functor BOOST_FUNCTION_FASTCALL get_typed_functor( function_buffer const & buffer )
+ // See the related comment in the vtable struct definition.
+ #ifdef __GNUC__
+ static typed_functor get_typed_functor( function_buffer const & buffer )
+ #else
+ static typed_functor BF_FASTCALL get_typed_functor( function_buffer const & buffer )
+ #endif
           {
               StoredFunctor * const pStoredFunctor( FunctorManager::functor_ptr( const_cast<function_buffer &>( buffer ) ) );
- ActualFunctor * const pActualFunctor( actual_functor_ptr<is_reference_wrapper<StoredFunctor>::value, is_member_pointer<ActualFunctor>::value>( pStoredFunctor ) );
+ ActualFunctor * const pActualFunctor( actual_functor_ptr( pStoredFunctor, is_reference_wrapper<StoredFunctor>(), is_member_pointer<ActualFunctor>() ) );
               return typed_functor( *pActualFunctor );
           }
       #endif // BOOST_FUNCTION_NO_RTTI
@@ -458,22 +477,22 @@
       <
           class FunctorManager,
           typename ActualFunctor,
- typename StoredFunctor = FunctorManager::Functor
+ typename StoredFunctor = typename FunctorManager::Functor
>
       struct typed_manager
           :
           public FunctorManager,
- public functor_type_info<ActualFunctor, StoredFunctor, typed_manager<FunctorManager, ActualFunctor, StoredFunctor>>
+ public functor_type_info<ActualFunctor, StoredFunctor, typed_manager<FunctorManager, ActualFunctor, StoredFunctor> >
       {
           typedef StoredFunctor Functor;
- static StoredFunctor * functor_ptr( function_buffer & buffer ) { return static_cast<StoredFunctor *>( FunctorManager::functor_ptr( buffer ) ); }
+ static StoredFunctor * functor_ptr( function_buffer & buffer ) { return static_cast<StoredFunctor *>( static_cast<void *>( FunctorManager::functor_ptr( buffer ) ) ); }
       };
 
       /// Manager for trivial objects that fit into sizeof( void * ).
       struct manager_ptr
       {
       public:
- static void * * functor_ptr( function_buffer & buffer ) { __assume( buffer.obj_ptr ); return &buffer.obj_ptr; }
+ static void * * functor_ptr( function_buffer & buffer ) { BF_ASSUME( buffer.obj_ptr ); return &buffer.obj_ptr; }
           static void const * const * functor_ptr( function_buffer const & buffer ) { return functor_ptr( const_cast<function_buffer &>( buffer ) ); }
 
           template <typename Functor>
@@ -483,18 +502,18 @@
               new ( functor_ptr( out_buffer ) ) Functor( functor );
           }
 
- static void BOOST_FUNCTION_FASTCALL 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 )
           {
               return assign( *functor_ptr( in_buffer ), out_buffer );
           }
 
- static void BOOST_FUNCTION_FASTCALL move( function_buffer & in_buffer, function_buffer & out_buffer )
+ static void BF_FASTCALL_WORKAROUND move( function_buffer & in_buffer, function_buffer & out_buffer )
           {
               clone( in_buffer, out_buffer );
               destroy( in_buffer );
           }
 
- static void BOOST_FUNCTION_FASTCALL destroy( function_buffer & buffer )
+ static void BF_FASTCALL_WORKAROUND destroy( function_buffer & /*buffer*/ )
           {
               //*functor_ptr( buffer ) = 0;
           }
@@ -509,7 +528,7 @@
           template <typename Functor>
           static void assign( Functor const & functor, function_buffer & out_buffer )
           {
- BOOST_STATIC_ASSERT
+ BOOST_ASSERT
               (
                 functor_traits<Functor>::allowsPODOptimization &&
                 functor_traits<Functor>::allowsSmallObjectOptimization
@@ -517,18 +536,18 @@
               new ( functor_ptr( out_buffer ) ) Functor( functor );
           }
 
- static void BOOST_FUNCTION_FASTCALL 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 )
           {
               return assign( in_buffer, out_buffer );
           }
 
- static void BOOST_FUNCTION_FASTCALL move( function_buffer & in_buffer, function_buffer & out_buffer )
+ static void BF_FASTCALL_WORKAROUND move( function_buffer & in_buffer, function_buffer & out_buffer )
           {
               clone( in_buffer, out_buffer );
               destroy( in_buffer );
           }
 
- static void BOOST_FUNCTION_FASTCALL destroy( function_buffer & buffer )
+ static void BF_FASTCALL_WORKAROUND destroy( function_buffer & /*buffer*/ )
           {
               //std::memset( &buffer, 0, sizeof( buffer ) );
           }
@@ -538,16 +557,16 @@
       struct manager_trivial_heap
       {
       public:
- typedef boost::aligned_storage<sizeof( void * ) * 2, sizeof( void * ) * 2>::type storage_atom;
+ typedef trivial_heap_storage_atom storage_atom;
 
       public:
- static void * & functor_ptr( function_buffer & buffer ) { __assume( buffer.trivial_heap_obj.ptr ); return buffer.trivial_heap_obj.ptr; }
+ static void * & functor_ptr( function_buffer & buffer ) { BF_ASSUME( buffer.trivial_heap_obj.ptr ); return buffer.trivial_heap_obj.ptr; }
           static void * functor_ptr( function_buffer const & buffer ) { return functor_ptr( const_cast<function_buffer &>( buffer ) ); }
 
           template <typename Functor>
           static void assign( Functor const & functor, function_buffer & out_buffer )
           {
- BOOST_STATIC_ASSERT
+ BOOST_FUNCTION_CLANG_AND_OLD_GCC_BROKEN_STATIC_ASSERT
               (
                 functor_traits<Functor>::allowsPODOptimization &&
                 functor_traits<Functor>::hasDefaultAlignement
@@ -560,7 +579,7 @@
               return clone( in_buffer, out_buffer );
           }
 
- static void BOOST_FUNCTION_FASTCALL 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 )
           {
               std::size_t const storage_array_size( in_buffer.trivial_heap_obj.size );
               out_buffer.trivial_heap_obj.ptr = new storage_atom[ storage_array_size ];
@@ -568,25 +587,25 @@
               std::memcpy( functor_ptr( out_buffer ), functor_ptr( in_buffer ), storage_array_size * sizeof( storage_atom ) );
           }
 
- static void BOOST_FUNCTION_FASTCALL move( function_buffer & in_buffer, function_buffer & out_buffer )
+ static void BF_FASTCALL_WORKAROUND move( function_buffer & in_buffer, function_buffer & out_buffer )
           {
               out_buffer.trivial_heap_obj = in_buffer.trivial_heap_obj;
               //in_buffer.trivial_heap_obj.ptr = 0;
           }
 
- static void BOOST_FUNCTION_FASTCALL destroy( function_buffer & buffer )
+ static void BF_FASTCALL_WORKAROUND destroy( function_buffer & buffer )
           {
- delete [] functor_ptr( buffer );
+ delete [] static_cast<storage_atom *>( functor_ptr( buffer ) );
               //functor_ptr( buffer ) = 0;
           }
       };
 
       /// Manager for non-trivial objects that can live in a function_buffer.
- template <typename Functor>
+ template <typename FunctorParam>
       struct manager_small
       {
       public:
- typedef Functor Functor;
+ typedef FunctorParam Functor;
 
           static Functor * functor_ptr( function_buffer & buffer ) { return static_cast<Functor *>( manager_trivial_small::functor_ptr( buffer ) ); }
           static Functor const * functor_ptr( function_buffer const & buffer ) { return functor_ptr( const_cast<function_buffer &>( buffer ) ); }
@@ -596,20 +615,20 @@
               new ( functor_ptr( out_buffer ) ) Functor( functor );
           }
 
- static void BOOST_FUNCTION_FASTCALL 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 const & in_functor( *functor_ptr( in_buffer ) );
               return assign( in_functor, out_buffer );
           }
 
- static void BOOST_FUNCTION_FASTCALL move( function_buffer & in_buffer, function_buffer & out_buffer )
+ static void BF_FASTCALL_WORKAROUND move( function_buffer & in_buffer, function_buffer & out_buffer )
           {
               // ...use swap here?
               clone( in_buffer, out_buffer );
               destroy( in_buffer );
           }
 
- static void BOOST_FUNCTION_FASTCALL destroy( function_buffer & buffer )
+ static void BF_FASTCALL_WORKAROUND destroy( function_buffer & buffer )
           {
               functor_ptr( buffer )->~Functor();
           }
@@ -617,15 +636,21 @@
 
       /// Fully generic manager for non-trivial objects that cannot live/fit in
       /// a function_buffer.
- template <typename Functor>
+ template <typename FunctorParam>
       struct manager_generic
       {
       public:
- typedef Functor Functor;
+ typedef FunctorParam Functor;
 
           static Functor * & functor_ptr( function_buffer & buffer )
           {
- return static_cast<Functor * &>( manager_trivial_heap::functor_ptr( buffer ) );
+ return *static_cast<Functor * *>
+ (
+ static_cast<void *>
+ (
+ &manager_trivial_heap::functor_ptr( buffer )
+ )
+ );
           }
 
           static Functor * functor_ptr( function_buffer const & buffer )
@@ -913,9 +938,7 @@
 
         void clone ( function_buffer const & in_buffer, function_buffer & out_buffer ) const { do_clone( in_buffer, out_buffer ); }
         void move ( function_buffer & in_buffer, function_buffer & out_buffer ) const { do_move ( in_buffer, out_buffer ); }
- #ifdef BOOST_MSVC
- __declspec( nothrow )
- #endif
+ BF_NOTHROW
         void destroy( function_buffer & buffer ) const { do_destroy( buffer ); }
 
         // The possibly-decorated-invoker-wrapper is not used here because MSVC
@@ -926,20 +949,24 @@
       public: // "Private but not private" to enable aggregate-style initialization.
         invoker_placeholder_type const void_invoker;
 
- void (BOOST_FUNCTION_FASTCALL & do_clone )( function_buffer const & in_buffer, function_buffer & out_buffer );
- void (BOOST_FUNCTION_FASTCALL & do_move )( function_buffer & in_buffer, function_buffer & out_buffer );
- void (BOOST_FUNCTION_FASTCALL & do_destroy )( function_buffer & buffer );
+ void (BF_FASTCALL_WORKAROUND BF_VT_REF do_clone )( function_buffer const & in_buffer, function_buffer & out_buffer );
+ void (BF_FASTCALL_WORKAROUND BF_VT_REF do_move )( function_buffer & in_buffer, function_buffer & out_buffer );
+ void (BF_FASTCALL_WORKAROUND BF_VT_REF do_destroy )( function_buffer & buffer );
 
       #ifndef BOOST_FUNCTION_NO_RTTI
+ public:
         // Because of the MSVC issue described above we mark the
         // get_typed_functor function as nothrow like this, explicitly (because
         // MSVC does not properly support exception specifications this is not a
         // pessimization...it is equivalent to __declspec( nothrow )).
- typed_functor (BOOST_FUNCTION_FASTCALL & get_typed_functor)( function_buffer const & )
- #ifdef BOOST_MSVC
- throw()
+ // OTOH, All GCCs and Clang break down here if they find the fastcall
+ // attribute so they get it undecorated...
+ #ifdef _MSC_VER
+ typed_functor ( BF_FASTCALL BF_VT_REF get_typed_functor )( function_buffer const & ) throw();
+ #else
+ typed_functor ( BF_VT_REF get_typed_functor )( function_buffer const & );
         #endif // BOOST_MSVC
- ;
+
       #endif // BOOST_FUNCTION_NO_RTTI
 
 
@@ -985,11 +1012,11 @@
       vtable const vtable_holder<Invoker, Manager>::stored_vtable =
       {
           vtable_holder<Invoker, Manager>::get_invoker_pointer( thiscall_optimization_available() ),
- &Manager::clone,
- &Manager::move,
- &Manager::destroy
+ BF_VT_DEREF &Manager::clone,
+ BF_VT_DEREF &Manager::move,
+ BF_VT_DEREF &Manager::destroy
         #ifndef BOOST_FUNCTION_NO_RTTI
- ,&Manager::get_typed_functor
+ ,BF_VT_DEREF &Manager::get_typed_functor
         #endif // BOOST_FUNCTION_NO_RTTI
       };
     } // end namespace function
@@ -1033,11 +1060,11 @@
           using namespace detail::function;
           if ( clear )
           {
- assert( pFunction_ );
- typedef functor_traits<EmptyHandler> empty_handler_traits;
- typedef get_functor_manager<EmptyHandler>::type empty_handler_manager;
+ BOOST_ASSERT( pFunction_ );
+ typedef functor_traits <EmptyHandler> empty_handler_traits ;
+ typedef typename get_functor_manager<EmptyHandler>::type empty_handler_manager;
               // remove completely or replace with a simple is_stateless<>?
- BOOST_STATIC_ASSERT
+ BOOST_FUNCTION_CLANG_AND_OLD_GCC_BROKEN_STATIC_ASSERT
               (
                 empty_handler_traits::allowsPODOptimization &&
                 empty_handler_traits::allowsSmallObjectOptimization
@@ -1061,22 +1088,7 @@
     ~function_base() { destroy(); }
 
   template <class EmptyHandler>
- void swap( function_base & other, detail::function::vtable const & empty_handler_vtable )
- {
- if (&other == this)
- return;
-
- function_base tmp( empty_handler_vtable );
-
- safe_mover<EmptyHandler> my_restorer ( *this, tmp );
-
- safe_mover<EmptyHandler> other_restorer( other, *this );
-
- safe_mover_base::move( tmp, other, empty_handler_vtable );
-
- my_restorer .cancel();
- other_restorer.cancel();
- }
+ void swap( function_base & other, detail::function::vtable const & empty_handler_vtable );
 
 #ifndef BOOST_FUNCTION_NO_RTTI
 
@@ -1141,29 +1153,24 @@
 public: // should be protected, but GCC 2.95.3 will fail to allow access
   detail::function::vtable const & get_vtable() const
   {
- assert( pVTable );
- #ifdef BOOST_MSVC
- __assume( pVTable );
- #endif // BOOST_MSVC
+ BF_ASSUME( pVTable );
       return *pVTable;
   }
 
 protected:
   template <class EmptyHandler>
- #ifdef BOOST_MSVC
- __declspec( nothrow )
- #endif
+ BF_NOTHROW
   void clear( detail::function::vtable const & empty_handler_vtable )
   {
       // If we hold to the is_stateless<EmptyHandler> requirement a full assign
       // is not necessary here but a simple
       // this->pVTable = &empty_handler_vtable...
- EmptyHandler const emptyHandler;
+ EmptyHandler /*const*/ emptyHandler;
       assign<false, EmptyHandler>( emptyHandler, empty_handler_vtable, empty_handler_vtable );
   }
 
 private: // Assignment from another boost function helpers.
- __declspec( noinline )
+ BF_NOINLINE
   void assign_direct( function_base const & source )
   {
       source.pVTable->clone( source.functor, this->functor );
@@ -1171,7 +1178,7 @@
   }
 
   template <class EmptyHandler>
- __declspec( noinline )
+ BF_NOINLINE
   void assign_guarded( function_base const & source, detail::function::vtable const & empty_handler_vtable )
   {
       this->destroy();
@@ -1183,7 +1190,7 @@
 protected:
   // Assignment from another boost function.
   template<bool direct, typename EmptyHandler, typename FunctionObj>
- typename enable_if<is_base_of<function_base, FunctionObj>>::type
+ typename enable_if<is_base_of<function_base, FunctionObj> >::type
   assign
   (
     FunctionObj const & f,
@@ -1207,56 +1214,16 @@
 
   // General actual assignment.
   template<bool direct, typename EmptyHandler, typename FunctionObj>
- typename disable_if<is_base_of<function_base, FunctionObj>>::type
+ typename disable_if<is_base_of<function_base, FunctionObj> >::type
   assign
   (
     FunctionObj const & f,
     detail::function::vtable const & functor_vtable,
     detail::function::vtable const & empty_handler_vtable
- )
- {
- using namespace detail::function;
-
- if ( has_empty_target( boost::addressof( f ) ) )
- this->clear<EmptyHandler>( empty_handler_vtable );
- else
- if ( direct )
- {
- assert( this->pVTable == &empty_handler_vtable );
- typedef get_functor_manager<FunctionObj>::type functor_manager;
- functor_manager::assign( f, this->functor );
- this->pVTable = &functor_vtable;
- return;
- }
- else
- {
- // This can/should be rewritten because the small-object-optimization
- // condition is too strict (requires a trivial destructor which is not
- // needed for a no fail assignment).
- bool const has_no_fail_assignement
- (
- functor_traits<FunctionObj>::allowsSmallObjectOptimization &&
- (
- has_nothrow_copy_constructor<FunctionObj>::value ||
- has_trivial_copy_constructor<FunctionObj>::value ||
- is_msvc_exception_specified_function_pointer<FunctionObj>::value
- )
- );
-
- actual_assign<EmptyHandler>
- (
- f,
- functor_vtable,
- empty_handler_vtable,
- mpl::bool_<has_no_fail_assignement>()
- );
- }
- }
+ );
 
   template<typename EmptyHandler, typename FunctionObj>
- #ifdef BOOST_MSVC
- __declspec( nothrow )
- #endif
+ BF_NOTHROW
   void actual_assign
   (
     FunctionObj const & f,
@@ -1265,7 +1232,7 @@
     mpl::true_ /*can use direct assign*/
   )
   {
- typedef detail::function::get_functor_manager<FunctionObj>::type functor_manager;
+ typedef typename detail::function::get_functor_manager<FunctionObj>::type functor_manager;
       this->destroy();
       functor_manager::assign( f, this->functor );
       this->pVTable = &functor_vtable;
@@ -1283,7 +1250,7 @@
       // This most generic case needs to be reworked [currently uses redundant
       // copying (generic one, through function pointers) and does not use all
       // the type information it can...]...
- typedef detail::function::get_functor_manager<FunctionObj>::type functor_manager;
+ typedef typename detail::function::get_functor_manager<FunctionObj>::type functor_manager;
       function_base tmp( empty_handler_vtable );
       functor_manager::assign( f, tmp.functor );
       tmp.pVTable = &functor_vtable;
@@ -1356,6 +1323,26 @@
     }
 };
 
+
+template <class EmptyHandler>
+void function_base::swap( function_base & other, detail::function::vtable const & empty_handler_vtable )
+{
+ if (&other == this)
+ return;
+
+ function_base tmp( empty_handler_vtable );
+
+ safe_mover<EmptyHandler> my_restorer ( *this, tmp );
+
+ safe_mover<EmptyHandler> other_restorer( other, *this );
+
+ safe_mover_base::move( tmp, other, empty_handler_vtable );
+
+ my_restorer .cancel();
+ other_restorer.cancel();
+}
+
+
 /// The bad_function_call exception class is thrown when an empty
 /// boost::function object is invoked that uses the throw_on_empty empty
 /// handler.
@@ -1370,8 +1357,10 @@
 private:
     #ifdef BOOST_MSVC
         __declspec( noinline noreturn )
+ #else
+ BF_NOINLINE
     #endif // BOOST_MSVC
- void throw_bad_call() const
+ static void throw_bad_call()
     {
         boost::throw_exception( bad_function_call() );
     }
@@ -1381,7 +1370,7 @@
     #ifdef BOOST_MSVC
         __declspec( noreturn )
     #endif // BOOST_MSVC
- result_type operator()() const
+ static result_type handle_empty_invoke()
     {
         throw_bad_call();
         #ifndef BOOST_MSVC
@@ -1394,7 +1383,7 @@
 {
 public:
     template <class result_type>
- result_type operator()() const
+ static result_type handle_empty_invoke()
     {
         BOOST_ASSERT( !"Call to empty boost::function!" );
         return result_type();
@@ -1405,16 +1394,16 @@
 {
 public:
     template <class result_type>
- result_type operator()() const { return result_type(); }
+ static result_type handle_empty_invoke() { return result_type(); }
 };
 
 
-#define BOOST_FUNCTION_ENABLE_IF_FUNCTION \
- template <class Function> \
- typename enable_if \
- < \
- is_base_of<::boost::function_base, Function>, \
- bool \
+#define BOOST_FUNCTION_ENABLE_IF_FUNCTION \
+ template <class Function> \
+ typename enable_if \
+ < \
+ is_base_of<boost::function_base, Function>, \
+ bool \
>::type
 
 #ifndef BOOST_NO_SFINAE
@@ -1611,12 +1600,63 @@
     }
   } // end namespace function
 } // end namespace detail
+
+//...zzz...here because of has_empty_target()...GCC & Clang are not lazy enough
+template<bool direct, typename EmptyHandler, typename FunctionObj>
+typename disable_if<is_base_of<function_base, FunctionObj> >::type
+function_base::assign
+(
+ FunctionObj const & f,
+ detail::function::vtable const & functor_vtable,
+ detail::function::vtable const & empty_handler_vtable
+)
+{
+ using namespace detail::function;
+
+ if ( has_empty_target( boost::addressof( f ) ) )
+ this->clear<EmptyHandler>( empty_handler_vtable );
+ else
+ if ( direct )
+ {
+ BOOST_ASSERT( this->pVTable == &empty_handler_vtable );
+ typedef typename get_functor_manager<FunctionObj>::type functor_manager;
+ functor_manager::assign( f, this->functor );
+ this->pVTable = &functor_vtable;
+ return;
+ }
+ else
+ {
+ // This can/should be rewritten because the small-object-optimization
+ // condition is too strict (requires a trivial destructor which is not
+ // needed for a no fail assignment).
+
+ actual_assign<EmptyHandler>
+ (
+ f,
+ functor_vtable,
+ empty_handler_vtable,
+ mpl::bool_
+ <
+ //has_no_fail_assignement:
+ functor_traits<FunctionObj>::allowsSmallObjectOptimization &&
+ (
+ has_nothrow_copy_constructor<FunctionObj>::value ||
+ has_trivial_copy_constructor<FunctionObj>::value ||
+ is_msvc_exception_specified_function_pointer<FunctionObj>::value
+ )
+ >()
+ );
+ }
+}
+
 } // end namespace boost
 
 #undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
 #undef BOOST_FUNCTION_COMPARE_TYPE_ID
 #undef BOOST_FUNCTION_ENABLE_IF_FUNCTION
-#undef BOOST_FUNCTION_FASTCALL
+#undef BOOST_FUNCTION_CLANG_AND_OLD_GCC_BROKEN_STATIC_ASSERT
+#undef BF_VT_REF
+#undef BF_VT_DEREF
 
 // ...to be moved 'somewhere else'...
 namespace boost {
@@ -1642,7 +1682,7 @@
 template
 <
     typename T,
- typename detail::get_non_type_template_parameter_type<T>::type t
+ typename detail::get_non_type_template_parameter_type<T>::type static_instance
>
 class static_reference_wrapper
 {
@@ -1656,15 +1696,15 @@
 public:
     operator type () const { return get(); }
 
- static type get() { return t; }
+ static type get() { return static_instance; }
 
     static T const * get_pointer()
     {
         if ( is_reference<type>::value )
- return get_pointer( t );
+ return get_pointer( static_instance );
         else
         {
- static add_const<type>::type t_( t );
+ static typename add_const<type>::type t_( static_instance );
             return get_pointer( t_ );
         }
     }
@@ -1673,9 +1713,9 @@
 template
 <
     typename T,
- typename detail::get_non_type_template_parameter_type<T>::type t
+ typename detail::get_non_type_template_parameter_type<T>::type static_instance
>
-class is_reference_wrapper<static_reference_wrapper<T, t>>
+class is_reference_wrapper<static_reference_wrapper<T, static_instance> >
     : public mpl::true_
 {
 };
@@ -1689,9 +1729,9 @@
 template
 <
     typename T,
- typename detail::get_non_type_template_parameter_type<T>::type t
+ typename detail::get_non_type_template_parameter_type<T>::type static_instance
>
-class is_static_reference_wrapper<static_reference_wrapper<T, t>>
+class is_static_reference_wrapper<static_reference_wrapper<T, static_instance> >
     : public mpl::true_
 {
 };
@@ -1725,7 +1765,7 @@
     return detail::static_reference_maker<T const>( t );
 }
 
-#define BOOST_SREF( object ) boost::sref( object ).sref<object>()
+#define BOOST_SREF( object ) boost::sref( object ). BOOST_NESTED_TEMPLATE sref<object>()
 
 } // end namespace boost
 

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-26 14:09:51 EDT (Tue, 26 Oct 2010)
@@ -195,8 +195,6 @@
                 user_specified_empty_handler
>::type base_empty_handler;
 
- BOOST_STATIC_ASSERT( is_stateless<base_empty_handler>::value );
-
   // The nothrow policy and runtime throw detection functionality works only in
   // release mode/with optimizations on. It should also work in debug for plain
   // function pointers with compilers that properly implement the 'exception
@@ -225,7 +223,7 @@
     {
         R operator()( BOOST_FUNCTION_PARMS ) const
         {
- return base_empty_handler::operator()<R>();
+ return base_empty_handler:: BOOST_NESTED_TEMPLATE handle_empty_invoke<R>();
         }
     };
 
@@ -235,7 +233,10 @@
 
   public: // Public function interface.
 
- BOOST_FUNCTION_FUNCTION() : function_base( empty_handler_vtable() ) {}
+ BOOST_FUNCTION_FUNCTION() : function_base( empty_handler_vtable() )
+ {
+ BOOST_FUNCTION_CLANG_AND_OLD_GCC_BROKEN_STATIC_ASSERT( is_stateless<base_empty_handler>::value );
+ }
 
     // MSVC chokes if the following two constructors are collapsed into
     // one with a default parameter.
@@ -301,7 +302,7 @@
     template <signature_type * f>
     void assign()
     {
- this->assign( detail::static_reference_maker<signature_type *>::sref<f>() );
+ this->assign( detail::static_reference_maker<signature_type *>:: BOOST_NESTED_TEMPLATE sref<f>() );
     }
 
     template <class AClass, R (AClass::*mmf)(BOOST_FUNCTION_TEMPLATE_ARGS)>
@@ -349,7 +350,7 @@
     // over"...
     BOOST_FUNCTION_FUNCTION & operator=( BOOST_FUNCTION_FUNCTION const & f )
     {
- this->assign( f )
+ this->assign( f );
         return *this;
     }
 
@@ -428,12 +429,12 @@
     template <class F>
     static bool is_nothrow()
     {
- typedef bool ( throw_test_signature ) ( unwrap_reference<F>::type & BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS );
+ typedef bool ( throw_test_signature ) ( typename unwrap_reference<F>::type & BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS );
         return detail::function::is_nothrow_helper
                 <
                     throw_test_signature,
- &nothrow_test<unwrap_reference<F>::type>,
- &throw_test <unwrap_reference<F>::type>
+ &BOOST_FUNCTION_FUNCTION:: BOOST_NESTED_TEMPLATE nothrow_test<typename unwrap_reference<F>::type>,
+ &BOOST_FUNCTION_FUNCTION:: BOOST_NESTED_TEMPLATE throw_test <typename unwrap_reference<F>::type>
>::is_nothrow;
 
                 #if defined(BOOST_MSVC) && BOOST_MSVC == 1400
@@ -469,13 +470,13 @@
     result_type do_invoke( BOOST_FUNCTION_PARMS BOOST_FUNCTION_COMMA mpl::true_ /*this call*/ ) const
     {
         typedef result_type (detail::function::function_buffer::* invoker_type)(BOOST_FUNCTION_TEMPLATE_ARGS);
- return (functor.*(get_vtable().invoker<invoker_type>()))(BOOST_FUNCTION_ARGS);
+ return (functor.*(get_vtable(). BOOST_NESTED_TEMPLATE invoker<invoker_type>()))(BOOST_FUNCTION_ARGS);
     }
 
     result_type do_invoke( BOOST_FUNCTION_PARMS BOOST_FUNCTION_COMMA mpl::false_ /*free call*/ ) const
     {
         typedef result_type (* invoker_type)( BOOST_FUNCTION_TEMPLATE_ARGS BOOST_FUNCTION_COMMA detail::function::function_buffer & );
- return get_vtable().invoker<invoker_type>()( BOOST_FUNCTION_ARGS BOOST_FUNCTION_COMMA functor );
+ return get_vtable(). BOOST_NESTED_TEMPLATE invoker<invoker_type>()( BOOST_FUNCTION_ARGS BOOST_FUNCTION_COMMA functor );
     }
 
 
@@ -605,14 +606,14 @@
             // assign) when the nothrow policy is specified...this should be
             // fixed...
             BOOST_ASSERT( is_nothrow<my_empty_handler>() );
- base_empty_handler const emptyHandler;
+ base_empty_handler /*const*/ emptyHandler;
             function_base::assign<direct, base_empty_handler>
             (
                 emptyHandler,
                 empty_handler_vtable(),
                 empty_handler_vtable()
             );
- emptyHandler.operator()<R>();
+ emptyHandler. BOOST_NESTED_TEMPLATE handle_empty_invoke<R>();
         }
         else
             function_base::assign<direct, base_empty_handler>
@@ -736,7 +737,7 @@
 #endif
   operator=(Functor const & f)
   {
- this->assign<Functor>( f );
+ this-> BOOST_NESTED_TEMPLATE assign<Functor>( f );
     return *this;
   }
 


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