forked from boostorg/function
Compare commits
11 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
8a4a73fa56 | |||
22c6592a40 | |||
a1f62de420 | |||
81c7876588 | |||
2020d39e2c | |||
8b63c146ea | |||
ae534d7342 | |||
e8247198fa | |||
ff3244d562 | |||
68128bfffa | |||
e10f4eaef9 |
@ -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
|
||||
)
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
boost_add_documentation(function.xml
|
||||
faq.xml history.xml misc.xml reference.xml tests.xml tutorial.xml)
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
boost_module(function DEPENDS detail preprocessor utility)
|
@ -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)
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
Reference in New Issue
Block a user