Compare commits

...

11 Commits

Author SHA1 Message Date
8a4a73fa56 Branch for merging Boost.Build and Boost.Jam completely.
[SVN r59143]
2010-01-19 20:47:20 +00:00
22c6592a40 Fix function_base.hpp to not require typeid. Refs #3666. Requires [58127].
[SVN r58128]
2009-12-03 20:59:32 +00:00
a1f62de420 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
81c7876588 Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
2020d39e2c Fix a typo.
[SVN r54909]
2009-07-12 15:53:54 +00:00
8b63c146ea Work around Visual C++ copy constructor bug. Fixes #2929.
Based on the patch by Steven Watanabe.

[SVN r54619]
2009-07-03 22:22:03 +00:00
ae534d7342 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.

[SVN r54618]
2009-07-03 22:21:40 +00:00
e8247198fa 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.

[SVN r54617]
2009-07-03 22:20:52 +00:00
ff3244d562 When copying boost::ref, copy even when the referenced function is empty. Fixes #2642
Patch by Steven Watanabe

[SVN r54616]
2009-07-03 22:20:26 +00:00
68128bfffa Make Boost.Function compile with disabled exceptions.
Closes #2900. Patch from Gabi Davar.


[SVN r53722]
2009-06-07 15:44:50 +00:00
e10f4eaef9 Add missing #pragma warning(pop). Fixes #2767.
[SVN r53694]
2009-06-06 15:31:47 +00:00
10 changed files with 102 additions and 112 deletions

View File

@ -1,22 +0,0 @@
#----------------------------------------------------------------------------
# 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
)

View File

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

View File

@ -35,12 +35,12 @@ form to use for your compiler.
<row>
<entry>
<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 versions</simpara></listitem>
<listitem><simpara>Comeau C++ 4.2.45.2</simpara></listitem>
<listitem><simpara>SGI MIPSpro 7.3.0</simpara></listitem>
<listitem><simpara>Intel C++ 5.0, 6.0</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>
</entry>
<entry>

View File

