diff --git a/include/boost/function.hpp b/include/boost/function.hpp index c01808f..31b1f0b 100644 --- a/include/boost/function.hpp +++ b/include/boost/function.hpp @@ -463,58 +463,58 @@ namespace boost { function(Functor* f) : base_type(f) {} #endif // __BORLANDC__ - function(const function& f) : base_type(static_cast(f)){} + function(const self_type& f) : base_type(static_cast(f)){} template function& operator=(const Functor& f) { - function(f).swap(*this); + self_type(f).swap(*this); return *this; } #ifdef __BORLANDC__ template - function& operator=(Functor* f) + self_type& operator=(Functor* f) { - function(f).swap(*this); + self_type(f).swap(*this); return *this; } #endif // __BORLANDC__ - function& operator=(const base_type& f) + self_type& operator=(const base_type& f) { - function(f).swap(*this); + self_type(f).swap(*this); return *this; } - function& operator=(const function& f) + self_type& operator=(const self_type& f) { - function(f).swap(*this); + self_type(f).swap(*this); return *this; } template void set(const Functor& f) { - function(f).swap(*this); + self_type(f).swap(*this); } #ifdef __BORLANDC__ template void set(Functor* f) { - function(f).swap(*this); + self_type(f).swap(*this); } #endif // __BORLANDC__ void set(const base_type& f) { - function(f).swap(*this); + self_type(f).swap(*this); } - void set(const function& f) + void set(const self_type& f) { - function(f).swap(*this); + self_type(f).swap(*this); } }; diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp index 79ef170..12deacd 100644 --- a/include/boost/function/function_base.hpp +++ b/include/boost/function/function_base.hpp @@ -397,8 +397,15 @@ namespace boost { inline void postcall(const function_base*) {} }; - // The default function mixin costs nothing - struct empty_function_mixin {}; + // The default function mixin does nothing. The assignment and copy-construction operators + // are all defined because MSVC defines broken versions. + struct empty_function_mixin { + empty_function_mixin() {}; + empty_function_mixin(const empty_function_mixin&) {}; + + empty_function_mixin& operator=(const empty_function_mixin&) + {return *this; } + }; } #endif // BOOST_FUNCTION_BASE_HEADER diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index 0e8aafe..6d0cda1 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -474,6 +474,7 @@ namespace boost { typedef Policy policy_type; typedef Mixin mixin_type; typedef Allocator allocator_type; + typedef BOOST_FUNCTION_FUNCTION self_type; private: #ifdef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS @@ -490,8 +491,17 @@ namespace boost { { } + // MSVC chokes if the following two constructors are collapsed into + // one with a default parameter. template - BOOST_FUNCTION_FUNCTION(const Functor& f, const Mixin& m = Mixin()) : + BOOST_FUNCTION_FUNCTION(const Functor& f) : + function_base(), Mixin() BOOST_FUNCTION_INIT + { + this->assign_to(f); + } + + template + BOOST_FUNCTION_FUNCTION(const Functor& f, const Mixin& m) : function_base(), Mixin(m) BOOST_FUNCTION_INIT { this->assign_to(f); @@ -556,10 +566,15 @@ namespace boost { return result; } + // The distinction between when to use BOOST_FUNCTION_FUNCTION and + // when to use self_type is obnoxious. MSVC cannot handle self_type as + // the return type of these assignment operators, but Borland C++ cannot + // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to + // construct. template BOOST_FUNCTION_FUNCTION& operator=(const Functor& f) { - BOOST_FUNCTION_FUNCTION(f, static_cast(*this)).swap(*this); + self_type(f, static_cast(*this)).swap(*this); return *this; } @@ -567,7 +582,7 @@ namespace boost { template BOOST_FUNCTION_FUNCTION& operator=(Functor* f) { - BOOST_FUNCTION_FUNCTION(f, static_cast(*this)).swap(*this); + self_type(f, static_cast(*this)).swap(*this); return *this; } #endif // __BORLANDC__ @@ -575,14 +590,14 @@ namespace boost { template void set(const Functor& f) { - BOOST_FUNCTION_FUNCTION(f, static_cast(*this)).swap(*this); + self_type(f, static_cast(*this)).swap(*this); } #ifdef __BORLANDC__ template void set(Functor* f) { - BOOST_FUNCTION_FUNCTION(f, static_cast(*this)).swap(*this); + self_type(f, static_cast(*this)).swap(*this); } #endif // __BORLANDC__ @@ -592,7 +607,7 @@ namespace boost { if (&f == this) return *this; - BOOST_FUNCTION_FUNCTION(f).swap(*this); + self_type(f).swap(*this); return *this; } @@ -602,7 +617,7 @@ namespace boost { if (&f == this) return; - BOOST_FUNCTION_FUNCTION(f).swap(*this); + self_type(f).swap(*this); } void swap(BOOST_FUNCTION_FUNCTION& other)