mirror of
https://github.com/boostorg/function.git
synced 2025-07-02 15:30:59 +02:00
Compare commits
1 Commits
boost-1.25
...
boost-1.25
Author | SHA1 | Date | |
---|---|---|---|
9d940f27df |
@ -15,10 +15,8 @@
|
||||
<b>namespace</b> boost {
|
||||
<b>class</b> <a href="#function_base">function_base</a>
|
||||
{
|
||||
<b>typedef</b> <em>implementation-defined</em> safe_bool;
|
||||
<a href="#empty"><b>bool</b> empty() <b>const</b></a>;
|
||||
<a href="#bool"><b>operator</b> safe_bool() <b>const</b></a>;
|
||||
<a href="#not">safe_bool <b>operator!</b>() <b>const</b></a>;
|
||||
<a href="#bool"><b>operator</b> <b>bool</b>() <b>const</b></a>;
|
||||
};
|
||||
|
||||
// For <i>N</i> in [0, <i>MAX_ARGS</i>]
|
||||
@ -67,8 +65,8 @@
|
||||
<b>typename</b> Policy,
|
||||
<b>typename</b> Mixin,
|
||||
<b>typename</b> Allocator>
|
||||
<b>void</b> <a href="#swap_functionN">swap</a>(<b>const</b> function<em>N</em><Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b>,
|
||||
<b>const</b> function<em>N</em><Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b>);
|
||||
<b>void</b> <a href="#swap_functionN">swap</a>(<b>const</b> function<Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b>,
|
||||
<b>const</b> function<Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b>);
|
||||
|
||||
// For any <i>N</i> in [0, <i>MAX_ARGS</i>]
|
||||
<b>template</b><<b>typename</b> ResultType,
|
||||
@ -107,43 +105,6 @@
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2>Definitions</h2>
|
||||
<p>
|
||||
<ul>
|
||||
<li><a name="compatible"></a>A function object <code>f</code> is <em>compatible</em> if for the given set of argument types <code>Arg1</code>, <code>Arg2</code>, ..., <code>Arg<em>N</em></code> and a return type <code>ResultType</code>, the appropriate following function is well-formed:
|
||||
<pre>
|
||||
<em>// if ResultType is not <b>void</b></em>
|
||||
ResultType foo(Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>)
|
||||
{
|
||||
<b>return</b> f(arg1, arg2, ..., arg<em>N</em>);
|
||||
}
|
||||
|
||||
<em>// if ResultType is <b>void</b></em>
|
||||
ResultType foo(Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>)
|
||||
{
|
||||
f(arg1, arg2, ..., arg<em>N</em>);
|
||||
}
|
||||
</pre>
|
||||
<p> A special provision is made for pointers to member functions. Though they are not function objects, Boost.Function will adapt them internally to function objects. This requires that a pointer to member function of the form <code>R (X::*mf)(Arg1, Arg2, ..., Arg<em>N</em>) <em>cv-quals</em></code> be adapted to a function object with the following function call operator overloads:
|
||||
<pre>
|
||||
R <b>operator</b>()(<em>cv-quals</em> X& x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
|
||||
{
|
||||
<b>return</b> x.*mf(arg1, arg2, ..., arg<em>N</em>);
|
||||
}
|
||||
|
||||
R <b>operator</b>()(<em>cv-quals</em> X* x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
|
||||
{
|
||||
<b>return</b> x->*mf(arg1, arg2, ..., arg<em>N</em>);
|
||||
}
|
||||
|
||||
<b>template</b><<b>typename P</b>>
|
||||
R <b>operator</b>()(<em>cv-quals</em> P& x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
|
||||
{
|
||||
<b>return</b> (*x).*mf(arg1, arg2, ..., arg<em>N</em>);
|
||||
}
|
||||
</pre>
|
||||
</ul>
|
||||
|
||||
<h2><a name="function_base">Class <code>function_base</code></a></h2>
|
||||
<p> Class <code>function_base</code> is the common base class for all Boost.Function objects. Objects of type <code>function_base</code> may not be created directly.
|
||||
|
||||
@ -153,18 +114,10 @@
|
||||
<li><b>Throws</b>: will not throw.</li>
|
||||
</ul>
|
||||
|
||||
<p> <a name="bool"><code><b>operator</b> safe_bool() <b>const</b></code></a>
|
||||
<p> <a name="bool"><code><b>operator</b> <b>bool</b>() <b>const</b></code></a>
|
||||
<ul>
|
||||
<li><b>Returns</b>: <code>safe_bool</code> equivalent of <code>!<a href="#empty">empty</a>()</code></li>
|
||||
<li><b>Returns</b>: <code>!<a href="#empty">empty</a>()</code></li>
|
||||
<li><b>Throws</b>: will not throw.</li>
|
||||
<li><b>Notes</b>: The <code>safe_bool</code> type can be used in contexts where a <b>bool</b> is expected (e.g., an <b>if</b> condition); however, implicit conversions (e.g., to <b>int</b>) that can occur with <b>bool</b> are not allowed, eliminating some sources of user error.
|
||||
</ul>
|
||||
|
||||
<p> <a name="not"><code>safe_bool <b>operator!</b>() <b>const</b></code></a>
|
||||
<ul>
|
||||
<li><b>Returns</b>: <code>safe_bool</code> equivalent of <code><a href="#empty">empty</a>()</code></li>
|
||||
<li><b>Throws</b>: will not throw.</li>
|
||||
<li><b>Notes</b>: See <a href="#bool"><code>safe_bool</code> conversion</a>
|
||||
</ul>
|
||||
|
||||
<h2><a name="functionN">Class template <code>function<i>N</i></code></a></h2>
|
||||
@ -184,7 +137,7 @@
|
||||
|
||||
<p> <a name="functionN_target"><code><b>template</b><<b>typename</b> F> function<i>N</i>(<b>const</b> F<b>&</b> g, <b>const</b> Mixin<b>&</b> = Mixin());</code></a>
|
||||
<ul>
|
||||
<li><b>Requires</b>: <code>g</code> is a <a href="#compatible">compatible</a> function object.</li>
|
||||
<li><b>Requires</b>: <code>g</code> is a compatible function object.</li>
|
||||
<li><b>Effects</b>: Constructs the <code>Mixin</code> subobject from the given mixin.</li>
|
||||
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li>
|
||||
<li><b>Rationale</b>: <code>g</code> is a reference-to-<code><b>const</b></code> because it is a portable, efficient, and concise way to accept any function object or function pointer. In the case of a function pointer, the type of <code>g</code> is reference-to-<code><b>const</b></code> pointer-to-function.</li>
|
||||
@ -198,7 +151,7 @@
|
||||
|
||||
<p> <a name="functionN_target_assn"><code><b>template</b><<b>typename</b> F> function<i>N</i><b>&</b> <b>operator</b>=(<b>const</b> F<b>&</b> g);</code></a>
|
||||
<ul>
|
||||
<li><b>Requires</b>: <code>g</code> is a <a href="#compatible">compatible</a> function object.</li>
|
||||
<li><b>Requires</b>: <code>g</code> is a compatible function object.</li>
|
||||
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li>
|
||||
<li><b>Returns</b>: <code>*this</code>.</li>
|
||||
<li><b>Rationale</b>: <code>g</code> is a reference-to-<code><b>const</b></code> because it is a portable, efficient, and concise way to accept any function object or function pointer. In the case of a function pointer, the type of <code>g</code> is reference-to-<code><b>const</b></code> pointer-to-function.</li>
|
||||
@ -280,7 +233,7 @@
|
||||
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
|
||||
<!-- Created: Fri Jul 13 10:57:20 EDT 2001 -->
|
||||
<!-- hhmts start -->
|
||||
Last modified: Sun Oct 28 00:40:55 EDT 2001
|
||||
Last modified: Sun Jul 22 01:29:50 EDT 2001
|
||||
<!-- hhmts end -->
|
||||
</body>
|
||||
</html>
|
||||
|
@ -66,22 +66,8 @@ else
|
||||
<h3>Member functions</h3>
|
||||
<a name="member_func">
|
||||
<p> In many systems, callbacks often call to member functions of a particular
|
||||
object. This is often referred to as "argument binding", and is beyond the scope of Boost.Function. The use of member functions directly, however, is supported, so the following code is valid:
|
||||
<pre>
|
||||
struct X {
|
||||
int foo(int);
|
||||
};
|
||||
|
||||
boost::function<int, X*, int> f;
|
||||
f = &X::foo;
|
||||
|
||||
X x;
|
||||
f(&x, 5);
|
||||
</pre>
|
||||
<p> Several libraries exist that support argument binding. Three such libraries are summarized below:
|
||||
object. Handling argument binding is beyond the scope of Boost.Function. However, there are several libraries that perform 'argument binding', including
|
||||
<ul>
|
||||
<li> <a href="../../bind/bind.html">Boost.Bind</a>. This library allows binding of arguments for any function object. It is lightweight and very portable.</li>
|
||||
|
||||
<li> The C++ Standard library. Using <code>std::bind1st</code> and <code>std::mem_fun</code> together one can bind the object of a pointer-to-member function for use with Boost.Function:
|
||||
<pre>
|
||||
struct X {
|
||||
@ -95,6 +81,8 @@ object. This is often referred to as "argument binding", and is beyond the scope
|
||||
f(5); // Call x.foo(5)</pre></li>
|
||||
|
||||
<li><a href="http://lambda.cs.utu.fi/">The Lambda library</a>. This library provides a powerful composition mechanism to construct function objects that uses very natural C++ syntax. Lambda requires a compiler that is reasonably conformant to the C++ standard. Note that it is not a Boost library.</li>
|
||||
|
||||
<li>Peter Dimov's <a href="http://groups.yahoo.com/group/boost/files/bind/bind.hpp">bind</a> library. It has a smaller scope than the Lambda Library but is more tolerant of broken compilers. It is an unreviewed library in development.</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="family">The <code>function</code> family</a></h2>
|
||||
@ -173,7 +161,7 @@ boost::function2<float, int, int, SynchronizedPolicy, SynchronizedMixin> f
|
||||
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
|
||||
<!-- Created: Fri Jul 13 12:47:11 EDT 2001 -->
|
||||
<!-- hhmts start -->
|
||||
Last modified: Sun Oct 28 00:49:02 EDT 2001
|
||||
Last modified: Fri Jul 13 23:58:17 EDT 2001
|
||||
<!-- hhmts end -->
|
||||
</body>
|
||||
</html>
|
||||
|
@ -19,11 +19,8 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <typeinfo>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/mem_fn.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
@ -81,11 +78,9 @@ namespace boost {
|
||||
union any_pointer
|
||||
{
|
||||
void* obj_ptr;
|
||||
const void* const_obj_ptr;
|
||||
void (*func_ptr)();
|
||||
|
||||
explicit any_pointer(void* p) : obj_ptr(p) {}
|
||||
explicit any_pointer(const void* p) : const_obj_ptr(p) {}
|
||||
explicit any_pointer(void (*p)()) : func_ptr(p) {}
|
||||
};
|
||||
|
||||
@ -114,29 +109,11 @@ namespace boost {
|
||||
};
|
||||
|
||||
// The operation type to perform on the given functor/function pointer
|
||||
enum functor_manager_operation_type {
|
||||
clone_functor,
|
||||
destroy_functor,
|
||||
retrieve_type_info
|
||||
};
|
||||
enum functor_manager_operation_type { clone_functor, destroy_functor };
|
||||
|
||||
// Tags used to decide between different types of functions
|
||||
// Tags used to decide between function and function object pointers.
|
||||
struct function_ptr_tag {};
|
||||
struct function_obj_tag {};
|
||||
struct member_ptr_tag {};
|
||||
|
||||
template<typename F>
|
||||
class get_function_tag
|
||||
{
|
||||
typedef typename IF<(is_pointer<F>::value),
|
||||
function_ptr_tag,
|
||||
function_obj_tag>::type ptr_or_obj_tag;
|
||||
|
||||
public:
|
||||
typedef typename IF<(is_member_pointer<F>::value),
|
||||
member_ptr_tag,
|
||||
ptr_or_obj_tag>::type type;
|
||||
};
|
||||
|
||||
#ifndef BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
|
||||
/**
|
||||
@ -163,10 +140,8 @@ namespace boost {
|
||||
{
|
||||
if (op == clone_functor)
|
||||
return function_ptr;
|
||||
else if (op == destroy_functor)
|
||||
return any_pointer(static_cast<void (*)()>(0));
|
||||
else
|
||||
return any_pointer(&typeid(Functor));
|
||||
return any_pointer(static_cast<void (*)()>(0));
|
||||
}
|
||||
|
||||
// For function object pointers, we clone the pointer to each
|
||||
@ -196,7 +171,7 @@ namespace boost {
|
||||
# endif // BOOST_NO_STD_ALLOCATOR
|
||||
return any_pointer(static_cast<void*>(new_f));
|
||||
}
|
||||
else if (op == destroy_functor) {
|
||||
else {
|
||||
/* Cast from the void pointer to the functor pointer type */
|
||||
functor_type* f =
|
||||
reinterpret_cast<functor_type*>(function_obj_ptr.obj_ptr);
|
||||
@ -215,10 +190,8 @@ namespace boost {
|
||||
|
||||
return any_pointer(static_cast<void*>(0));
|
||||
}
|
||||
else {
|
||||
return any_pointer(&typeid(Functor));
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/* Dispatch to an appropriate manager based on whether we have a
|
||||
function pointer or a function object pointer. */
|
||||
|
@ -28,13 +28,6 @@
|
||||
# define BOOST_FUNCTION_INIT , invoker(0)
|
||||
#endif // BOOST_FUNCTION_USE_VIRTUAL_FUNCTIONS
|
||||
|
||||
// Type of the default allocator
|
||||
#ifndef BOOST_NO_STD_ALLOCATOR
|
||||
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>
|
||||
#else
|
||||
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR int
|
||||
#endif // BOOST_NO_STD_ALLOCATOR
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
namespace function {
|
||||
@ -114,7 +107,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
private:
|
||||
mutable FunctionPtr function_ptr;
|
||||
FunctionPtr function_ptr;
|
||||
#else
|
||||
static R invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA
|
||||
BOOST_FUNCTION_PARMS)
|
||||
@ -191,7 +184,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
private:
|
||||
mutable FunctionPtr function_ptr;
|
||||
FunctionPtr function_ptr;
|
||||
# else
|
||||
static unusable invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA
|
||||
BOOST_FUNCTION_PARMS)
|
||||
@ -424,7 +417,7 @@ namespace boost {
|
||||
BOOST_FUNCTION_TEMPLATE_PARMS,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
|
||||
typename Allocator = std::allocator<function_base>
|
||||
>
|
||||
class BOOST_FUNCTION_FUNCTION : public function_base, public Mixin
|
||||
{
|
||||
@ -619,16 +612,12 @@ namespace boost {
|
||||
template<typename Functor>
|
||||
void assign_to(const Functor& f)
|
||||
{
|
||||
typedef typename detail::function::get_function_tag<Functor>::type tag;
|
||||
typedef typename detail::function::IF<(is_pointer<Functor>::value),
|
||||
detail::function::function_ptr_tag,
|
||||
detail::function::function_obj_tag>::type tag;
|
||||
this->assign_to(f, tag());
|
||||
}
|
||||
|
||||
template<typename MemberPtr>
|
||||
void assign_to(MemberPtr f, detail::function::member_ptr_tag)
|
||||
{
|
||||
this->assign_to(mem_fn(f));
|
||||
}
|
||||
|
||||
template<typename FunctionPtr>
|
||||
void assign_to(FunctionPtr f, detail::function::function_ptr_tag)
|
||||
{
|
||||
@ -734,9 +723,8 @@ namespace boost {
|
||||
>& f2)
|
||||
{
|
||||
f1.swap(f2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup after ourselves...
|
||||
#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
|
||||
#undef BOOST_FUNCTION_INIT
|
||||
|
56
test/defarg_test.cpp
Normal file
56
test/defarg_test.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
// Boost.Function library
|
||||
|
||||
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
static int sub_ints(int x = 5, int y = 3, int z = 1) { return x-y-z; }
|
||||
|
||||
static void
|
||||
test_zero_args()
|
||||
{
|
||||
function<int> one(&sub_ints);
|
||||
BOOST_TEST(one() == 1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_one_arg()
|
||||
{
|
||||
function<int, int> minus_four(&sub_ints);
|
||||
BOOST_TEST(minus_four(7) == 3);
|
||||
}
|
||||
|
||||
static void
|
||||
test_two_args()
|
||||
{
|
||||
function<int, int, int> sub(&sub_ints);
|
||||
BOOST_TEST(sub(10, 2) == 7);
|
||||
}
|
||||
|
||||
int
|
||||
test_main(int, char* [])
|
||||
{
|
||||
test_zero_args();
|
||||
test_one_arg();
|
||||
test_two_args();
|
||||
return 0;
|
||||
}
|
@ -44,15 +44,6 @@ struct write_const_1_nonconst_2
|
||||
void operator()() const { global_int = 1; }
|
||||
};
|
||||
|
||||
struct add_to_obj
|
||||
{
|
||||
add_to_obj(int v) : value(v) {}
|
||||
|
||||
int operator()(int x) const { return value + x; }
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
static void
|
||||
test_zero_args()
|
||||
{
|
||||
@ -536,15 +527,8 @@ test_one_arg()
|
||||
function1<string, string> id(&identity_str);
|
||||
BOOST_TEST(id("str") == "str");
|
||||
|
||||
function1<std::string, const char*> id2(&identity_str);
|
||||
function1<std::string, char*> id2(&identity_str);
|
||||
BOOST_TEST(id2("foo") == "foo");
|
||||
|
||||
add_to_obj add_to(5);
|
||||
function1<int, int> f2(add_to);
|
||||
BOOST_TEST(f2(3) == 8);
|
||||
|
||||
const function1<int, int> cf2(add_to);
|
||||
BOOST_TEST(cf2(3) == 8);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -572,37 +556,6 @@ test_emptiness()
|
||||
BOOST_TEST(f3.empty());
|
||||
}
|
||||
|
||||
struct X {
|
||||
X(int v) : value(v) {}
|
||||
|
||||
int twice() const { return 2*value; }
|
||||
int plus(int v) { return value + v; }
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
static void
|
||||
test_member_functions()
|
||||
{
|
||||
boost::function1<int, X*> f1(&X::twice);
|
||||
|
||||
X one(1);
|
||||
X five(5);
|
||||
|
||||
BOOST_TEST(f1(&one) == 2);
|
||||
BOOST_TEST(f1(&five) == 10);
|
||||
|
||||
boost::function1<int, X*> f1_2;
|
||||
f1_2 = &X::twice;
|
||||
|
||||
BOOST_TEST(f1_2(&one) == 2);
|
||||
BOOST_TEST(f1_2(&five) == 10);
|
||||
|
||||
boost::function2<int, X&, int> f2(&X::plus);
|
||||
BOOST_TEST(f2(one, 3) == 4);
|
||||
BOOST_TEST(f2(five, 4) == 9);
|
||||
}
|
||||
|
||||
int
|
||||
test_main(int, char* [])
|
||||
{
|
||||
@ -610,6 +563,5 @@ test_main(int, char* [])
|
||||
test_one_arg();
|
||||
test_two_args();
|
||||
test_emptiness();
|
||||
test_member_functions();
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,15 +44,6 @@ struct write_const_1_nonconst_2
|
||||
void operator()() const { global_int = 1; }
|
||||
};
|
||||
|
||||
struct add_to_obj
|
||||
{
|
||||
add_to_obj(int v) : value(v) {}
|
||||
|
||||
int operator()(int x) const { return value + x; }
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
static void
|
||||
test_zero_args()
|
||||
{
|
||||
@ -536,15 +527,8 @@ test_one_arg()
|
||||
function<string, string> id(&identity_str);
|
||||
BOOST_TEST(id("str") == "str");
|
||||
|
||||
function<std::string, const char*> id2(&identity_str);
|
||||
function<std::string, char*> id2(&identity_str);
|
||||
BOOST_TEST(id2("foo") == "foo");
|
||||
|
||||
add_to_obj add_to(5);
|
||||
function<int, int> f2(add_to);
|
||||
BOOST_TEST(f2(3) == 8);
|
||||
|
||||
const function<int, int> cf2(add_to);
|
||||
BOOST_TEST(cf2(3) == 8);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -572,37 +556,6 @@ test_emptiness()
|
||||
BOOST_TEST(f3.empty());
|
||||
}
|
||||
|
||||
struct X {
|
||||
X(int v) : value(v) {}
|
||||
|
||||
int twice() const { return 2*value; }
|
||||
int plus(int v) { return value + v; }
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
static void
|
||||
test_member_functions()
|
||||
{
|
||||
boost::function<int, X*> f1(&X::twice);
|
||||
|
||||
X one(1);
|
||||
X five(5);
|
||||
|
||||
BOOST_TEST(f1(&one) == 2);
|
||||
BOOST_TEST(f1(&five) == 10);
|
||||
|
||||
boost::function<int, X*> f1_2;
|
||||
f1_2 = &X::twice;
|
||||
|
||||
BOOST_TEST(f1_2(&one) == 2);
|
||||
BOOST_TEST(f1_2(&five) == 10);
|
||||
|
||||
boost::function<int, X&, int> f2(&X::plus);
|
||||
BOOST_TEST(f2(one, 3) == 4);
|
||||
BOOST_TEST(f2(five, 4) == 9);
|
||||
}
|
||||
|
||||
int
|
||||
test_main(int, char* [])
|
||||
{
|
||||
@ -610,6 +563,5 @@ test_main(int, char* [])
|
||||
test_one_arg();
|
||||
test_two_args();
|
||||
test_emptiness();
|
||||
test_member_functions();
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
|
||||
run libs/function/test/allocator_test.cpp
|
||||
run libs/function/test/defarg_test.cpp
|
||||
run libs/function/test/function_n_test.cpp
|
||||
run libs/function/test/function_test.cpp
|
||||
compile-fail libs/function/test/function_test_fail1.cpp
|
||||
|
Reference in New Issue
Block a user