@ -15,8 +15,8 @@
#include <string>
#include <memory>
#include <new>
#include <typeinfo>
#include <boost/config.hpp>
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/assert.hpp>
#include <boost/integer.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
@ -54,7 +54,9 @@
// Borrowed from Boost.Python library: determines the cases where we
// need to use std::type_info::name to compare instead of operator==.
# if (defined(__GNUC__) && __GNUC__ >= 3) \
#if defined( BOOST_NO_TYPEID )
# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
#elif (defined(__GNUC__) && __GNUC__ >= 3) \
|| defined(_AIX) \
|| ( defined(__sgi) && defined(__host_mips))
# include <cstring>
@ -103,7 +105,7 @@ namespace boost {
// For pointers to std::type_info objects
struct type_t {
// (get_functor_type_tag, check_functor_type_tag).
const BOOST_FUNCTION_STD_NS::type_info* type;
const detail::sp_typeinfo* type;
// Whether the type is const-qualified.
bool const_qualified;
@ -215,12 +217,12 @@ namespace boost {
case check_functor_type_tag:
{
const BOOST_FUNCTION_STD_NS::type_info& check_type
const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
// Check whether we have the same type. We can add
// cv-qualifiers, but we can't take them away.
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F))
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(F))
&& (!in_buffer.obj_ref.is_const_qualified
|| out_buffer.type.const_qualified)
&& (!in_buffer.obj_ref.is_volatile_qualified
@ -232,7 +234,7 @@ namespace boost {
return;
case get_functor_type_tag:
out_buffer.type.type = &typeid(F);
out_buffer.type.type = &BOOST_SP_TYPEID(F);
out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified;
out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified;
return;
@ -262,6 +264,12 @@ namespace boost {
A(a)
{
}
functor_wrapper(const functor_wrapper& f) :
F(static_cast<const F&>(f)),
A(static_cast<const A&>(f))
{
}
};
/**
@ -286,14 +294,14 @@ namespace boost {
} else if (op == destroy_functor_tag)
out_buffer.func_ptr = 0;
else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
out_buffer.obj_ptr = &in_buffer.func_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
@ -316,14 +324,14 @@ namespace boost {
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor();
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
out_buffer.obj_ptr = &in_buffer.data;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
@ -375,14 +383,14 @@ namespace boost {
delete f;
out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
@ -417,7 +425,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) {
case get_functor_type_tag:
out_buffer.type.type = &typeid(functor_type);
out_buffer.type.type = &BOOST_SP_TYPEID(functor_type);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
return;
@ -486,14 +494,14 @@ namespace boost {
wrapper_allocator.deallocate(victim,1);
out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
const detail::sp_typeinfo& check_type
= *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
@ -520,7 +528,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) {
case get_functor_type_tag:
out_buffer.type.type = &typeid(functor_type);
out_buffer.type.type = &BOOST_SP_TYPEID(functor_type);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
return;
@ -621,11 +629,11 @@ public:
/** Determine if the function is empty (i.e., has no target). */
bool empty() const { return !vtable; }
/** Retrieve the type of the stored function object, or typeid(void)
/** Retrieve the type of the stored function object, or BOOST_SP_TYPEID(void)
if this is empty. */
const BOOST_FUNCTION_STD_NS::type_info& target_type() const
const detail::sp_typeinfo& target_type() const
{
if (!vtable) return typeid(void);
if (!vtable) return BOOST_SP_TYPEID(void);
detail::function::function_buffer type;
get_vtable()->manager(functor, type, detail::function::get_functor_type_tag);
@ -638,7 +646,7 @@ public:
if (!vtable) return 0;
detail::function::function_buffer type_result;
type_result.type.type = &typeid(Functor);
type_result.type.type = &BOOST_SP_TYPEID(Functor);
type_result.type.const_qualified = is_const<Functor>::value;
type_result.type.volatile_qualified = is_volatile<Functor>::value;
get_vtable()->manager(functor, type_result,
@ -656,7 +664,7 @@ public:
if (!vtable) return 0;
detail::function::function_buffer type_result;
type_result.type.type = &typeid(Functor);
type_result.type.type = &BOOST_SP_TYPEID(Functor);
type_result.type.const_qualified = true;
type_result.type.volatile_qualified = is_volatile<Functor>::value;
get_vtable()->manager(functor, type_result,
@ -889,4 +897,8 @@ namespace detail {
#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
#undef BOOST_FUNCTION_COMPARE_TYPE_ID
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif
#endif // BOOST_FUNCTION_BASE_HEADER

View File

@ -11,6 +11,7 @@
// Note: this header is a header template and must NOT have multiple-inclusion
// protection.
#include <boost/function/detail/prologue.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#if defined(BOOST_MSVC)
# pragma warning( push )
@ -624,14 +625,10 @@ namespace boost {
assign_to(const reference_wrapper<FunctionObj>& f,
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.is_const_qualified = is_const<FunctionObj>::value;
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
return true;
} else {
return false;
}
functor.obj_ref.obj_ptr = (void *)f.get_pointer();
functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
return true;
}
template<typename FunctionObj,typename Allocator>
bool
@ -786,24 +783,26 @@ namespace boost {
operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
{
this->clear();
try {
BOOST_TRY {
this->assign_to(f);
} catch (...) {
} BOOST_CATCH (...) {
vtable = 0;
throw;
BOOST_RETHROW;
}
BOOST_CATCH_END
return *this;
}
template<typename Functor,typename Allocator>
void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
{
this->clear();
try {
BOOST_TRY{
this->assign_to_a(f,a);
} catch (...) {
} BOOST_CATCH (...) {
vtable = 0;
throw;
BOOST_RETHROW;
}
BOOST_CATCH_END
}
#ifndef BOOST_NO_SFINAE
@ -828,12 +827,13 @@ namespace boost {
return *this;
this->clear();
try {
BOOST_TRY {
this->assign_to_own(f);
} catch (...) {
} BOOST_CATCH (...) {
vtable = 0;
throw;
BOOST_RETHROW;
}
BOOST_CATCH_END
return *this;
}
@ -965,9 +965,7 @@ namespace boost {
if (&f == this)
return;
#if !defined(BOOST_NO_EXCEPTIONS)
try {
#endif
BOOST_TRY {
if (!f.empty()) {
this->vtable = f.vtable;
if (this->has_trivial_copy_and_destroy())
@ -979,12 +977,11 @@ namespace boost {
} else {
clear();
}
#if !defined(BOOST_NO_EXCEPTIONS)
} catch (...) {
} BOOST_CATCH (...) {
vtable = 0;
throw;
BOOST_RETHROW;
}
#endif
BOOST_CATCH_END
}
};

View File

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

View File

@ -1,23 +0,0 @@
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

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

View File

@ -13,8 +13,8 @@
#include <string>
#include <utility>
using namespace boost;
using namespace std;
using boost::function;
using std::string;
int global_int;
@ -525,7 +525,7 @@ test_zero_args()
static void
test_one_arg()
{
negate<int> neg;
std::negate<int> neg;
function<int (int)> f1(neg);
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&)
{
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&)
{
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;
try {
boost::function<int (int, int)> f(ref(atc));
boost::function<int (int, int)> f(boost::ref(atc));
BOOST_CHECK(f(1, 3) == 4);
}
catch(runtime_error e) {
catch(std::runtime_error e) {
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()
{
boost::function<int (int, int)> f;
@ -674,6 +698,7 @@ int test_main(int, char* [])
test_emptiness();
test_member_functions();
test_ref();
test_empty_ref();
test_exception();
test_implicit();
test_call();

View File

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