|
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,
- ¬hrow_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