mirror of
https://github.com/boostorg/function.git
synced 2025-07-06 09:16:35 +02:00
Merge various function changes from trunk.
Merged revisions 49571,50064,51743,51745,53722,54616-54619 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r49571 | noel_belcourt | 2008-11-03 18:37:49 +0000 (Mon, 03 Nov 2008) | 9 lines Both Sun and Pgi on Linux correctly put typeinfo into the std namespace, but function_base keys off the BOOST_NO_EXCEPTION_STD_NAMESPACE macro instead of the BOOST_NO_STD_TYPEINFO macro. The attached patch changes function_base to use the typeinfo macro. Because eVC 4.2 doesn't put typeinfo into the std namespace, I need to define BOOST_NO_STD_TYPEINFO only for this eVC version. ........ r50064 | johnmaddock | 2008-12-02 10:10:46 +0000 (Tue, 02 Dec 2008) | 1 line Fix -Wundef warning and suspect usage of BOOST_STRICT_CONFIG. ........ r51743 | dgregor | 2009-03-13 05:23:53 +0000 (Fri, 13 Mar 2009) | 11 lines Implement an optimization that David Abrahams and myself came up with, where Boost.Function uses a bit in the vtable pointer to indicate when the target function object has a trivial copy constructor, trivial destructor, and fits within the small object buffer. In this case, we just copy the bits of the function object rather than performing an indirect call to the manager. This results in a 60% speedup on a micro-benchmark that copies and calls such function objects repeatedly. ........ r51745 | dgregor | 2009-03-13 05:49:02 +0000 (Fri, 13 Mar 2009) | 7 lines Make Boost.Function compile under BOOST_NO_EXCEPTIONS. Fixes #2499 Fixes #2494 Fixes #2469 Fixes #2466 ........ r53722 | vladimir_prus | 2009-06-07 16:44:50 +0100 (Sun, 07 Jun 2009) | 4 lines Make Boost.Function compile with disabled exceptions. Closes #2900. Patch from Gabi Davar. ........ r54616 | danieljames | 2009-07-03 23:20:26 +0100 (Fri, 03 Jul 2009) | 3 lines When copying boost::ref, copy even when the referenced function is empty. Fixes #2642 Patch by Steven Watanabe ........ r54617 | danieljames | 2009-07-03 23:20:52 +0100 (Fri, 03 Jul 2009) | 6 lines Add 'and later versions' to support info for GCC and Visual C++. Fixes #2847. I didn't explicitly specify the versions since no one's updating this list and it's highly unlikely that a future version will break this. The same could probably be done for the other compilers but I don't know them very well so I'm leaving them alone. ........ r54618 | danieljames | 2009-07-03 23:21:40 +0100 (Fri, 03 Jul 2009) | 4 lines Fix Boost.Function unit tests for C++0x. Fixes #3012 Based on a patch from Richard Webb. Changed a bit so that it also works for the Visual C++ 10 beta. ........ r54619 | danieljames | 2009-07-03 23:22:03 +0100 (Fri, 03 Jul 2009) | 3 lines Work around Visual C++ copy constructor bug. Fixes #2929. Based on the patch by Steven Watanabe. ........ [SVN r54824]
This commit is contained in:
@ -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, 3.1.x</simpara></listitem>
|
<listitem><simpara>GNU C++ 2.95.x, 3.0.x and later verseions</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</simpara></listitem>
|
<listitem><simpara>Microsoft Visual C++ 7.1 and later versions</simpara></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/integer.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||||
#include <boost/type_traits/is_const.hpp>
|
#include <boost/type_traits/is_const.hpp>
|
||||||
#include <boost/type_traits/is_integral.hpp>
|
#include <boost/type_traits/is_integral.hpp>
|
||||||
#include <boost/type_traits/is_volatile.hpp>
|
#include <boost/type_traits/is_volatile.hpp>
|
||||||
@ -42,7 +45,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
|
// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
|
||||||
#ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE
|
#ifdef BOOST_NO_STD_TYPEINFO
|
||||||
// Embedded VC++ does not have type_info in namespace std
|
// Embedded VC++ does not have type_info in namespace std
|
||||||
# define BOOST_FUNCTION_STD_NS
|
# define BOOST_FUNCTION_STD_NS
|
||||||
#else
|
#else
|
||||||
@ -259,6 +262,12 @@ namespace boost {
|
|||||||
A(a)
|
A(a)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
functor_wrapper(const functor_wrapper& f) :
|
||||||
|
F(static_cast<const F&>(f)),
|
||||||
|
A(static_cast<const A&>(f))
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -625,7 +634,7 @@ public:
|
|||||||
if (!vtable) return typeid(void);
|
if (!vtable) return typeid(void);
|
||||||
|
|
||||||
detail::function::function_buffer type;
|
detail::function::function_buffer type;
|
||||||
vtable->manager(functor, type, detail::function::get_functor_type_tag);
|
get_vtable()->manager(functor, type, detail::function::get_functor_type_tag);
|
||||||
return *type.type.type;
|
return *type.type.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +647,7 @@ public:
|
|||||||
type_result.type.type = &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;
|
||||||
vtable->manager(functor, type_result,
|
get_vtable()->manager(functor, type_result,
|
||||||
detail::function::check_functor_type_tag);
|
detail::function::check_functor_type_tag);
|
||||||
return static_cast<Functor*>(type_result.obj_ptr);
|
return static_cast<Functor*>(type_result.obj_ptr);
|
||||||
}
|
}
|
||||||
@ -656,7 +665,7 @@ public:
|
|||||||
type_result.type.type = &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;
|
||||||
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.
|
||||||
@ -702,6 +711,15 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
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 {
|
||||||
|
return reinterpret_cast<detail::function::vtable_base*>(
|
||||||
|
reinterpret_cast<std::size_t>(vtable) & ~(std::size_t)0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_trivial_copy_and_destroy() const {
|
||||||
|
return reinterpret_cast<std::size_t>(vtable) & 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
detail::function::vtable_base* vtable;
|
detail::function::vtable_base* vtable;
|
||||||
mutable detail::function::function_buffer functor;
|
mutable detail::function::function_buffer functor;
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,7 @@ namespace boost { namespace python { namespace objects {
|
|||||||
|
|
||||||
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||||
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|
||||||
|| !(BOOST_STRICT_CONFIG || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
|
|| !(defined(BOOST_STRICT_CONFIG) || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
|
||||||
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
|
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
// 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 )
|
||||||
@ -624,14 +625,10 @@ 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)
|
||||||
{
|
{
|
||||||
if (!boost::detail::function::has_empty_target(f.get_pointer())) {
|
|
||||||
functor.obj_ref.obj_ptr = (void *)f.get_pointer();
|
functor.obj_ref.obj_ptr = (void *)f.get_pointer();
|
||||||
functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
|
functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
|
||||||
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
|
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
template<typename FunctionObj,typename Allocator>
|
template<typename FunctionObj,typename Allocator>
|
||||||
bool
|
bool
|
||||||
@ -678,6 +675,11 @@ namespace boost {
|
|||||||
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
|
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
|
||||||
vtable_type;
|
vtable_type;
|
||||||
|
|
||||||
|
vtable_type* get_vtable() const {
|
||||||
|
return reinterpret_cast<vtable_type*>(
|
||||||
|
reinterpret_cast<std::size_t>(vtable) & ~(std::size_t)0x01);
|
||||||
|
}
|
||||||
|
|
||||||
struct clear_type {};
|
struct clear_type {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -757,7 +759,7 @@ namespace boost {
|
|||||||
if (this->empty())
|
if (this->empty())
|
||||||
boost::throw_exception(bad_function_call());
|
boost::throw_exception(bad_function_call());
|
||||||
|
|
||||||
return static_cast<vtable_type*>(vtable)->invoker
|
return get_vtable()->invoker
|
||||||
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
|
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -781,24 +783,26 @@ namespace boost {
|
|||||||
operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
|
operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
|
||||||
{
|
{
|
||||||
this->clear();
|
this->clear();
|
||||||
try {
|
BOOST_TRY {
|
||||||
this->assign_to(f);
|
this->assign_to(f);
|
||||||
} catch (...) {
|
} BOOST_CATCH (...) {
|
||||||
vtable = 0;
|
vtable = 0;
|
||||||
throw;
|
BOOST_RETHROW;
|
||||||
}
|
}
|
||||||
|
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();
|
||||||
try {
|
BOOST_TRY{
|
||||||
this->assign_to_a(f,a);
|
this->assign_to_a(f,a);
|
||||||
} catch (...) {
|
} BOOST_CATCH (...) {
|
||||||
vtable = 0;
|
vtable = 0;
|
||||||
throw;
|
BOOST_RETHROW;
|
||||||
}
|
}
|
||||||
|
BOOST_CATCH_END
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_NO_SFINAE
|
#ifndef BOOST_NO_SFINAE
|
||||||
@ -823,12 +827,13 @@ namespace boost {
|
|||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
this->clear();
|
this->clear();
|
||||||
try {
|
BOOST_TRY {
|
||||||
this->assign_to_own(f);
|
this->assign_to_own(f);
|
||||||
} catch (...) {
|
} BOOST_CATCH (...) {
|
||||||
vtable = 0;
|
vtable = 0;
|
||||||
throw;
|
BOOST_RETHROW;
|
||||||
}
|
}
|
||||||
|
BOOST_CATCH_END
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,7 +852,8 @@ namespace boost {
|
|||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
if (vtable) {
|
if (vtable) {
|
||||||
reinterpret_cast<vtable_type*>(vtable)->clear(this->functor);
|
if (!this->has_trivial_copy_and_destroy())
|
||||||
|
get_vtable()->clear(this->functor);
|
||||||
vtable = 0;
|
vtable = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -876,7 +882,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
if (!f.empty()) {
|
if (!f.empty()) {
|
||||||
this->vtable = f.vtable;
|
this->vtable = f.vtable;
|
||||||
f.vtable->manager(f.functor, this->functor,
|
if (this->has_trivial_copy_and_destroy())
|
||||||
|
this->functor = f.functor;
|
||||||
|
else
|
||||||
|
get_vtable()->base.manager(f.functor, this->functor,
|
||||||
boost::detail::function::clone_functor_tag);
|
boost::detail::function::clone_functor_tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -903,8 +912,15 @@ namespace boost {
|
|||||||
static vtable_type stored_vtable =
|
static vtable_type stored_vtable =
|
||||||
{ { &manager_type::manage }, &invoker_type::invoke };
|
{ { &manager_type::manage }, &invoker_type::invoke };
|
||||||
|
|
||||||
if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable.base;
|
if (stored_vtable.assign_to(f, functor)) {
|
||||||
else vtable = 0;
|
std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
|
||||||
|
if (boost::has_trivial_copy_constructor<Functor>::value &&
|
||||||
|
boost::has_trivial_destructor<Functor>::value &&
|
||||||
|
detail::function::function_allows_small_object_optimization<Functor>::value)
|
||||||
|
value |= (std::size_t)0x01;
|
||||||
|
vtable = reinterpret_cast<detail::function::vtable_base *>(value);
|
||||||
|
} else
|
||||||
|
vtable = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Functor,typename Allocator>
|
template<typename Functor,typename Allocator>
|
||||||
@ -930,8 +946,15 @@ namespace boost {
|
|||||||
static vtable_type stored_vtable =
|
static vtable_type stored_vtable =
|
||||||
{ { &manager_type::manage }, &invoker_type::invoke };
|
{ { &manager_type::manage }, &invoker_type::invoke };
|
||||||
|
|
||||||
if (stored_vtable.assign_to_a(f, functor, a)) vtable = &stored_vtable.base;
|
if (stored_vtable.assign_to_a(f, functor, a)) {
|
||||||
else vtable = 0;
|
std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
|
||||||
|
if (boost::has_trivial_copy_constructor<Functor>::value &&
|
||||||
|
boost::has_trivial_destructor<Functor>::value &&
|
||||||
|
detail::function::function_allows_small_object_optimization<Functor>::value)
|
||||||
|
value |= (std::size_t)0x01;
|
||||||
|
vtable = reinterpret_cast<detail::function::vtable_base *>(value);
|
||||||
|
} else
|
||||||
|
vtable = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves the value from the specified argument to *this. If the argument
|
// Moves the value from the specified argument to *this. If the argument
|
||||||
@ -942,23 +965,23 @@ namespace boost {
|
|||||||
if (&f == this)
|
if (&f == this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
BOOST_TRY {
|
||||||
try {
|
|
||||||
#endif
|
|
||||||
if (!f.empty()) {
|
if (!f.empty()) {
|
||||||
this->vtable = f.vtable;
|
this->vtable = f.vtable;
|
||||||
f.vtable->manager(f.functor, this->functor,
|
if (this->has_trivial_copy_and_destroy())
|
||||||
|
this->functor = f.functor;
|
||||||
|
else
|
||||||
|
get_vtable()->base.manager(f.functor, this->functor,
|
||||||
boost::detail::function::move_functor_tag);
|
boost::detail::function::move_functor_tag);
|
||||||
f.vtable = 0;
|
f.vtable = 0;
|
||||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
|
||||||
} else {
|
} else {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} BOOST_CATCH (...) {
|
||||||
vtable = 0;
|
vtable = 0;
|
||||||
throw;
|
BOOST_RETHROW;
|
||||||
}
|
}
|
||||||
#endif
|
BOOST_CATCH_END
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -979,13 +1002,14 @@ namespace boost {
|
|||||||
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
|
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
|
||||||
typename BOOST_FUNCTION_FUNCTION<
|
typename BOOST_FUNCTION_FUNCTION<
|
||||||
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
|
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
|
||||||
|
inline
|
||||||
BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
|
BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
|
||||||
::operator()(BOOST_FUNCTION_PARMS) const
|
::operator()(BOOST_FUNCTION_PARMS) const
|
||||||
{
|
{
|
||||||
if (this->empty())
|
if (this->empty())
|
||||||
boost::throw_exception(bad_function_call());
|
boost::throw_exception(bad_function_call());
|
||||||
|
|
||||||
return reinterpret_cast<const vtable_type*>(vtable)->invoker
|
return get_vtable()->invoker
|
||||||
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
|
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -129,5 +129,9 @@ test_main(int, char*[])
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using namespace boost;
|
using boost::function;
|
||||||
using namespace std;
|
using std::string;
|
||||||
|
|
||||||
int global_int;
|
int global_int;
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ test_zero_args()
|
|||||||
static void
|
static void
|
||||||
test_one_arg()
|
test_one_arg()
|
||||||
{
|
{
|
||||||
negate<int> neg;
|
std::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 runtime_error("But this CAN'T throw");
|
throw std::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 runtime_error("But this CAN'T throw");
|
throw std::runtime_error("But this CAN'T throw");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -621,14 +621,38 @@ test_ref()
|
|||||||
{
|
{
|
||||||
add_with_throw_on_copy atc;
|
add_with_throw_on_copy atc;
|
||||||
try {
|
try {
|
||||||
boost::function<int (int, int)> f(ref(atc));
|
boost::function<int (int, int)> f(boost::ref(atc));
|
||||||
BOOST_CHECK(f(1, 3) == 4);
|
BOOST_CHECK(f(1, 3) == 4);
|
||||||
}
|
}
|
||||||
catch(runtime_error e) {
|
catch(std::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;
|
||||||
@ -674,6 +698,7 @@ 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();
|
||||||
|
@ -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 = bind(f1, false, _1);
|
function <unsigned(double)> f2 = boost::lambda::bind(f1, false, _1);
|
||||||
function <unsigned()> f3 = bind(f2, 4.0);
|
function <unsigned()> f3 = boost::lambda::bind(f2, 4.0);
|
||||||
|
|
||||||
f3();
|
f3();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user