/Src/Dependencies/Boost/libs/function/test/function_test.cpp

http://hadesmem.googlecode.com/ · C++ · 707 lines · 453 code · 152 blank · 102 comment · 73 complexity · b048c0ef7090a7b8023ce67e6c7d0adc MD5 · raw file

  1. // Boost.Function library
  2. // Copyright Douglas Gregor 2001-2003. Use, modification and
  3. // distribution is subject to the Boost Software License, Version
  4. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // For more information, see http://www.boost.org
  7. #include <boost/test/minimal.hpp>
  8. #include <boost/function.hpp>
  9. #include <functional>
  10. #include <string>
  11. #include <utility>
  12. using boost::function;
  13. using std::string;
  14. int global_int;
  15. struct write_five_obj { void operator()() const { global_int = 5; } };
  16. struct write_three_obj { int operator()() const { global_int = 3; return 7; }};
  17. static void write_five() { global_int = 5; }
  18. static void write_three() { global_int = 3; }
  19. struct generate_five_obj { int operator()() const { return 5; } };
  20. struct generate_three_obj { int operator()() const { return 3; } };
  21. static int generate_five() { return 5; }
  22. static int generate_three() { return 3; }
  23. static string identity_str(const string& s) { return s; }
  24. static string string_cat(const string& s1, const string& s2) { return s1+s2; }
  25. static int sum_ints(int x, int y) { return x+y; }
  26. struct write_const_1_nonconst_2
  27. {
  28. void operator()() { global_int = 2; }
  29. void operator()() const { global_int = 1; }
  30. };
  31. struct add_to_obj
  32. {
  33. add_to_obj(int v) : value(v) {}
  34. int operator()(int x) const { return value + x; }
  35. int value;
  36. };
  37. static void
  38. test_zero_args()
  39. {
  40. typedef function<void ()> func_void_type;
  41. write_five_obj five;
  42. write_three_obj three;
  43. // Default construction
  44. func_void_type v1;
  45. BOOST_CHECK(v1.empty());
  46. // Assignment to an empty function
  47. v1 = five;
  48. BOOST_CHECK(v1 != 0);
  49. // Invocation of a function
  50. global_int = 0;
  51. v1();
  52. BOOST_CHECK(global_int == 5);
  53. // clear() method
  54. v1.clear();
  55. BOOST_CHECK(v1 == 0);
  56. // Assignment to an empty function
  57. v1 = three;
  58. BOOST_CHECK(!v1.empty());
  59. // Invocation and self-assignment
  60. global_int = 0;
  61. v1 = v1;
  62. v1();
  63. BOOST_CHECK(global_int == 3);
  64. // Assignment to a non-empty function
  65. v1 = five;
  66. // Invocation and self-assignment
  67. global_int = 0;
  68. v1 = (v1);
  69. v1();
  70. BOOST_CHECK(global_int == 5);
  71. // clear
  72. v1 = 0;
  73. BOOST_CHECK(0 == v1);
  74. // Assignment to an empty function from a free function
  75. v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
  76. BOOST_CHECK(0 != v1);
  77. // Invocation
  78. global_int = 0;
  79. v1();
  80. BOOST_CHECK(global_int == 5);
  81. // Assignment to a non-empty function from a free function
  82. v1 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
  83. BOOST_CHECK(!v1.empty());
  84. // Invocation
  85. global_int = 0;
  86. v1();
  87. BOOST_CHECK(global_int == 3);
  88. // Assignment
  89. v1 = five;
  90. BOOST_CHECK(!v1.empty());
  91. // Invocation
  92. global_int = 0;
  93. v1();
  94. BOOST_CHECK(global_int == 5);
  95. // Assignment to a non-empty function from a free function
  96. v1 = &write_three;
  97. BOOST_CHECK(!v1.empty());
  98. // Invocation
  99. global_int = 0;
  100. v1();
  101. BOOST_CHECK(global_int == 3);
  102. // Construction from another function (that is empty)
  103. v1.clear();
  104. func_void_type v2(v1);
  105. BOOST_CHECK(!v2? true : false);
  106. // Assignment to an empty function
  107. v2 = three;
  108. BOOST_CHECK(!v2.empty());
  109. // Invocation
  110. global_int = 0;
  111. v2();
  112. BOOST_CHECK(global_int == 3);
  113. // Assignment to a non-empty function
  114. v2 = (five);
  115. // Invocation
  116. global_int = 0;
  117. v2();
  118. BOOST_CHECK(global_int == 5);
  119. v2.clear();
  120. BOOST_CHECK(v2.empty());
  121. // Assignment to an empty function from a free function
  122. v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five);
  123. BOOST_CHECK(v2? true : false);
  124. // Invocation
  125. global_int = 0;
  126. v2();
  127. BOOST_CHECK(global_int == 5);
  128. // Assignment to a non-empty function from a free function
  129. v2 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
  130. BOOST_CHECK(!v2.empty());
  131. // Invocation
  132. global_int = 0;
  133. v2();
  134. BOOST_CHECK(global_int == 3);
  135. // Swapping
  136. v1 = five;
  137. swap(v1, v2);
  138. v2();
  139. BOOST_CHECK(global_int == 5);
  140. v1();
  141. BOOST_CHECK(global_int == 3);
  142. swap(v1, v2);
  143. v1.clear();
  144. // Assignment
  145. v2 = five;
  146. BOOST_CHECK(!v2.empty());
  147. // Invocation
  148. global_int = 0;
  149. v2();
  150. BOOST_CHECK(global_int == 5);
  151. // Assignment to a non-empty function from a free function
  152. v2 = &write_three;
  153. BOOST_CHECK(!v2.empty());
  154. // Invocation
  155. global_int = 0;
  156. v2();
  157. BOOST_CHECK(global_int == 3);
  158. // Assignment to a function from an empty function
  159. v2 = v1;
  160. BOOST_CHECK(v2.empty());
  161. // Assignment to a function from a function with a functor
  162. v1 = three;
  163. v2 = v1;
  164. BOOST_CHECK(!v1.empty());
  165. BOOST_CHECK(!v2.empty());
  166. // Invocation
  167. global_int = 0;
  168. v1();
  169. BOOST_CHECK(global_int == 3);
  170. global_int = 0;
  171. v2();
  172. BOOST_CHECK(global_int == 3);
  173. // Assign to a function from a function with a function
  174. v2 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
  175. v1 = v2;
  176. BOOST_CHECK(!v1.empty());
  177. BOOST_CHECK(!v2.empty());
  178. global_int = 0;
  179. v1();
  180. BOOST_CHECK(global_int == 5);
  181. global_int = 0;
  182. v2();
  183. BOOST_CHECK(global_int == 5);
  184. // Construct a function given another function containing a function
  185. func_void_type v3(v1);
  186. // Invocation of a function
  187. global_int = 0;
  188. v3();
  189. BOOST_CHECK(global_int == 5);
  190. // clear() method
  191. v3.clear();
  192. BOOST_CHECK(!v3? true : false);
  193. // Assignment to an empty function
  194. v3 = three;
  195. BOOST_CHECK(!v3.empty());
  196. // Invocation
  197. global_int = 0;
  198. v3();
  199. BOOST_CHECK(global_int == 3);
  200. // Assignment to a non-empty function
  201. v3 = five;
  202. // Invocation
  203. global_int = 0;
  204. v3();
  205. BOOST_CHECK(global_int == 5);
  206. // clear()
  207. v3.clear();
  208. BOOST_CHECK(v3.empty());
  209. // Assignment to an empty function from a free function
  210. v3 = &write_five;
  211. BOOST_CHECK(!v3.empty());
  212. // Invocation
  213. global_int = 0;
  214. v3();
  215. BOOST_CHECK(global_int == 5);
  216. // Assignment to a non-empty function from a free function
  217. v3 = &write_three;
  218. BOOST_CHECK(!v3.empty());
  219. // Invocation
  220. global_int = 0;
  221. v3();
  222. BOOST_CHECK(global_int == 3);
  223. // Assignment
  224. v3 = five;
  225. BOOST_CHECK(!v3.empty());
  226. // Invocation
  227. global_int = 0;
  228. v3();
  229. BOOST_CHECK(global_int == 5);
  230. // Construction of a function from a function containing a functor
  231. func_void_type v4(v3);
  232. // Invocation of a function
  233. global_int = 0;
  234. v4();
  235. BOOST_CHECK(global_int == 5);
  236. // clear() method
  237. v4.clear();
  238. BOOST_CHECK(v4.empty());
  239. // Assignment to an empty function
  240. v4 = three;
  241. BOOST_CHECK(!v4.empty());
  242. // Invocation
  243. global_int = 0;
  244. v4();
  245. BOOST_CHECK(global_int == 3);
  246. // Assignment to a non-empty function
  247. v4 = five;
  248. // Invocation
  249. global_int = 0;
  250. v4();
  251. BOOST_CHECK(global_int == 5);
  252. // clear()
  253. v4.clear();
  254. BOOST_CHECK(v4.empty());
  255. // Assignment to an empty function from a free function
  256. v4 = &write_five;
  257. BOOST_CHECK(!v4.empty());
  258. // Invocation
  259. global_int = 0;
  260. v4();
  261. BOOST_CHECK(global_int == 5);
  262. // Assignment to a non-empty function from a free function
  263. v4 = &write_three;
  264. BOOST_CHECK(!v4.empty());
  265. // Invocation
  266. global_int = 0;
  267. v4();
  268. BOOST_CHECK(global_int == 3);
  269. // Assignment
  270. v4 = five;
  271. BOOST_CHECK(!v4.empty());
  272. // Invocation
  273. global_int = 0;
  274. v4();
  275. BOOST_CHECK(global_int == 5);
  276. // Construction of a function from a functor
  277. func_void_type v5(five);
  278. // Invocation of a function
  279. global_int = 0;
  280. v5();
  281. BOOST_CHECK(global_int == 5);
  282. // clear() method
  283. v5.clear();
  284. BOOST_CHECK(v5.empty());
  285. // Assignment to an empty function
  286. v5 = three;
  287. BOOST_CHECK(!v5.empty());
  288. // Invocation
  289. global_int = 0;
  290. v5();
  291. BOOST_CHECK(global_int == 3);
  292. // Assignment to a non-empty function
  293. v5 = five;
  294. // Invocation
  295. global_int = 0;
  296. v5();
  297. BOOST_CHECK(global_int == 5);
  298. // clear()
  299. v5.clear();
  300. BOOST_CHECK(v5.empty());
  301. // Assignment to an empty function from a free function
  302. v5 = &write_five;
  303. BOOST_CHECK(!v5.empty());
  304. // Invocation
  305. global_int = 0;
  306. v5();
  307. BOOST_CHECK(global_int == 5);
  308. // Assignment to a non-empty function from a free function
  309. v5 = &write_three;
  310. BOOST_CHECK(!v5.empty());
  311. // Invocation
  312. global_int = 0;
  313. v5();
  314. BOOST_CHECK(global_int == 3);
  315. // Assignment
  316. v5 = five;
  317. BOOST_CHECK(!v5.empty());
  318. // Invocation
  319. global_int = 0;
  320. v5();
  321. BOOST_CHECK(global_int == 5);
  322. // Construction of a function from a function
  323. func_void_type v6(&write_five);
  324. // Invocation of a function
  325. global_int = 0;
  326. v6();
  327. BOOST_CHECK(global_int == 5);
  328. // clear() method
  329. v6.clear();
  330. BOOST_CHECK(v6.empty());
  331. // Assignment to an empty function
  332. v6 = three;
  333. BOOST_CHECK(!v6.empty());
  334. // Invocation
  335. global_int = 0;
  336. v6();
  337. BOOST_CHECK(global_int == 3);
  338. // Assignment to a non-empty function
  339. v6 = five;
  340. // Invocation
  341. global_int = 0;
  342. v6();
  343. BOOST_CHECK(global_int == 5);
  344. // clear()
  345. v6.clear();
  346. BOOST_CHECK(v6.empty());
  347. // Assignment to an empty function from a free function
  348. v6 = &write_five;
  349. BOOST_CHECK(!v6.empty());
  350. // Invocation
  351. global_int = 0;
  352. v6();
  353. BOOST_CHECK(global_int == 5);
  354. // Assignment to a non-empty function from a free function
  355. v6 = &write_three;
  356. BOOST_CHECK(!v6.empty());
  357. // Invocation
  358. global_int = 0;
  359. v6();
  360. BOOST_CHECK(global_int == 3);
  361. // Assignment
  362. v6 = five;
  363. BOOST_CHECK(!v6.empty());
  364. // Invocation
  365. global_int = 0;
  366. v6();
  367. BOOST_CHECK(global_int == 5);
  368. // Const vs. non-const
  369. write_const_1_nonconst_2 one_or_two;
  370. const function<void ()> v7(one_or_two);
  371. function<void ()> v8(one_or_two);
  372. global_int = 0;
  373. v7();
  374. BOOST_CHECK(global_int == 2);
  375. global_int = 0;
  376. v8();
  377. BOOST_CHECK(global_int == 2);
  378. // Test construction from 0 and comparison to 0
  379. func_void_type v9(0);
  380. BOOST_CHECK(v9 == 0);
  381. BOOST_CHECK(0 == v9);
  382. // Test return values
  383. typedef function<int ()> func_int_type;
  384. generate_five_obj gen_five;
  385. generate_three_obj gen_three;
  386. func_int_type i0(gen_five);
  387. BOOST_CHECK(i0() == 5);
  388. i0 = gen_three;
  389. BOOST_CHECK(i0() == 3);
  390. i0 = &generate_five;
  391. BOOST_CHECK(i0() == 5);
  392. i0 = &generate_three;
  393. BOOST_CHECK(i0() == 3);
  394. BOOST_CHECK(i0? true : false);
  395. i0.clear();
  396. BOOST_CHECK(!i0? true : false);
  397. // Test return values with compatible types
  398. typedef function<long ()> func_long_type;
  399. func_long_type i1(gen_five);
  400. BOOST_CHECK(i1() == 5);
  401. i1 = gen_three;
  402. BOOST_CHECK(i1() == 3);
  403. i1 = &generate_five;
  404. BOOST_CHECK(i1() == 5);
  405. i1 = &generate_three;
  406. BOOST_CHECK(i1() == 3);
  407. BOOST_CHECK(i1? true : false);
  408. i1.clear();
  409. BOOST_CHECK(!i1? true : false);
  410. }
  411. static void
  412. test_one_arg()
  413. {
  414. std::negate<int> neg;
  415. function<int (int)> f1(neg);
  416. BOOST_CHECK(f1(5) == -5);
  417. function<string (string)> id(&identity_str);
  418. BOOST_CHECK(id("str") == "str");
  419. function<string (const char*)> id2(&identity_str);
  420. BOOST_CHECK(id2("foo") == "foo");
  421. add_to_obj add_to(5);
  422. function<int (int)> f2(add_to);
  423. BOOST_CHECK(f2(3) == 8);
  424. const function<int (int)> cf2(add_to);
  425. BOOST_CHECK(cf2(3) == 8);
  426. }
  427. static void
  428. test_two_args()
  429. {
  430. function<string (const string&, const string&)> cat(&string_cat);
  431. BOOST_CHECK(cat("str", "ing") == "string");
  432. function<int (short, short)> sum(&sum_ints);
  433. BOOST_CHECK(sum(2, 3) == 5);
  434. }
  435. static void
  436. test_emptiness()
  437. {
  438. function<float ()> f1;
  439. BOOST_CHECK(f1.empty());
  440. function<float ()> f2;
  441. f2 = f1;
  442. BOOST_CHECK(f2.empty());
  443. function<double ()> f3;
  444. f3 = f2;
  445. BOOST_CHECK(f3.empty());
  446. }
  447. struct X {
  448. X(int v) : value(v) {}
  449. int twice() const { return 2*value; }
  450. int plus(int v) { return value + v; }
  451. int value;
  452. };
  453. static void
  454. test_member_functions()
  455. {
  456. boost::function<int (X*)> f1(&X::twice);
  457. X one(1);
  458. X five(5);
  459. BOOST_CHECK(f1(&one) == 2);
  460. BOOST_CHECK(f1(&five) == 10);
  461. boost::function<int (X*)> f1_2;
  462. f1_2 = &X::twice;
  463. BOOST_CHECK(f1_2(&one) == 2);
  464. BOOST_CHECK(f1_2(&five) == 10);
  465. boost::function<int (X&, int)> f2(&X::plus);
  466. BOOST_CHECK(f2(one, 3) == 4);
  467. BOOST_CHECK(f2(five, 4) == 9);
  468. }
  469. struct add_with_throw_on_copy {
  470. int operator()(int x, int y) const { return x+y; }
  471. add_with_throw_on_copy() {}
  472. add_with_throw_on_copy(const add_with_throw_on_copy&)
  473. {
  474. throw std::runtime_error("But this CAN'T throw");
  475. }
  476. add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
  477. {
  478. throw std::runtime_error("But this CAN'T throw");
  479. }
  480. };
  481. static void
  482. test_ref()
  483. {
  484. add_with_throw_on_copy atc;
  485. try {
  486. boost::function<int (int, int)> f(boost::ref(atc));
  487. BOOST_CHECK(f(1, 3) == 4);
  488. }
  489. catch(std::runtime_error e) {
  490. BOOST_ERROR("Nonthrowing constructor threw an exception");
  491. }
  492. }
  493. static void dummy() {}
  494. static void test_empty_ref()
  495. {
  496. boost::function<void()> f1;
  497. boost::function<void()> f2(boost::ref(f1));
  498. try {
  499. f2();
  500. BOOST_ERROR("Exception didn't throw for reference to empty function.");
  501. }
  502. catch(std::runtime_error e) {}
  503. f1 = dummy;
  504. try {
  505. f2();
  506. }
  507. catch(std::runtime_error e) {
  508. BOOST_ERROR("Error calling referenced function.");
  509. }
  510. }
  511. static void test_exception()
  512. {
  513. boost::function<int (int, int)> f;
  514. try {
  515. f(5, 4);
  516. BOOST_CHECK(false);
  517. }
  518. catch(boost::bad_function_call) {
  519. // okay
  520. }
  521. }
  522. typedef boost::function< void * (void * reader) > reader_type;
  523. typedef std::pair<int, reader_type> mapped_type;
  524. static void test_implicit()
  525. {
  526. mapped_type m;
  527. m = mapped_type();
  528. }
  529. static void test_call_obj(boost::function<int (int, int)> f)
  530. {
  531. BOOST_CHECK(!f.empty());
  532. }
  533. static void test_call_cref(const boost::function<int (int, int)>& f)
  534. {
  535. BOOST_CHECK(!f.empty());
  536. }
  537. static void test_call()
  538. {
  539. test_call_obj(std::plus<int>());
  540. test_call_cref(std::plus<int>());
  541. }
  542. int test_main(int, char* [])
  543. {
  544. test_zero_args();
  545. test_one_arg();
  546. test_two_args();
  547. test_emptiness();
  548. test_member_functions();
  549. test_ref();
  550. test_empty_ref();
  551. test_exception();
  552. test_implicit();
  553. test_call();
  554. return 0;
  555. }