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