2001-06-22 14:13:03 +00:00
|
|
|
// Boost.Function library
|
|
|
|
|
2003-10-01 04:10:37 +00:00
|
|
|
// Copyright Doug Gregor 2001-2003. Use, modification and
|
|
|
|
// distribution is subject to the Boost Software License, Version
|
|
|
|
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
|
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
2001-06-22 14:13:03 +00:00
|
|
|
|
|
|
|
// For more information, see http://www.boost.org
|
|
|
|
|
2002-11-09 16:02:47 +00:00
|
|
|
#include <boost/test/minimal.hpp>
|
2001-06-21 17:01:43 +00:00
|
|
|
#include <boost/function.hpp>
|
|
|
|
#include <functional>
|
|
|
|
#include <cassert>
|
|
|
|
#include <string>
|
2002-11-04 18:19:01 +00:00
|
|
|
#include <utility>
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
using namespace boost;
|
2002-08-05 06:13:32 +00:00
|
|
|
using namespace std;
|
2001-06-21 17:01:43 +00:00
|
|
|
|
2001-07-22 05:03:43 +00:00
|
|
|
int global_int;
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
struct write_five_obj { void operator()() const { global_int = 5; } };
|
|
|
|
struct write_three_obj { int operator()() const { global_int = 3; return 7; }};
|
|
|
|
static void write_five() { global_int = 5; }
|
|
|
|
static void write_three() { global_int = 3; }
|
|
|
|
struct generate_five_obj { int operator()() const { return 5; } };
|
|
|
|
struct generate_three_obj { int operator()() const { return 3; } };
|
|
|
|
static int generate_five() { return 5; }
|
|
|
|
static int generate_three() { return 3; }
|
|
|
|
static string identity_str(const string& s) { return s; }
|
|
|
|
static string string_cat(const string& s1, const string& s2) { return s1+s2; }
|
|
|
|
static int sum_ints(int x, int y) { return x+y; }
|
|
|
|
|
|
|
|
struct write_const_1_nonconst_2
|
|
|
|
{
|
|
|
|
void operator()() { global_int = 2; }
|
|
|
|
void operator()() const { global_int = 1; }
|
|
|
|
};
|
|
|
|
|
2001-10-08 13:33:14 +00:00
|
|
|
struct add_to_obj
|
|
|
|
{
|
|
|
|
add_to_obj(int v) : value(v) {}
|
|
|
|
|
|
|
|
int operator()(int x) const { return value + x; }
|
|
|
|
|
|
|
|
int value;
|
|
|
|
};
|
|
|
|
|
2001-06-21 17:01:43 +00:00
|
|
|
static void
|
|
|
|
test_zero_args()
|
|
|
|
{
|
2002-08-05 06:13:32 +00:00
|
|
|
typedef function<void ()> func_void_type;
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
write_five_obj five;
|
|
|
|
write_three_obj three;
|
|
|
|
|
|
|
|
// Default construction
|
|
|
|
func_void_type v1;
|
|
|
|
BOOST_TEST(v1.empty());
|
|
|
|
|
2002-10-08 02:32:38 +00:00
|
|
|
// Assignment to an empty function
|
2001-06-21 17:01:43 +00:00
|
|
|
v1 = five;
|
2002-10-08 02:32:38 +00:00
|
|
|
BOOST_TEST(v1 != 0);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Invocation of a function
|
|
|
|
global_int = 0;
|
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// clear() method
|
|
|
|
v1.clear();
|
2002-10-08 02:32:38 +00:00
|
|
|
BOOST_TEST(v1 == 0);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Assignment to an empty function
|
|
|
|
v1 = three;
|
|
|
|
BOOST_TEST(!v1.empty());
|
|
|
|
|
2001-06-26 13:41:10 +00:00
|
|
|
// Invocation and self-assignment
|
2001-06-21 17:01:43 +00:00
|
|
|
global_int = 0;
|
2001-06-26 13:41:10 +00:00
|
|
|
v1 = v1;
|
2001-06-21 17:01:43 +00:00
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function
|
|
|
|
v1 = five;
|
|
|
|
|
2001-06-26 13:41:10 +00:00
|
|
|
// Invocation and self-assignment
|
2001-06-21 17:01:43 +00:00
|
|
|
global_int = 0;
|
2002-07-19 20:45:36 +00:00
|
|
|
v1 = (v1);
|
2001-06-21 17:01:43 +00:00
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
2002-10-08 02:32:38 +00:00
|
|
|
// clear
|
2002-11-09 16:02:47 +00:00
|
|
|
v1 = 0;
|
2002-10-08 02:32:38 +00:00
|
|
|
BOOST_TEST(0 == v1);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Assignment to an empty function from a free function
|
2001-12-24 17:11:11 +00:00
|
|
|
v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
|
2002-10-08 02:32:38 +00:00
|
|
|
BOOST_TEST(0 != v1);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function from a free function
|
2001-12-24 17:11:11 +00:00
|
|
|
v1 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
|
2001-06-21 17:01:43 +00:00
|
|
|
BOOST_TEST(!v1.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment
|
|
|
|
v1 = five;
|
|
|
|
BOOST_TEST(!v1.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function from a free function
|
|
|
|
v1 = &write_three;
|
|
|
|
BOOST_TEST(!v1.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Construction from another function (that is empty)
|
|
|
|
v1.clear();
|
2001-06-29 19:35:40 +00:00
|
|
|
func_void_type v2(v1);
|
2002-08-15 03:22:31 +00:00
|
|
|
BOOST_TEST(!v2? true : false);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Assignment to an empty function
|
|
|
|
v2 = three;
|
|
|
|
BOOST_TEST(!v2.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v2();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function
|
2002-07-19 20:45:36 +00:00
|
|
|
v2 = (five);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v2();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
v2.clear();
|
|
|
|
BOOST_TEST(v2.empty());
|
|
|
|
|
|
|
|
// Assignment to an empty function from a free function
|
2002-07-19 20:45:36 +00:00
|
|
|
v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five);
|
2002-08-15 03:22:31 +00:00
|
|
|
BOOST_TEST(v2? true : false);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v2();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function from a free function
|
2001-12-24 17:11:11 +00:00
|
|
|
v2 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
|
2001-06-21 17:01:43 +00:00
|
|
|
BOOST_TEST(!v2.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v2();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Swapping
|
|
|
|
v1 = five;
|
|
|
|
swap(v1, v2);
|
|
|
|
v2();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
swap(v1, v2);
|
|
|
|
v1.clear();
|
|
|
|
|
|
|
|
// Assignment
|
|
|
|
v2 = five;
|
|
|
|
BOOST_TEST(!v2.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v2();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function from a free function
|
|
|
|
v2 = &write_three;
|
|
|
|
BOOST_TEST(!v2.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v2();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment to a function from an empty function
|
|
|
|
v2 = v1;
|
2002-10-08 02:32:38 +00:00
|
|
|
BOOST_TEST(v2.empty());
|
|
|
|
|
2001-06-21 17:01:43 +00:00
|
|
|
// Assignment to a function from a function with a functor
|
|
|
|
v1 = three;
|
|
|
|
v2 = v1;
|
|
|
|
BOOST_TEST(!v1.empty());
|
|
|
|
BOOST_TEST(!v2.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
global_int = 0;
|
|
|
|
v2();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assign to a function from a function with a function
|
2001-12-24 17:11:11 +00:00
|
|
|
v2 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
|
2001-06-21 17:01:43 +00:00
|
|
|
v1 = v2;
|
|
|
|
BOOST_TEST(!v1.empty());
|
|
|
|
BOOST_TEST(!v2.empty());
|
|
|
|
global_int = 0;
|
|
|
|
v1();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
global_int = 0;
|
|
|
|
v2();
|
2001-06-29 19:35:40 +00:00
|
|
|
BOOST_TEST(global_int == 5);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Construct a function given another function containing a function
|
2001-06-29 19:35:40 +00:00
|
|
|
func_void_type v3(v1);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Invocation of a function
|
|
|
|
global_int = 0;
|
|
|
|
v3();
|
|
|
|
BOOST_TEST(global_int == 5);
|
2002-10-08 02:32:38 +00:00
|
|
|
|
2001-06-21 17:01:43 +00:00
|
|
|
// clear() method
|
|
|
|
v3.clear();
|
2002-08-15 03:22:31 +00:00
|
|
|
BOOST_TEST(!v3? true : false);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Assignment to an empty function
|
|
|
|
v3 = three;
|
|
|
|
BOOST_TEST(!v3.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v3();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function
|
|
|
|
v3 = five;
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v3();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// clear()
|
|
|
|
v3.clear();
|
|
|
|
BOOST_TEST(v3.empty());
|
|
|
|
|
|
|
|
// Assignment to an empty function from a free function
|
|
|
|
v3 = &write_five;
|
|
|
|
BOOST_TEST(!v3.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v3();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function from a free function
|
|
|
|
v3 = &write_three;
|
|
|
|
BOOST_TEST(!v3.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v3();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment
|
|
|
|
v3 = five;
|
|
|
|
BOOST_TEST(!v3.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v3();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Construction of a function from a function containing a functor
|
|
|
|
func_void_type v4(v3);
|
|
|
|
|
|
|
|
// Invocation of a function
|
|
|
|
global_int = 0;
|
|
|
|
v4();
|
|
|
|
BOOST_TEST(global_int == 5);
|
2002-10-08 02:32:38 +00:00
|
|
|
|
2001-06-21 17:01:43 +00:00
|
|
|
// clear() method
|
|
|
|
v4.clear();
|
|
|
|
BOOST_TEST(v4.empty());
|
|
|
|
|
|
|
|
// Assignment to an empty function
|
|
|
|
v4 = three;
|
|
|
|
BOOST_TEST(!v4.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v4();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function
|
|
|
|
v4 = five;
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v4();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// clear()
|
|
|
|
v4.clear();
|
|
|
|
BOOST_TEST(v4.empty());
|
|
|
|
|
|
|
|
// Assignment to an empty function from a free function
|
|
|
|
v4 = &write_five;
|
|
|
|
BOOST_TEST(!v4.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v4();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function from a free function
|
|
|
|
v4 = &write_three;
|
|
|
|
BOOST_TEST(!v4.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v4();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment
|
|
|
|
v4 = five;
|
|
|
|
BOOST_TEST(!v4.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v4();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Construction of a function from a functor
|
|
|
|
func_void_type v5(five);
|
|
|
|
|
|
|
|
// Invocation of a function
|
|
|
|
global_int = 0;
|
|
|
|
v5();
|
|
|
|
BOOST_TEST(global_int == 5);
|
2002-10-08 02:32:38 +00:00
|
|
|
|
2001-06-21 17:01:43 +00:00
|
|
|
// clear() method
|
|
|
|
v5.clear();
|
|
|
|
BOOST_TEST(v5.empty());
|
|
|
|
|
|
|
|
// Assignment to an empty function
|
|
|
|
v5 = three;
|
|
|
|
BOOST_TEST(!v5.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v5();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function
|
|
|
|
v5 = five;
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v5();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// clear()
|
|
|
|
v5.clear();
|
|
|
|
BOOST_TEST(v5.empty());
|
|
|
|
|
|
|
|
// Assignment to an empty function from a free function
|
|
|
|
v5 = &write_five;
|
|
|
|
BOOST_TEST(!v5.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v5();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function from a free function
|
|
|
|
v5 = &write_three;
|
|
|
|
BOOST_TEST(!v5.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v5();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment
|
|
|
|
v5 = five;
|
|
|
|
BOOST_TEST(!v5.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v5();
|
2002-10-08 02:32:38 +00:00
|
|
|
BOOST_TEST(global_int == 5);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Construction of a function from a function
|
|
|
|
func_void_type v6(&write_five);
|
|
|
|
|
|
|
|
// Invocation of a function
|
|
|
|
global_int = 0;
|
|
|
|
v6();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// clear() method
|
|
|
|
v6.clear();
|
|
|
|
BOOST_TEST(v6.empty());
|
|
|
|
|
|
|
|
// Assignment to an empty function
|
|
|
|
v6 = three;
|
|
|
|
BOOST_TEST(!v6.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v6();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function
|
|
|
|
v6 = five;
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v6();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// clear()
|
|
|
|
v6.clear();
|
|
|
|
BOOST_TEST(v6.empty());
|
|
|
|
|
|
|
|
// Assignment to an empty function from a free function
|
|
|
|
v6 = &write_five;
|
|
|
|
BOOST_TEST(!v6.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v6();
|
|
|
|
BOOST_TEST(global_int == 5);
|
|
|
|
|
|
|
|
// Assignment to a non-empty function from a free function
|
|
|
|
v6 = &write_three;
|
|
|
|
BOOST_TEST(!v6.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v6();
|
|
|
|
BOOST_TEST(global_int == 3);
|
|
|
|
|
|
|
|
// Assignment
|
|
|
|
v6 = five;
|
|
|
|
BOOST_TEST(!v6.empty());
|
|
|
|
|
|
|
|
// Invocation
|
|
|
|
global_int = 0;
|
|
|
|
v6();
|
2002-10-08 02:32:38 +00:00
|
|
|
BOOST_TEST(global_int == 5);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Const vs. non-const
|
|
|
|
write_const_1_nonconst_2 one_or_two;
|
2002-08-05 06:13:32 +00:00
|
|
|
const function<void ()> v7(one_or_two);
|
|
|
|
function<void ()> v8(one_or_two);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
global_int = 0;
|
|
|
|
v7();
|
2001-07-22 05:27:20 +00:00
|
|
|
BOOST_TEST(global_int == 2);
|
2002-10-08 02:32:38 +00:00
|
|
|
|
2001-06-21 17:01:43 +00:00
|
|
|
global_int = 0;
|
|
|
|
v8();
|
|
|
|
BOOST_TEST(global_int == 2);
|
|
|
|
|
2002-11-09 16:02:47 +00:00
|
|
|
// Test construction from 0 and comparison to 0
|
|
|
|
func_void_type v9(0);
|
|
|
|
BOOST_TEST(v9 == 0);
|
|
|
|
BOOST_TEST(0 == v9);
|
|
|
|
|
2001-06-21 17:01:43 +00:00
|
|
|
// Test return values
|
2002-08-05 06:13:32 +00:00
|
|
|
typedef function<int ()> func_int_type;
|
2001-06-21 17:01:43 +00:00
|
|
|
generate_five_obj gen_five;
|
|
|
|
generate_three_obj gen_three;
|
|
|
|
|
|
|
|
func_int_type i0(gen_five);
|
|
|
|
|
|
|
|
BOOST_TEST(i0() == 5);
|
|
|
|
i0 = gen_three;
|
|
|
|
BOOST_TEST(i0() == 3);
|
|
|
|
i0 = &generate_five;
|
|
|
|
BOOST_TEST(i0() == 5);
|
|
|
|
i0 = &generate_three;
|
|
|
|
BOOST_TEST(i0() == 3);
|
2002-08-15 03:22:31 +00:00
|
|
|
BOOST_TEST(i0? true : false);
|
2001-06-21 17:01:43 +00:00
|
|
|
i0.clear();
|
2002-08-15 03:22:31 +00:00
|
|
|
BOOST_TEST(!i0? true : false);
|
2001-06-21 17:01:43 +00:00
|
|
|
|
|
|
|
// Test return values with compatible types
|
2002-08-05 06:13:32 +00:00
|
|
|
typedef function<long ()> func_long_type;
|
2001-06-21 17:01:43 +00:00
|
|
|
func_long_type i1(gen_five);
|
|
|
|
|
|
|
|
BOOST_TEST(i1() == 5);
|
|
|
|
i1 = gen_three;
|
|
|
|
BOOST_TEST(i1() == 3);
|
|
|
|
i1 = &generate_five;
|
|
|
|
BOOST_TEST(i1() == 5);
|
|
|
|
i1 = &generate_three;
|
|
|
|
BOOST_TEST(i1() == 3);
|
2002-08-15 03:22:31 +00:00
|
|
|
BOOST_TEST(i1? true : false);
|
2001-06-21 17:01:43 +00:00
|
|
|
i1.clear();
|
2002-08-15 03:22:31 +00:00
|
|
|
BOOST_TEST(!i1? true : false);
|
2001-06-21 17:01:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_one_arg()
|
|
|
|
{
|
|
|
|
negate<int> neg;
|
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
function<int (int)> f1(neg);
|
2001-06-21 17:01:43 +00:00
|
|
|
BOOST_TEST(f1(5) == -5);
|
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
function<string (string)> id(&identity_str);
|
2001-06-21 17:01:43 +00:00
|
|
|
BOOST_TEST(id("str") == "str");
|
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
function<string (const char*)> id2(&identity_str);
|
2001-06-21 17:01:43 +00:00
|
|
|
BOOST_TEST(id2("foo") == "foo");
|
2001-10-08 13:33:14 +00:00
|
|
|
|
|
|
|
add_to_obj add_to(5);
|
2002-08-05 06:13:32 +00:00
|
|
|
function<int (int)> f2(add_to);
|
2001-10-08 13:33:14 +00:00
|
|
|
BOOST_TEST(f2(3) == 8);
|
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
const function<int (int)> cf2(add_to);
|
2001-10-08 13:33:14 +00:00
|
|
|
BOOST_TEST(cf2(3) == 8);
|
2001-06-21 17:01:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_two_args()
|
|
|
|
{
|
2002-08-05 06:13:32 +00:00
|
|
|
function<string (const string&, const string&)> cat(&string_cat);
|
2002-10-08 02:32:38 +00:00
|
|
|
BOOST_TEST(cat("str", "ing") == "string");
|
2001-06-21 17:01:43 +00:00
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
function<int (short, short)> sum(&sum_ints);
|
2001-06-21 17:01:43 +00:00
|
|
|
BOOST_TEST(sum(2, 3) == 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_emptiness()
|
|
|
|
{
|
2002-08-05 06:13:32 +00:00
|
|
|
function<float ()> f1;
|
2001-06-21 17:01:43 +00:00
|
|
|
BOOST_TEST(f1.empty());
|
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
function<float ()> f2;
|
2001-06-21 17:01:43 +00:00
|
|
|
f2 = f1;
|
|
|
|
BOOST_TEST(f2.empty());
|
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
function<double ()> f3;
|
2001-06-29 19:35:40 +00:00
|
|
|
f3 = f2;
|
2001-06-21 17:01:43 +00:00
|
|
|
BOOST_TEST(f3.empty());
|
|
|
|
}
|
|
|
|
|
2001-10-16 19:24:04 +00:00
|
|
|
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()
|
|
|
|
{
|
2002-08-05 06:13:32 +00:00
|
|
|
boost::function<int (X*)> f1(&X::twice);
|
2002-10-08 02:32:38 +00:00
|
|
|
|
2001-10-16 19:24:04 +00:00
|
|
|
X one(1);
|
|
|
|
X five(5);
|
|
|
|
|
|
|
|
BOOST_TEST(f1(&one) == 2);
|
|
|
|
BOOST_TEST(f1(&five) == 10);
|
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
boost::function<int (X*)> f1_2;
|
2001-10-16 19:24:04 +00:00
|
|
|
f1_2 = &X::twice;
|
|
|
|
|
|
|
|
BOOST_TEST(f1_2(&one) == 2);
|
|
|
|
BOOST_TEST(f1_2(&five) == 10);
|
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
boost::function<int (X&, int)> f2(&X::plus);
|
2001-11-19 20:57:57 +00:00
|
|
|
BOOST_TEST(f2(one, 3) == 4);
|
|
|
|
BOOST_TEST(f2(five, 4) == 9);
|
2001-10-16 19:24:04 +00:00
|
|
|
}
|
|
|
|
|
2001-12-03 16:25:00 +00:00
|
|
|
struct add_with_throw_on_copy {
|
|
|
|
int operator()(int x, int y) const { return x+y; }
|
|
|
|
|
|
|
|
add_with_throw_on_copy() {}
|
|
|
|
|
|
|
|
add_with_throw_on_copy(const add_with_throw_on_copy&)
|
|
|
|
{
|
2002-08-05 06:13:32 +00:00
|
|
|
throw runtime_error("But this CAN'T throw");
|
2001-12-03 16:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
|
|
|
|
{
|
2002-08-05 06:13:32 +00:00
|
|
|
throw runtime_error("But this CAN'T throw");
|
2001-12-03 16:25:00 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_ref()
|
|
|
|
{
|
|
|
|
add_with_throw_on_copy atc;
|
|
|
|
try {
|
2002-08-05 06:13:32 +00:00
|
|
|
boost::function<int (int, int)> f(ref(atc));
|
2001-12-03 16:25:00 +00:00
|
|
|
BOOST_TEST(f(1, 3) == 4);
|
|
|
|
}
|
2002-08-05 06:13:32 +00:00
|
|
|
catch(runtime_error e) {
|
2001-12-03 16:25:00 +00:00
|
|
|
BOOST_ERROR("Nonthrowing constructor threw an exception");
|
|
|
|
}
|
2001-12-05 22:39:33 +00:00
|
|
|
}
|
2001-12-03 16:25:00 +00:00
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
static int alloc_count = 0;
|
|
|
|
static int dealloc_count = 0;
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
struct counting_allocator : public allocator<T>
|
2002-07-19 18:31:41 +00:00
|
|
|
{
|
2002-08-05 06:13:32 +00:00
|
|
|
template<typename U>
|
|
|
|
struct rebind
|
|
|
|
{
|
|
|
|
typedef counting_allocator<U> other;
|
|
|
|
};
|
2002-07-19 18:31:41 +00:00
|
|
|
|
2002-10-08 02:32:38 +00:00
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
T* allocate(size_t n)
|
|
|
|
{
|
|
|
|
alloc_count++;
|
|
|
|
return allocator<T>::allocate(n);
|
|
|
|
}
|
2002-07-19 18:31:41 +00:00
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
void deallocate(T* p, size_t n)
|
|
|
|
{
|
|
|
|
dealloc_count++;
|
|
|
|
allocator<T>::deallocate(p, n);
|
|
|
|
}
|
|
|
|
};
|
2002-07-19 18:31:41 +00:00
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
static int do_minus(int x, int y) { return x-y; }
|
2002-07-19 18:31:41 +00:00
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
struct DoNothing
|
|
|
|
{
|
|
|
|
void operator()() const {}
|
|
|
|
};
|
|
|
|
|
|
|
|
static void do_nothing() {}
|
|
|
|
|
|
|
|
static void test_allocator()
|
|
|
|
{
|
2002-08-05 15:05:34 +00:00
|
|
|
#ifndef BOOST_NO_STD_ALLOCATOR
|
2002-08-05 06:13:32 +00:00
|
|
|
boost::function<int (int, int), counting_allocator<int> > f;
|
|
|
|
f = plus<int>();
|
|
|
|
f.clear();
|
|
|
|
BOOST_TEST(alloc_count == 1);
|
|
|
|
BOOST_TEST(dealloc_count == 1);
|
|
|
|
|
|
|
|
alloc_count = 0;
|
|
|
|
dealloc_count = 0;
|
|
|
|
f = &do_minus;
|
|
|
|
f.clear();
|
|
|
|
|
|
|
|
boost::function<void (), counting_allocator<int> > fv;
|
|
|
|
alloc_count = 0;
|
|
|
|
dealloc_count = 0;
|
|
|
|
fv = DoNothing();
|
|
|
|
fv.clear();
|
|
|
|
BOOST_TEST(alloc_count == 1);
|
|
|
|
BOOST_TEST(dealloc_count == 1);
|
2002-10-08 02:32:38 +00:00
|
|
|
|
2002-08-05 06:13:32 +00:00
|
|
|
alloc_count = 0;
|
|
|
|
dealloc_count = 0;
|
|
|
|
fv = &do_nothing;
|
|
|
|
fv.clear();
|
2002-08-05 15:05:34 +00:00
|
|
|
#endif // ndef BOOST_NO_STD_ALLOCATOR
|
2002-07-19 18:31:41 +00:00
|
|
|
}
|
|
|
|
|
2002-11-04 18:19:01 +00:00
|
|
|
static void test_exception()
|
|
|
|
{
|
|
|
|
boost::function<int (int, int)> f;
|
|
|
|
try {
|
|
|
|
f(5, 4);
|
|
|
|
BOOST_TEST(false);
|
|
|
|
}
|
|
|
|
catch(boost::bad_function_call) {
|
|
|
|
// okay
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef boost::function< void * (void * reader) > reader_type;
|
|
|
|
typedef std::pair<int, reader_type> mapped_type;
|
|
|
|
|
|
|
|
static void test_implicit()
|
|
|
|
{
|
|
|
|
mapped_type m;
|
|
|
|
m = mapped_type();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_call_obj(boost::function<int (int, int)> f)
|
|
|
|
{
|
|
|
|
assert(!f.empty());
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_call_cref(const boost::function<int (int, int)>& f)
|
|
|
|
{
|
|
|
|
assert(!f.empty());
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_call()
|
|
|
|
{
|
|
|
|
test_call_obj(std::plus<int>());
|
|
|
|
test_call_cref(std::plus<int>());
|
|
|
|
}
|
|
|
|
|
2001-11-19 20:19:23 +00:00
|
|
|
int test_main(int, char* [])
|
2001-06-21 17:01:43 +00:00
|
|
|
{
|
|
|
|
test_zero_args();
|
|
|
|
test_one_arg();
|
|
|
|
test_two_args();
|
|
|
|
test_emptiness();
|
2001-10-16 19:24:04 +00:00
|
|
|
test_member_functions();
|
2001-12-03 16:25:00 +00:00
|
|
|
test_ref();
|
2002-08-05 06:13:32 +00:00
|
|
|
test_allocator();
|
2002-11-04 18:19:01 +00:00
|
|
|
test_exception();
|
|
|
|
test_implicit();
|
|
|
|
test_call();
|
2001-12-03 16:25:00 +00:00
|
|
|
|
2001-06-21 17:01:43 +00:00
|
|
|
return 0;
|
|
|
|
}
|