Compare commits

..

1 Commits

Author SHA1 Message Date
d6a9a888f1 Phoenix Reloaded
[SVN r53348]
2009-05-28 17:15:17 +00:00
13 changed files with 156 additions and 132 deletions

22
CMakeLists.txt Normal file
View File

@ -0,0 +1,22 @@
#----------------------------------------------------------------------------
# This file was automatically generated from the original CMakeLists.txt file
# Add a variable to hold the headers for the library
set (lib_headers
function.hpp
function
)
# Add a library target to the build system
boost_library_project(
function
# SRCDIRS
TESTDIRS test
HEADERS ${lib_headers}
DOCDIRS doc
# DESCRIPTION
MODULARIZED
# AUTHORS
# MAINTAINERS
)

2
doc/CMakeLists.txt Normal file
View File

@ -0,0 +1,2 @@
boost_add_documentation(function.xml
faq.xml history.xml misc.xml reference.xml tests.xml tutorial.xml)

View File

@ -7,10 +7,9 @@ project boost/doc ;
import boostbook : boostbook ; import boostbook : boostbook ;
boostbook function-doc boostbook function-doc
: :
function.xml function.xml
: :
<xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
; ;

View File

@ -35,12 +35,12 @@ form to use for your compiler.
<row> <row>
<entry> <entry>
<itemizedlist spacing="compact"> <itemizedlist spacing="compact">
<listitem><simpara>GNU C++ 2.95.x, 3.0.x and later versions</simpara></listitem> <listitem><simpara>GNU C++ 2.95.x, 3.0.x, 3.1.x</simpara></listitem>
<listitem><simpara>Comeau C++ 4.2.45.2</simpara></listitem> <listitem><simpara>Comeau C++ 4.2.45.2</simpara></listitem>
<listitem><simpara>SGI MIPSpro 7.3.0</simpara></listitem> <listitem><simpara>SGI MIPSpro 7.3.0</simpara></listitem>
<listitem><simpara>Intel C++ 5.0, 6.0</simpara></listitem> <listitem><simpara>Intel C++ 5.0, 6.0</simpara></listitem>
<listitem><simpara>Compaq's cxx 6.2</simpara></listitem> <listitem><simpara>Compaq's cxx 6.2</simpara></listitem>
<listitem><simpara>Microsoft Visual C++ 7.1 and later versions</simpara></listitem> <listitem><simpara>Microsoft Visual C++ 7.1</simpara></listitem>
</itemizedlist> </itemizedlist>
</entry> </entry>
<entry> <entry>

View File

@ -23,8 +23,8 @@
// in anything that may be included by function_template.hpp doesn't break // in anything that may be included by function_template.hpp doesn't break
#include <boost/function/detail/prologue.hpp> #include <boost/function/detail/prologue.hpp>
// Older Visual Age C++ version do not handle the file iteration well // Visual Age C++ doesn't handle the file iteration well
#if BOOST_WORKAROUND(__IBMCPP__, >= 500) && BOOST_WORKAROUND(__IBMCPP__, < 800) #if BOOST_WORKAROUND(__IBMCPP__, >= 500)
# if BOOST_FUNCTION_MAX_ARGS >= 0 # if BOOST_FUNCTION_MAX_ARGS >= 0
# include <boost/function/function0.hpp> # include <boost/function/function0.hpp>
# endif # endif

View File

