From 3ba640809b97931d513135d1c270a6a9b8a28c68 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 14 Jul 2001 19:34:14 +0000 Subject: [PATCH] function.hpp: - Use "self_type" instead of "function" for constructing swapping temporary (Borland C++ needs it) function_base.hpp: - Give empty copy constructor, default constructor, and assignment operator to empty_function_mixin (MSVC generates incorrect ones) function_template.hpp: - Make Borland C++ and MSVC agree on the code (involves an extra constructor definition and careful use of self_type vs. BOOST_FUNCTION_FUNCTION) [SVN r10619] --- include/boost/function.hpp | 26 +++++++++--------- include/boost/function/function_base.hpp | 11 ++++++-- include/boost/function/function_template.hpp | 29 +++++++++++++++----- 3 files changed, 44 insertions(+), 22 deletions(-) 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)