function_n_test.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 698 行

CPP
698
字号
// Boost.Function library//  Copyright Douglas 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)// For more information, see http://www.boost.org#include <boost/test/minimal.hpp>#include <boost/function.hpp>#include <functional>#include <cassert>#include <string>using namespace boost;using std::string;using std::negate;int global_int;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; }};struct add_to_obj{  add_to_obj(int v) : value(v) {}  int operator()(int x) const { return value + x; }  int value;};static voidtest_zero_args(){  typedef function0<void> func_void_type;  write_five_obj five = write_five_obj(); // Initialization for Borland C++ 5.5  write_three_obj three = write_three_obj(); // Ditto  // Default construction  func_void_type v1;  BOOST_CHECK(v1.empty());  // Assignment to an empty function  v1 = five;  BOOST_CHECK(!v1.empty());  // Invocation of a function  global_int = 0;  v1();  BOOST_CHECK(global_int == 5);  // clear() method  v1.clear();  BOOST_CHECK(!v1);  // Assignment to an empty function  v1 = three;  BOOST_CHECK(!v1.empty());  // Invocation and self-assignment  global_int = 0;  v1 = v1;  v1();  BOOST_CHECK(global_int == 3);  // Assignment to a non-empty function  v1 = five;  // Invocation and self-assignment  global_int = 0;  v1 = (v1);  v1();  BOOST_CHECK(global_int == 5);  // clear  v1 = 0;  BOOST_CHECK(v1.empty());  // Assignment to an empty function from a free function  v1 = &write_five;  BOOST_CHECK(!v1.empty());  // Invocation  global_int = 0;  v1();  BOOST_CHECK(global_int == 5);  // Assignment to a non-empty function from a free function  v1 = &write_three;  BOOST_CHECK(!v1.empty());  // Invocation  global_int = 0;  v1();  BOOST_CHECK(global_int == 3);  // Assignment  v1 = five;  BOOST_CHECK(!v1.empty());  // Invocation  global_int = 0;  v1();  BOOST_CHECK(global_int == 5);  // Assignment to a non-empty function from a free function  v1 = write_three;  BOOST_CHECK(!v1.empty());  // Invocation  global_int = 0;  v1();  BOOST_CHECK(global_int == 3);  // Construction from another function (that is empty)  v1.clear();  func_void_type v2(v1);  BOOST_CHECK(!v2? true : false);  // Assignment to an empty function  v2 = three;  BOOST_CHECK(!v2.empty());  // Invocation  global_int = 0;  v2();  BOOST_CHECK(global_int == 3);  // Assignment to a non-empty function  v2 = (five);  // Invocation  global_int = 0;  v2();  BOOST_CHECK(global_int == 5);  v2.clear();  BOOST_CHECK(v2.empty());  // Assignment to an empty function from a free function  v2 = (&write_five);  BOOST_CHECK(v2? true : false);  // Invocation  global_int = 0;  v2();  BOOST_CHECK(global_int == 5);  // Assignment to a non-empty function from a free function  v2 = &write_three;  BOOST_CHECK(!v2.empty());  // Invocation  global_int = 0;  v2();  BOOST_CHECK(global_int == 3);  // Swapping  v1 = five;  swap(v1, v2);  v2();  BOOST_CHECK(global_int == 5);  v1();  BOOST_CHECK(global_int == 3);  swap(v1, v2);  v1.clear();  // Assignment  v2 = five;  BOOST_CHECK(!v2.empty());  // Invocation  global_int = 0;  v2();  BOOST_CHECK(global_int == 5);  // Assignment to a non-empty function from a free function  v2 = &write_three;  BOOST_CHECK(!v2.empty());  // Invocation  global_int = 0;  v2();  BOOST_CHECK(global_int == 3);  // Assignment to a function from an empty function  v2 = v1;  BOOST_CHECK(v2.empty());  // Assignment to a function from a function with a functor  v1 = three;  v2 = v1;  BOOST_CHECK(!v1.empty());  BOOST_CHECK(!v2.empty());  // Invocation  global_int = 0;  v1();  BOOST_CHECK(global_int == 3);  global_int = 0;  v2();  BOOST_CHECK(global_int == 3);  // Assign to a function from a function with a function  v2 = &write_five;  v1 = v2;  BOOST_CHECK(!v1.empty());  BOOST_CHECK(!v2.empty());  global_int = 0;  v1();  BOOST_CHECK(global_int == 5);  global_int = 0;  v2();  BOOST_CHECK(global_int == 5);  // Construct a function given another function containing a function  func_void_type v3(v1);  // Invocation of a function  global_int = 0;  v3();  BOOST_CHECK(global_int == 5);  // clear() method  v3.clear();  BOOST_CHECK(!v3? true : false);  // Assignment to an empty function  v3 = three;  BOOST_CHECK(!v3.empty());  // Invocation  global_int = 0;  v3();  BOOST_CHECK(global_int == 3);  // Assignment to a non-empty function  v3 = five;  // Invocation  global_int = 0;  v3();  BOOST_CHECK(global_int == 5);  // clear()  v3.clear();  BOOST_CHECK(v3.empty());  // Assignment to an empty function from a free function  v3 = &write_five;  BOOST_CHECK(!v3.empty());  // Invocation  global_int = 0;  v3();  BOOST_CHECK(global_int == 5);  // Assignment to a non-empty function from a free function  v3 = &write_three;  BOOST_CHECK(!v3.empty());  // Invocation  global_int = 0;  v3();  BOOST_CHECK(global_int == 3);  // Assignment  v3 = five;  BOOST_CHECK(!v3.empty());  // Invocation  global_int = 0;  v3();  BOOST_CHECK(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_CHECK(global_int == 5);  // clear() method  v4.clear();  BOOST_CHECK(v4.empty());  // Assignment to an empty function  v4 = three;  BOOST_CHECK(!v4.empty());  // Invocation  global_int = 0;  v4();  BOOST_CHECK(global_int == 3);  // Assignment to a non-empty function  v4 = five;  // Invocation  global_int = 0;  v4();  BOOST_CHECK(global_int == 5);  // clear()  v4.clear();  BOOST_CHECK(v4.empty());  // Assignment to an empty function from a free function  v4 = &write_five;  BOOST_CHECK(!v4.empty());  // Invocation  global_int = 0;  v4();  BOOST_CHECK(global_int == 5);  // Assignment to a non-empty function from a free function  v4 = &write_three;  BOOST_CHECK(!v4.empty());  // Invocation  global_int = 0;  v4();  BOOST_CHECK(global_int == 3);  // Assignment  v4 = five;  BOOST_CHECK(!v4.empty());  // Invocation  global_int = 0;  v4();  BOOST_CHECK(global_int == 5);  // Construction of a function from a functor  func_void_type v5(five);  // Invocation of a function  global_int = 0;  v5();  BOOST_CHECK(global_int == 5);  // clear() method  v5.clear();  BOOST_CHECK(v5.empty());  // Assignment to an empty function  v5 = three;  BOOST_CHECK(!v5.empty());  // Invocation  global_int = 0;  v5();  BOOST_CHECK(global_int == 3);  // Assignment to a non-empty function  v5 = five;  // Invocation  global_int = 0;  v5();  BOOST_CHECK(global_int == 5);  // clear()  v5.clear();  BOOST_CHECK(v5.empty());  // Assignment to an empty function from a free function  v5 = &write_five;  BOOST_CHECK(!v5.empty());  // Invocation  global_int = 0;  v5();  BOOST_CHECK(global_int == 5);  // Assignment to a non-empty function from a free function  v5 = &write_three;  BOOST_CHECK(!v5.empty());  // Invocation  global_int = 0;  v5();  BOOST_CHECK(global_int == 3);  // Assignment  v5 = five;  BOOST_CHECK(!v5.empty());  // Invocation  global_int = 0;  v5();  BOOST_CHECK(global_int == 5);  // Construction of a function from a function  func_void_type v6(&write_five);  // Invocation of a function  global_int = 0;  v6();  BOOST_CHECK(global_int == 5);  // clear() method  v6.clear();  BOOST_CHECK(v6.empty());  // Assignment to an empty function  v6 = three;  BOOST_CHECK(!v6.empty());  // Invocation  global_int = 0;  v6();  BOOST_CHECK(global_int == 3);  // Assignment to a non-empty function  v6 = five;  // Invocation  global_int = 0;  v6();  BOOST_CHECK(global_int == 5);  // clear()  v6.clear();  BOOST_CHECK(v6.empty());  // Assignment to an empty function from a free function  v6 = &write_five;  BOOST_CHECK(!v6.empty());  // Invocation  global_int = 0;  v6();  BOOST_CHECK(global_int == 5);  // Assignment to a non-empty function from a free function  v6 = &write_three;  BOOST_CHECK(!v6.empty());  // Invocation  global_int = 0;  v6();  BOOST_CHECK(global_int == 3);  // Assignment  v6 = five;  BOOST_CHECK(!v6.empty());  // Invocation  global_int = 0;  v6();  BOOST_CHECK(global_int == 5);  // Const vs. non-const  // Initialization for Borland C++ 5.5  write_const_1_nonconst_2 one_or_two = write_const_1_nonconst_2();   const function0<void> v7(one_or_two);  function0<void> v8(one_or_two);  global_int = 0;  v7();  BOOST_CHECK(global_int == 2);  global_int = 0;  v8();  BOOST_CHECK(global_int == 2);  // Test construction from 0 and comparison to 0  func_void_type v9(0);  BOOST_CHECK(v9 == 0);# if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540 || defined(BOOST_STRICT_CONFIG)  BOOST_CHECK(0 == v9);#else  BOOST_CHECK(v9.empty());#endif  // Test return values  typedef function0<int> func_int_type;  // Initialization for Borland C++ 5.5  generate_five_obj gen_five = generate_five_obj();  generate_three_obj gen_three = generate_three_obj();  func_int_type i0(gen_five);  BOOST_CHECK(i0() == 5);  i0 = gen_three;  BOOST_CHECK(i0() == 3);  i0 = &generate_five;  BOOST_CHECK(i0() == 5);  i0 = &generate_three;  BOOST_CHECK(i0() == 3);  BOOST_CHECK(i0? true : false);  i0.clear();  BOOST_CHECK(!i0? true : false);  // Test return values with compatible types  typedef function0<long> func_long_type;  func_long_type i1(gen_five);  BOOST_CHECK(i1() == 5);  i1 = gen_three;  BOOST_CHECK(i1() == 3);  i1 = &generate_five;  BOOST_CHECK(i1() == 5);  i1 = &generate_three;  BOOST_CHECK(i1() == 3);  BOOST_CHECK(i1? true : false);  i1.clear();  BOOST_CHECK(!i1? true : false);}static voidtest_one_arg(){  negate<int> neg = negate<int>(); // Initialization for Borland C++ 5.5  function1<int, int> f1(neg);  BOOST_CHECK(f1(5) == -5);  function1<string, string> id(&identity_str);  BOOST_CHECK(id("str") == "str");  function1<std::string, const char*> id2(&identity_str);  BOOST_CHECK(id2("foo") == "foo");  add_to_obj add_to(5);  function1<int, int> f2(add_to);  BOOST_CHECK(f2(3) == 8);  const function1<int, int> cf2(add_to);  BOOST_CHECK(cf2(3) == 8);}static voidtest_two_args(){  function2<string, const string&, const string&> cat(&string_cat);  BOOST_CHECK(cat("str", "ing") == "string");  function2<int, short, short> sum(&sum_ints);  BOOST_CHECK(sum(2, 3) == 5);}static voidtest_emptiness(){  function0<float> f1;  BOOST_CHECK(f1.empty());  function0<float> f2;  f2 = f1;  BOOST_CHECK(f2.empty());  function0<double> f3;  f3 = f2;  BOOST_CHECK(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 voidtest_member_functions(){  boost::function1<int, X*> f1(&X::twice);  X one(1);  X five(5);  BOOST_CHECK(f1(&one) == 2);  BOOST_CHECK(f1(&five) == 10);  boost::function1<int, X*> f1_2;  f1_2 = &X::twice;  BOOST_CHECK(f1_2(&one) == 2);  BOOST_CHECK(f1_2(&five) == 10);  boost::function2<int, X&, int> f2(&X::plus);  BOOST_CHECK(f2(one, 3) == 4);  BOOST_CHECK(f2(five, 4) == 9);}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&)  {    throw std::runtime_error("But this CAN'T throw");  }  add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)  {    throw std::runtime_error("But this CAN'T throw");  }};static voidtest_ref(){  add_with_throw_on_copy atc;  try {    boost::function2<int, int, int> f(ref(atc));    BOOST_CHECK(f(1, 3) == 4);  }  catch(std::runtime_error e) {    BOOST_ERROR("Nonthrowing constructor threw an exception");  }}static unsigned construction_count = 0;static unsigned destruction_count = 0;struct MySmallFunctor {  MySmallFunctor() { ++construction_count; }  MySmallFunctor(const MySmallFunctor &) { ++construction_count; }  ~MySmallFunctor() { ++destruction_count; }  int operator()() { return 0; } };struct MyLargeFunctor {  MyLargeFunctor() { ++construction_count; }  MyLargeFunctor(const MyLargeFunctor &) { ++construction_count; }  ~MyLargeFunctor() { ++destruction_count; }  int operator()() { return 0; }  float data[128]; };void test_construct_destroy_count(){  {    boost::function0<int> f;    boost::function0<int> g;    f = MySmallFunctor();    g = MySmallFunctor();    f.swap(g);  }  // MySmallFunctor objects should be constructed as many times as  // they are destroyed.  BOOST_CHECK(construction_count == destruction_count);   construction_count = 0;  destruction_count = 0;  {    boost::function0<int> f;    boost::function0<int> g;    f = MyLargeFunctor();    g = MyLargeFunctor();    f.swap(g);   }   // MyLargeFunctor objects should be constructed as many times as   // they are destroyed.   BOOST_CHECK(construction_count == destruction_count);}int test_main(int, char* []){  test_zero_args();  test_one_arg();  test_two_args();  test_emptiness();  test_member_functions();  test_ref();  test_construct_destroy_count();  return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?