@ -15,8 +15,8 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include <new> #include <new>
#include <typeinfo>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/integer.hpp> #include <boost/integer.hpp>
#include <boost/type_traits/has_trivial_copy.hpp> #include <boost/type_traits/has_trivial_copy.hpp>
@ -54,9 +54,7 @@
// Borrowed from Boost.Python library: determines the cases where we // Borrowed from Boost.Python library: determines the cases where we
// need to use std::type_info::name to compare instead of operator==. // need to use std::type_info::name to compare instead of operator==.
#if defined( BOOST_NO_TYPEID ) # if (defined(__GNUC__) && __GNUC__ >= 3) \
# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
#elif (defined(__GNUC__) && __GNUC__ >= 3) \
|| defined(_AIX) \ || defined(_AIX) \
|| ( defined(__sgi) && defined(__host_mips)) || ( defined(__sgi) && defined(__host_mips))
# include <cstring> # include <cstring>
@ -105,7 +103,7 @@ namespace boost {
// For pointers to std::type_info objects // For pointers to std::type_info objects
struct type_t { struct type_t {
// (get_functor_type_tag, check_functor_type_tag). // (get_functor_type_tag, check_functor_type_tag).
const detail::sp_typeinfo* type; const BOOST_FUNCTION_STD_NS::type_info* type;
// Whether the type is const-qualified. // Whether the type is const-qualified.
bool const_qualified; bool const_qualified;
@ -203,11 +201,11 @@ namespace boost {
{ {
switch (op) { switch (op) {
case clone_functor_tag: case clone_functor_tag:
out_buffer.obj_ref = in_buffer.obj_ref; out_buffer.obj_ref.obj_ptr = in_buffer.obj_ref.obj_ptr;
return; return;
case move_functor_tag: case move_functor_tag:
out_buffer.obj_ref = in_buffer.obj_ref; out_buffer.obj_ref.obj_ptr = in_buffer.obj_ref.obj_ptr;
in_buffer.obj_ref.obj_ptr = 0; in_buffer.obj_ref.obj_ptr = 0;
return; return;
@ -217,12 +215,12 @@ namespace boost {
case check_functor_type_tag: case check_functor_type_tag:
{ {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
// Check whether we have the same type. We can add // Check whether we have the same type. We can add
// cv-qualifiers, but we can't take them away. // cv-qualifiers, but we can't take them away.
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(F)) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F))
&& (!in_buffer.obj_ref.is_const_qualified && (!in_buffer.obj_ref.is_const_qualified
|| out_buffer.type.const_qualified) || out_buffer.type.const_qualified)
&& (!in_buffer.obj_ref.is_volatile_qualified && (!in_buffer.obj_ref.is_volatile_qualified
@ -234,7 +232,7 @@ namespace boost {
return; return;
case get_functor_type_tag: case get_functor_type_tag:
out_buffer.type.type = &BOOST_SP_TYPEID(F); out_buffer.type.type = &typeid(F);
out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified; out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified;
out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified; out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified;
return; return;
@ -264,12 +262,6 @@ namespace boost {
A(a) A(a)
{ {
} }
functor_wrapper(const functor_wrapper& f) :
F(static_cast<const F&>(f)),
A(static_cast<const A&>(f))
{
}
}; };
/** /**
@ -294,14 +286,14 @@ namespace boost {
} else if (op == destroy_functor_tag) } else if (op == destroy_functor_tag)
out_buffer.func_ptr = 0; out_buffer.func_ptr = 0;
else if (op == check_functor_type_tag) { else if (op == check_functor_type_tag) {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = &in_buffer.func_ptr; out_buffer.obj_ptr = &in_buffer.func_ptr;
else else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &BOOST_SP_TYPEID(Functor); out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
@ -315,27 +307,23 @@ namespace boost {
if (op == clone_functor_tag || op == move_functor_tag) { if (op == clone_functor_tag || op == move_functor_tag) {
const functor_type* in_functor = const functor_type* in_functor =
reinterpret_cast<const functor_type*>(&in_buffer.data); reinterpret_cast<const functor_type*>(&in_buffer.data);
new (reinterpret_cast<void*>(&out_buffer.data)) functor_type(*in_functor); new ((void*)&out_buffer.data) functor_type(*in_functor);
if (op == move_functor_tag) { if (op == move_functor_tag) {
functor_type* f = reinterpret_cast<functor_type*>(&in_buffer.data); reinterpret_cast<functor_type*>(&in_buffer.data)->~Functor();
(void)f; // suppress warning about the value of f not being used (MSVC)
f->~Functor();
} }
} else if (op == destroy_functor_tag) { } else if (op == destroy_functor_tag) {
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
functor_type* f = reinterpret_cast<functor_type*>(&out_buffer.data); reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor();
(void)f; // suppress warning about the value of f not being used (MSVC)
f->~Functor();
} else if (op == check_functor_type_tag) { } else if (op == check_functor_type_tag) {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = &in_buffer.data; out_buffer.obj_ptr = &in_buffer.data;
else else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &BOOST_SP_TYPEID(Functor); out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
@ -373,10 +361,8 @@ namespace boost {
// Clone the functor // Clone the functor
// GCC 2.95.3 gets the CV qualifiers wrong here, so we // GCC 2.95.3 gets the CV qualifiers wrong here, so we
// can't do the static_cast that we should do. // can't do the static_cast that we should do.
// jewillco: Changing this to static_cast because GCC 2.95.3 is
// obsolete.
const functor_type* f = const functor_type* f =
static_cast<const functor_type*>(in_buffer.obj_ptr); (const functor_type*)(in_buffer.obj_ptr);
functor_type* new_f = new functor_type(*f); functor_type* new_f = new functor_type(*f);
out_buffer.obj_ptr = new_f; out_buffer.obj_ptr = new_f;
} else if (op == move_functor_tag) { } else if (op == move_functor_tag) {
@ -389,14 +375,14 @@ namespace boost {
delete f; delete f;
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) { } else if (op == check_functor_type_tag) {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr; out_buffer.obj_ptr = in_buffer.obj_ptr;
else else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &BOOST_SP_TYPEID(Functor); out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
@ -431,7 +417,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type; typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) { switch (op) {
case get_functor_type_tag: case get_functor_type_tag:
out_buffer.type.type = &BOOST_SP_TYPEID(functor_type); out_buffer.type.type = &typeid(functor_type);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
return; return;
@ -480,7 +466,7 @@ namespace boost {
// GCC 2.95.3 gets the CV qualifiers wrong here, so we // GCC 2.95.3 gets the CV qualifiers wrong here, so we
// can't do the static_cast that we should do. // can't do the static_cast that we should do.
const functor_wrapper_type* f = const functor_wrapper_type* f =
static_cast<const functor_wrapper_type*>(in_buffer.obj_ptr); (const functor_wrapper_type*)(in_buffer.obj_ptr);
wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*f)); wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*f));
wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
wrapper_allocator.construct(copy, *f); wrapper_allocator.construct(copy, *f);
@ -500,14 +486,14 @@ namespace boost {
wrapper_allocator.deallocate(victim,1); wrapper_allocator.deallocate(victim,1);
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) { } else if (op == check_functor_type_tag) {
const detail::sp_typeinfo& check_type const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type; = *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor))) if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr; out_buffer.obj_ptr = in_buffer.obj_ptr;
else else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &BOOST_SP_TYPEID(Functor); out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
@ -534,7 +520,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type; typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) { switch (op) {
case get_functor_type_tag: case get_functor_type_tag:
out_buffer.type.type = &BOOST_SP_TYPEID(functor_type); out_buffer.type.type = &typeid(functor_type);
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
return; return;
@ -635,11 +621,11 @@ public:
/** Determine if the function is empty (i.e., has no target). */ /** Determine if the function is empty (i.e., has no target). */
bool empty() const { return !vtable; } bool empty() const { return !vtable; }
/** Retrieve the type of the stored function object, or BOOST_SP_TYPEID(void) /** Retrieve the type of the stored function object, or typeid(void)
if this is empty. */ if this is empty. */
const detail::sp_typeinfo& target_type() const const BOOST_FUNCTION_STD_NS::type_info& target_type() const
{ {
if (!vtable) return BOOST_SP_TYPEID(void); if (!vtable) return typeid(void);
detail::function::function_buffer type; detail::function::function_buffer type;
get_vtable()->manager(functor, type, detail::function::get_functor_type_tag); get_vtable()->manager(functor, type, detail::function::get_functor_type_tag);
@ -652,7 +638,7 @@ public:
if (!vtable) return 0; if (!vtable) return 0;
detail::function::function_buffer type_result; detail::function::function_buffer type_result;
type_result.type.type = &BOOST_SP_TYPEID(Functor); type_result.type.type = &typeid(Functor);
type_result.type.const_qualified = is_const<Functor>::value; type_result.type.const_qualified = is_const<Functor>::value;
type_result.type.volatile_qualified = is_volatile<Functor>::value; type_result.type.volatile_qualified = is_volatile<Functor>::value;
get_vtable()->manager(functor, type_result, get_vtable()->manager(functor, type_result,
@ -670,14 +656,14 @@ public:
if (!vtable) return 0; if (!vtable) return 0;
detail::function::function_buffer type_result; detail::function::function_buffer type_result;
type_result.type.type = &BOOST_SP_TYPEID(Functor); type_result.type.type = &typeid(Functor);
type_result.type.const_qualified = true; type_result.type.const_qualified = true;
type_result.type.volatile_qualified = is_volatile<Functor>::value; type_result.type.volatile_qualified = is_volatile<Functor>::value;
get_vtable()->manager(functor, type_result, get_vtable()->manager(functor, type_result,
detail::function::check_functor_type_tag); detail::function::check_functor_type_tag);
// GCC 2.95.3 gets the CV qualifiers wrong here, so we // GCC 2.95.3 gets the CV qualifiers wrong here, so we
// can't do the static_cast that we should do. // can't do the static_cast that we should do.
return static_cast<const Functor*>(type_result.obj_ptr); return (const Functor*)(type_result.obj_ptr);
} }
template<typename F> template<typename F>
@ -721,7 +707,7 @@ public:
public: // should be protected, but GCC 2.95.3 will fail to allow access public: // should be protected, but GCC 2.95.3 will fail to allow access
detail::function::vtable_base* get_vtable() const { detail::function::vtable_base* get_vtable() const {
return reinterpret_cast<detail::function::vtable_base*>( return reinterpret_cast<detail::function::vtable_base*>(
reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01)); reinterpret_cast<std::size_t>(vtable) & ~(std::size_t)0x01);
} }
bool has_trivial_copy_and_destroy() const { bool has_trivial_copy_and_destroy() const {
@ -903,8 +889,4 @@ namespace detail {
#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL #undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
#undef BOOST_FUNCTION_COMPARE_TYPE_ID #undef BOOST_FUNCTION_COMPARE_TYPE_ID
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif
#endif // BOOST_FUNCTION_BASE_HEADER #endif // BOOST_FUNCTION_BASE_HEADER

View File

@ -11,7 +11,6 @@
// Note: this header is a header template and must NOT have multiple-inclusion // Note: this header is a header template and must NOT have multiple-inclusion
// protection. // protection.
#include <boost/function/detail/prologue.hpp> #include <boost/function/detail/prologue.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
# pragma warning( push ) # pragma warning( push )
@ -514,7 +513,7 @@ namespace boost {
if (f) { if (f) {
// should be a reinterpret cast, but some compilers insist // should be a reinterpret cast, but some compilers insist
// on giving cv-qualifiers to free functions // on giving cv-qualifiers to free functions
functor.func_ptr = reinterpret_cast<void (*)()>(f); functor.func_ptr = (void (*)())(f);
return true; return true;
} else { } else {
return false; return false;
@ -536,7 +535,7 @@ namespace boost {
// objects, so we invoke through mem_fn() but we retain the // objects, so we invoke through mem_fn() but we retain the
// right target_type() values. // right target_type() values.
if (f) { if (f) {
this->assign_to(boost::mem_fn(f), functor); this->assign_to(mem_fn(f), functor);
return true; return true;
} else { } else {
return false; return false;
@ -549,7 +548,7 @@ namespace boost {
// objects, so we invoke through mem_fn() but we retain the // objects, so we invoke through mem_fn() but we retain the
// right target_type() values. // right target_type() values.
if (f) { if (f) {
this->assign_to_a(boost::mem_fn(f), functor, a); this->assign_to_a(mem_fn(f), functor, a);
return true; return true;
} else { } else {
return false; return false;
@ -563,7 +562,7 @@ namespace boost {
void void
assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
{ {
new (reinterpret_cast<void*>(&functor.data)) FunctionObj(f); new ((void*)&functor.data) FunctionObj(f);
} }
template<typename FunctionObj,typename Allocator> template<typename FunctionObj,typename Allocator>
void void
@ -625,10 +624,14 @@ namespace boost {
assign_to(const reference_wrapper<FunctionObj>& f, assign_to(const reference_wrapper<FunctionObj>& f,
function_buffer& functor, function_obj_ref_tag) function_buffer& functor, function_obj_ref_tag)
{ {
functor.obj_ref.obj_ptr = (void *)(f.get_pointer()); if (!boost::detail::function::has_empty_target(f.get_pointer())) {
functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value; functor.obj_ref.obj_ptr = (void *)f.get_pointer();
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value; functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
return true; functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
return true;
} else {
return false;
}
} }
template<typename FunctionObj,typename Allocator> template<typename FunctionObj,typename Allocator>
bool bool
@ -677,7 +680,7 @@ namespace boost {
vtable_type* get_vtable() const { vtable_type* get_vtable() const {
return reinterpret_cast<vtable_type*>( return reinterpret_cast<vtable_type*>(
reinterpret_cast<std::size_t>(vtable) & ~static_cast<size_t>(0x01)); reinterpret_cast<std::size_t>(vtable) & ~(std::size_t)0x01);
} }
struct clear_type {}; struct clear_type {};
@ -751,6 +754,9 @@ namespace boost {
~BOOST_FUNCTION_FUNCTION() { clear(); } ~BOOST_FUNCTION_FUNCTION() { clear(); }
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// MSVC 6.0 and prior require all definitions to be inline, but
// these definitions can become very costly.
result_type operator()(BOOST_FUNCTION_PARMS) const result_type operator()(BOOST_FUNCTION_PARMS) const
{ {
if (this->empty()) if (this->empty())
@ -759,6 +765,9 @@ namespace boost {
return get_vtable()->invoker return get_vtable()->invoker
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
} }
#else
result_type operator()(BOOST_FUNCTION_PARMS) const;
#endif
// The distinction between when to use BOOST_FUNCTION_FUNCTION and // The distinction between when to use BOOST_FUNCTION_FUNCTION and
// when to use self_type is obnoxious. MSVC cannot handle self_type as // when to use self_type is obnoxious. MSVC cannot handle self_type as
@ -777,26 +786,24 @@ namespace boost {
operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
{ {
this->clear(); this->clear();
BOOST_TRY { try {
this->assign_to(f); this->assign_to(f);
} BOOST_CATCH (...) { } catch (...) {
vtable = 0; vtable = 0;
BOOST_RETHROW; throw;
} }
BOOST_CATCH_END
return *this; return *this;
} }
template<typename Functor,typename Allocator> template<typename Functor,typename Allocator>
void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a) void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
{ {
this->clear(); this->clear();
BOOST_TRY{ try {
this->assign_to_a(f,a); this->assign_to_a(f,a);
} BOOST_CATCH (...) { } catch (...) {
vtable = 0; vtable = 0;
BOOST_RETHROW; throw;
} }
BOOST_CATCH_END
} }
#ifndef BOOST_NO_SFINAE #ifndef BOOST_NO_SFINAE
@ -821,13 +828,12 @@ namespace boost {
return *this; return *this;
this->clear(); this->clear();
BOOST_TRY { try {
this->assign_to_own(f); this->assign_to_own(f);
} BOOST_CATCH (...) { } catch (...) {
vtable = 0; vtable = 0;
BOOST_RETHROW; throw;
} }
BOOST_CATCH_END
return *this; return *this;
} }
@ -911,7 +917,7 @@ namespace boost {
if (boost::has_trivial_copy_constructor<Functor>::value && if (boost::has_trivial_copy_constructor<Functor>::value &&
boost::has_trivial_destructor<Functor>::value && boost::has_trivial_destructor<Functor>::value &&
detail::function::function_allows_small_object_optimization<Functor>::value) detail::function::function_allows_small_object_optimization<Functor>::value)
value |= static_cast<size_t>(0x01); value |= (std::size_t)0x01;
vtable = reinterpret_cast<detail::function::vtable_base *>(value); vtable = reinterpret_cast<detail::function::vtable_base *>(value);
} else } else
vtable = 0; vtable = 0;
@ -945,7 +951,7 @@ namespace boost {
if (boost::has_trivial_copy_constructor<Functor>::value && if (boost::has_trivial_copy_constructor<Functor>::value &&
boost::has_trivial_destructor<Functor>::value && boost::has_trivial_destructor<Functor>::value &&
detail::function::function_allows_small_object_optimization<Functor>::value) detail::function::function_allows_small_object_optimization<Functor>::value)
value |= static_cast<std::size_t>(0x01); value |= (std::size_t)0x01;
vtable = reinterpret_cast<detail::function::vtable_base *>(value); vtable = reinterpret_cast<detail::function::vtable_base *>(value);
} else } else
vtable = 0; vtable = 0;
@ -959,7 +965,9 @@ namespace boost {
if (&f == this) if (&f == this)
return; return;
BOOST_TRY { #if !defined(BOOST_NO_EXCEPTIONS)
try {
#endif
if (!f.empty()) { if (!f.empty()) {
this->vtable = f.vtable; this->vtable = f.vtable;
if (this->has_trivial_copy_and_destroy()) if (this->has_trivial_copy_and_destroy())
@ -971,11 +979,12 @@ namespace boost {
} else { } else {
clear(); clear();
} }
} BOOST_CATCH (...) { #if !defined(BOOST_NO_EXCEPTIONS)
} catch (...) {
vtable = 0; vtable = 0;
BOOST_RETHROW; throw;
} }
BOOST_CATCH_END #endif
} }
}; };
@ -992,6 +1001,22 @@ namespace boost {
f1.swap(f2); f1.swap(f2);
} }
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
typename BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
inline
BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
::operator()(BOOST_FUNCTION_PARMS) const
{
if (this->empty())
boost::throw_exception(bad_function_call());
return get_vtable()->invoker
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
}
#endif
// Poison comparisons between boost::function objects of the same type. // Poison comparisons between boost::function objects of the same type.
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
void operator==(const BOOST_FUNCTION_FUNCTION< void operator==(const BOOST_FUNCTION_FUNCTION<

1
module.cmake Normal file
View File

@ -0,0 +1 @@
boost_module(function DEPENDS detail preprocessor utility)

23
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,23 @@
boost_additional_test_dependencies(function BOOST_DEPENDS test lambda)
boost_test_run(lib_function_test function_test.cpp)
boost_test_run(function_n_test)
boost_test_run(allocator_test)
boost_test_run(stateless_test)
boost_test_run(lambda_test)
boost_test_compile_fail(function_test_fail1)
boost_test_compile_fail(function_test_fail2)
boost_test_compile(function_30)
boost_test_run(function_arith_cxx98)
boost_test_run(function_arith_portable)
boost_test_run(sum_avg_cxx98)
boost_test_run(sum_avg_portable)
boost_test_run(mem_fun_cxx98)
boost_test_run(mem_fun_portable)
boost_test_run(std_bind_cxx98)
boost_test_run(std_bind_portable)
boost_test_run(function_ref_cxx98)
boost_test_run(function_ref_portable)
boost_test_run(contains_test)
boost_test_run(contains2_test)

View File

@ -8,7 +8,6 @@
# For more information, see http://www.boost.org/ # For more information, see http://www.boost.org/
project project
: requirements <toolset>msvc:<asynch-exceptions>on
: source-location $(BOOST_ROOT) : source-location $(BOOST_ROOT)
; ;

View File

@ -128,10 +128,6 @@ test_main(int, char*[])
BOOST_CHECK(dealloc_count == 0); BOOST_CHECK(dealloc_count == 0);
fv.assign( &do_nothing, std::allocator<int>() ); fv.assign( &do_nothing, std::allocator<int>() );
fv.clear(); fv.clear();
function0<void> fv2;
fv.assign(&do_nothing, std::allocator<int>() );
fv2.assign(fv, std::allocator<int>() );
return 0; return 0;
} }

View File

@ -13,8 +13,8 @@
#include <string> #include <string>
#include <utility> #include <utility>
using boost::function; using namespace boost;
using std::string; using namespace std;
int global_int; int global_int;
@ -525,7 +525,7 @@ test_zero_args()
static void static void
test_one_arg() test_one_arg()
{ {
std::negate<int> neg; negate<int> neg;
function<int (int)> f1(neg); function<int (int)> f1(neg);
BOOST_CHECK(f1(5) == -5); BOOST_CHECK(f1(5) == -5);
@ -607,12 +607,12 @@ struct add_with_throw_on_copy {
add_with_throw_on_copy(const add_with_throw_on_copy&) add_with_throw_on_copy(const add_with_throw_on_copy&)
{ {
throw std::runtime_error("But this CAN'T throw"); throw runtime_error("But this CAN'T throw");
} }
add_with_throw_on_copy& operator=(const add_with_throw_on_copy&) add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
{ {
throw std::runtime_error("But this CAN'T throw"); throw runtime_error("But this CAN'T throw");
} }
}; };
@ -621,38 +621,14 @@ test_ref()
{ {
add_with_throw_on_copy atc; add_with_throw_on_copy atc;
try { try {
boost::function<int (int, int)> f(boost::ref(atc)); boost::function<int (int, int)> f(ref(atc));
BOOST_CHECK(f(1, 3) == 4); BOOST_CHECK(f(1, 3) == 4);
} }
catch(std::runtime_error e) { catch(runtime_error e) {
BOOST_ERROR("Nonthrowing constructor threw an exception"); BOOST_ERROR("Nonthrowing constructor threw an exception");
} }
} }
static void dummy() {}
static void test_empty_ref()
{
boost::function<void()> f1;
boost::function<void()> f2(boost::ref(f1));
try {
f2();
BOOST_ERROR("Exception didn't throw for reference to empty function.");
}
catch(std::runtime_error e) {}
f1 = dummy;
try {
f2();
}
catch(std::runtime_error e) {
BOOST_ERROR("Error calling referenced function.");
}
}
static void test_exception() static void test_exception()
{ {
boost::function<int (int, int)> f; boost::function<int (int, int)> f;
@ -698,7 +674,6 @@ int test_main(int, char* [])
test_emptiness(); test_emptiness();
test_member_functions(); test_member_functions();
test_ref(); test_ref();
test_empty_ref();
test_exception(); test_exception();
test_implicit(); test_implicit();
test_call(); test_call();

View File

@ -15,21 +15,21 @@
#include <boost/lambda/bind.hpp> #include <boost/lambda/bind.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>
using namespace std;
using namespace boost;
using namespace boost::lambda;
static unsigned static unsigned
func_impl(int arg1, bool arg2, double arg3) func_impl(int arg1, bool arg2, double arg3)
{ {
using namespace std;
return abs (static_cast<int>((arg2 ? arg1 : 2 * arg1) * arg3)); return abs (static_cast<int>((arg2 ? arg1 : 2 * arg1) * arg3));
} }
int test_main(int, char*[]) int test_main(int, char*[])
{ {
using boost::function;
using namespace boost::lambda;
function <unsigned(bool, double)> f1 = bind(func_impl, 15, _1, _2); function <unsigned(bool, double)> f1 = bind(func_impl, 15, _1, _2);
function <unsigned(double)> f2 = boost::lambda::bind(f1, false, _1); function <unsigned(double)> f2 = bind(f1, false, _1);
function <unsigned()> f3 = boost::lambda::bind(f2, 4.0); function <unsigned()> f3 = bind(f2, 4.0);
f3(); f3();