exception_test.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. // -- exception_test.cpp -- The Boost Lambda Library ------------------
  2. //
  3. // Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
  4. // Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // For more information, see www.boost.org
  11. // -----------------------------------------------------------------------
  12. #include <boost/test/minimal.hpp> // see "Header Implementation Option"
  13. #include "boost/lambda/lambda.hpp"
  14. #include "boost/lambda/exceptions.hpp"
  15. #include "boost/lambda/bind.hpp"
  16. #include<iostream>
  17. #include<algorithm>
  18. #include <cstdlib>
  19. #include <iostream>
  20. using namespace boost::lambda;
  21. using namespace std;
  22. // to prevent unused variables warnings
  23. template <class T> void dummy(const T&) {}
  24. void erroneous_exception_related_lambda_expressions() {
  25. int i = 0;
  26. dummy(i);
  27. // Uncommenting any of the below code lines should result in a compile
  28. // time error
  29. // this should fail (a rethrow binder outside of catch
  30. // rethrow()();
  31. // this should fail too for the same reason
  32. // try_catch(rethrow(), catch_all(cout << constant("Howdy")))();
  33. // this fails too (_e outside of catch_exception)
  34. // (_1 + _2 + _e)(i, i, i);
  35. // and this (_e outside of catch_exception)
  36. // try_catch( throw_exception(1), catch_all(cout << _e));
  37. // and this (_3 in catch_exception
  38. // try_catch( throw_exception(1), catch_exception<int>(cout << _3));
  39. }
  40. class A1 {};
  41. class A2 {};
  42. class A3 {};
  43. class A4 {};
  44. class A5 {};
  45. class A6 {};
  46. class A7 {};
  47. class A8 {};
  48. class A9 {};
  49. void throw_AX(int j) {
  50. int i = j;
  51. switch(i) {
  52. case 1: throw A1();
  53. case 2: throw A2();
  54. case 3: throw A3();
  55. case 4: throw A4();
  56. case 5: throw A5();
  57. case 6: throw A6();
  58. case 7: throw A7();
  59. case 8: throw A8();
  60. case 9: throw A9();
  61. }
  62. }
  63. void test_different_number_of_catch_blocks() {
  64. int ecount;
  65. // no catch(...) cases
  66. ecount = 0;
  67. for(int i=1; i<=1; i++)
  68. {
  69. try_catch(
  70. bind(throw_AX, _1),
  71. catch_exception<A1>(
  72. var(ecount)++
  73. )
  74. )(i);
  75. }
  76. BOOST_CHECK(ecount == 1);
  77. ecount = 0;
  78. for(int i=1; i<=2; i++)
  79. {
  80. try_catch(
  81. bind(throw_AX, _1),
  82. catch_exception<A1>(
  83. var(ecount)++
  84. ),
  85. catch_exception<A2>(
  86. var(ecount)++
  87. )
  88. )(i);
  89. }
  90. BOOST_CHECK(ecount == 2);
  91. ecount = 0;
  92. for(int i=1; i<=3; i++)
  93. {
  94. try_catch(
  95. bind(throw_AX, _1),
  96. catch_exception<A1>(
  97. var(ecount)++
  98. ),
  99. catch_exception<A2>(
  100. var(ecount)++
  101. ),
  102. catch_exception<A3>(
  103. var(ecount)++
  104. )
  105. )(i);
  106. }
  107. BOOST_CHECK(ecount == 3);
  108. ecount = 0;
  109. for(int i=1; i<=4; i++)
  110. {
  111. try_catch(
  112. bind(throw_AX, _1),
  113. catch_exception<A1>(
  114. var(ecount)++
  115. ),
  116. catch_exception<A2>(
  117. var(ecount)++
  118. ),
  119. catch_exception<A3>(
  120. var(ecount)++
  121. ),
  122. catch_exception<A4>(
  123. var(ecount)++
  124. )
  125. )(i);
  126. }
  127. BOOST_CHECK(ecount == 4);
  128. ecount = 0;
  129. for(int i=1; i<=5; i++)
  130. {
  131. try_catch(
  132. bind(throw_AX, _1),
  133. catch_exception<A1>(
  134. var(ecount)++
  135. ),
  136. catch_exception<A2>(
  137. var(ecount)++
  138. ),
  139. catch_exception<A3>(
  140. var(ecount)++
  141. ),
  142. catch_exception<A4>(
  143. var(ecount)++
  144. ),
  145. catch_exception<A5>(
  146. var(ecount)++
  147. )
  148. )(i);
  149. }
  150. BOOST_CHECK(ecount == 5);
  151. ecount = 0;
  152. for(int i=1; i<=6; i++)
  153. {
  154. try_catch(
  155. bind(throw_AX, _1),
  156. catch_exception<A1>(
  157. var(ecount)++
  158. ),
  159. catch_exception<A2>(
  160. var(ecount)++
  161. ),
  162. catch_exception<A3>(
  163. var(ecount)++
  164. ),
  165. catch_exception<A4>(
  166. var(ecount)++
  167. ),
  168. catch_exception<A5>(
  169. var(ecount)++
  170. ),
  171. catch_exception<A6>(
  172. var(ecount)++
  173. )
  174. )(i);
  175. }
  176. BOOST_CHECK(ecount == 6);
  177. ecount = 0;
  178. for(int i=1; i<=7; i++)
  179. {
  180. try_catch(
  181. bind(throw_AX, _1),
  182. catch_exception<A1>(
  183. var(ecount)++
  184. ),
  185. catch_exception<A2>(
  186. var(ecount)++
  187. ),
  188. catch_exception<A3>(
  189. var(ecount)++
  190. ),
  191. catch_exception<A4>(
  192. var(ecount)++
  193. ),
  194. catch_exception<A5>(
  195. var(ecount)++
  196. ),
  197. catch_exception<A6>(
  198. var(ecount)++
  199. ),
  200. catch_exception<A7>(
  201. var(ecount)++
  202. )
  203. )(i);
  204. }
  205. BOOST_CHECK(ecount == 7);
  206. ecount = 0;
  207. for(int i=1; i<=8; i++)
  208. {
  209. try_catch(
  210. bind(throw_AX, _1),
  211. catch_exception<A1>(
  212. var(ecount)++
  213. ),
  214. catch_exception<A2>(
  215. var(ecount)++
  216. ),
  217. catch_exception<A3>(
  218. var(ecount)++
  219. ),
  220. catch_exception<A4>(
  221. var(ecount)++
  222. ),
  223. catch_exception<A5>(
  224. var(ecount)++
  225. ),
  226. catch_exception<A6>(
  227. var(ecount)++
  228. ),
  229. catch_exception<A7>(
  230. var(ecount)++
  231. ),
  232. catch_exception<A8>(
  233. var(ecount)++
  234. )
  235. )(i);
  236. }
  237. BOOST_CHECK(ecount == 8);
  238. ecount = 0;
  239. for(int i=1; i<=9; i++)
  240. {
  241. try_catch(
  242. bind(throw_AX, _1),
  243. catch_exception<A1>(
  244. var(ecount)++
  245. ),
  246. catch_exception<A2>(
  247. var(ecount)++
  248. ),
  249. catch_exception<A3>(
  250. var(ecount)++
  251. ),
  252. catch_exception<A4>(
  253. var(ecount)++
  254. ),
  255. catch_exception<A5>(
  256. var(ecount)++
  257. ),
  258. catch_exception<A6>(
  259. var(ecount)++
  260. ),
  261. catch_exception<A7>(
  262. var(ecount)++
  263. ),
  264. catch_exception<A8>(
  265. var(ecount)++
  266. ),
  267. catch_exception<A9>(
  268. var(ecount)++
  269. )
  270. )(i);
  271. }
  272. BOOST_CHECK(ecount == 9);
  273. // with catch(...) blocks
  274. ecount = 0;
  275. for(int i=1; i<=1; i++)
  276. {
  277. try_catch(
  278. bind(throw_AX, _1),
  279. catch_all(
  280. var(ecount)++
  281. )
  282. )(i);
  283. }
  284. BOOST_CHECK(ecount == 1);
  285. ecount = 0;
  286. for(int i=1; i<=2; i++)
  287. {
  288. try_catch(
  289. bind(throw_AX, _1),
  290. catch_exception<A1>(
  291. var(ecount)++
  292. ),
  293. catch_all(
  294. var(ecount)++
  295. )
  296. )(i);
  297. }
  298. BOOST_CHECK(ecount == 2);
  299. ecount = 0;
  300. for(int i=1; i<=3; i++)
  301. {
  302. try_catch(
  303. bind(throw_AX, _1),
  304. catch_exception<A1>(
  305. var(ecount)++
  306. ),
  307. catch_exception<A2>(
  308. var(ecount)++
  309. ),
  310. catch_all(
  311. var(ecount)++
  312. )
  313. )(i);
  314. }
  315. BOOST_CHECK(ecount == 3);
  316. ecount = 0;
  317. for(int i=1; i<=4; i++)
  318. {
  319. try_catch(
  320. bind(throw_AX, _1),
  321. catch_exception<A1>(
  322. var(ecount)++
  323. ),
  324. catch_exception<A2>(
  325. var(ecount)++
  326. ),
  327. catch_exception<A3>(
  328. var(ecount)++
  329. ),
  330. catch_all(
  331. var(ecount)++
  332. )
  333. )(i);
  334. }
  335. BOOST_CHECK(ecount == 4);
  336. ecount = 0;
  337. for(int i=1; i<=5; i++)
  338. {
  339. try_catch(
  340. bind(throw_AX, _1),
  341. catch_exception<A1>(
  342. var(ecount)++
  343. ),
  344. catch_exception<A2>(
  345. var(ecount)++
  346. ),
  347. catch_exception<A3>(
  348. var(ecount)++
  349. ),
  350. catch_exception<A4>(
  351. var(ecount)++
  352. ),
  353. catch_all(
  354. var(ecount)++
  355. )
  356. )(i);
  357. }
  358. BOOST_CHECK(ecount == 5);
  359. ecount = 0;
  360. for(int i=1; i<=6; i++)
  361. {
  362. try_catch(
  363. bind(throw_AX, _1),
  364. catch_exception<A1>(
  365. var(ecount)++
  366. ),
  367. catch_exception<A2>(
  368. var(ecount)++
  369. ),
  370. catch_exception<A3>(
  371. var(ecount)++
  372. ),
  373. catch_exception<A4>(
  374. var(ecount)++
  375. ),
  376. catch_exception<A5>(
  377. var(ecount)++
  378. ),
  379. catch_all(
  380. var(ecount)++
  381. )
  382. )(i);
  383. }
  384. BOOST_CHECK(ecount == 6);
  385. ecount = 0;
  386. for(int i=1; i<=7; i++)
  387. {
  388. try_catch(
  389. bind(throw_AX, _1),
  390. catch_exception<A1>(
  391. var(ecount)++
  392. ),
  393. catch_exception<A2>(
  394. var(ecount)++
  395. ),
  396. catch_exception<A3>(
  397. var(ecount)++
  398. ),
  399. catch_exception<A4>(
  400. var(ecount)++
  401. ),
  402. catch_exception<A5>(
  403. var(ecount)++
  404. ),
  405. catch_exception<A6>(
  406. var(ecount)++
  407. ),
  408. catch_all(
  409. var(ecount)++
  410. )
  411. )(i);
  412. }
  413. BOOST_CHECK(ecount == 7);
  414. ecount = 0;
  415. for(int i=1; i<=8; i++)
  416. {
  417. try_catch(
  418. bind(throw_AX, _1),
  419. catch_exception<A1>(
  420. var(ecount)++
  421. ),
  422. catch_exception<A2>(
  423. var(ecount)++
  424. ),
  425. catch_exception<A3>(
  426. var(ecount)++
  427. ),
  428. catch_exception<A4>(
  429. var(ecount)++
  430. ),
  431. catch_exception<A5>(
  432. var(ecount)++
  433. ),
  434. catch_exception<A6>(
  435. var(ecount)++
  436. ),
  437. catch_exception<A7>(
  438. var(ecount)++
  439. ),
  440. catch_all(
  441. var(ecount)++
  442. )
  443. )(i);
  444. }
  445. BOOST_CHECK(ecount == 8);
  446. ecount = 0;
  447. for(int i=1; i<=9; i++)
  448. {
  449. try_catch(
  450. bind(throw_AX, _1),
  451. catch_exception<A1>(
  452. var(ecount)++
  453. ),
  454. catch_exception<A2>(
  455. var(ecount)++
  456. ),
  457. catch_exception<A3>(
  458. var(ecount)++
  459. ),
  460. catch_exception<A4>(
  461. var(ecount)++
  462. ),
  463. catch_exception<A5>(
  464. var(ecount)++
  465. ),
  466. catch_exception<A6>(
  467. var(ecount)++
  468. ),
  469. catch_exception<A7>(
  470. var(ecount)++
  471. ),
  472. catch_exception<A8>(
  473. var(ecount)++
  474. ),
  475. catch_all(
  476. var(ecount)++
  477. )
  478. )(i);
  479. }
  480. BOOST_CHECK(ecount == 9);
  481. }
  482. void test_empty_catch_blocks() {
  483. try_catch(
  484. bind(throw_AX, _1),
  485. catch_exception<A1>()
  486. )(make_const(1));
  487. try_catch(
  488. bind(throw_AX, _1),
  489. catch_all()
  490. )(make_const(1));
  491. }
  492. void return_type_matching() {
  493. // Rules for return types of the lambda functors in try and catch parts:
  494. // 1. The try part dictates the return type of the whole
  495. // try_catch lambda functor
  496. // 2. If return type of try part is void, catch parts can return anything,
  497. // but the return types are ignored
  498. // 3. If the return type of the try part is A, then each catch return type
  499. // must be implicitly convertible to A, or then it must throw for sure
  500. int i = 1;
  501. BOOST_CHECK(
  502. try_catch(
  503. _1 + 1,
  504. catch_exception<int>((&_1, rethrow())), // no match, but ok since throws
  505. catch_exception<char>(_e) // ok, char convertible to int
  506. )(i)
  507. == 2
  508. );
  509. // note that while e.g. char is convertible to int, it is not convertible
  510. // to int&, (some lambda functors return references)
  511. // try_catch(
  512. // _1 += 1,
  513. // catch_exception<char>(_e) // NOT ok, char not convertible to int&
  514. // )(i);
  515. // if you don't care about the return type, you can use make_void
  516. try_catch(
  517. make_void(_1 += 1),
  518. catch_exception<char>(_e) // since try is void, catch can return anything
  519. )(i);
  520. BOOST_CHECK(i == 2);
  521. try_catch(
  522. (_1 += 1, throw_exception('a')),
  523. catch_exception<char>(_e) // since try throws, it is void,
  524. // so catch can return anything
  525. )(i);
  526. BOOST_CHECK(i == 3);
  527. char a = 'a';
  528. try_catch(
  529. try_catch(
  530. throw_exception(1),
  531. catch_exception<int>(throw_exception('b'))
  532. ),
  533. catch_exception<char>( _1 = _e )
  534. )(a);
  535. BOOST_CHECK(a == 'b');
  536. }
  537. int test_main(int, char *[]) {
  538. try
  539. {
  540. test_different_number_of_catch_blocks();
  541. return_type_matching();
  542. test_empty_catch_blocks();
  543. }
  544. catch (int)
  545. {
  546. BOOST_CHECK(false);
  547. }
  548. catch(...)
  549. {
  550. BOOST_CHECK(false);
  551. }
  552. return EXIT_SUCCESS;
  553. }