123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621 |
- // -- exception_test.cpp -- The Boost Lambda Library ------------------
- //
- // Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
- // Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
- //
- // Distributed under 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 www.boost.org
- // -----------------------------------------------------------------------
- #include <boost/test/minimal.hpp> // see "Header Implementation Option"
- #include "boost/lambda/lambda.hpp"
- #include "boost/lambda/exceptions.hpp"
- #include "boost/lambda/bind.hpp"
- #include<iostream>
- #include<algorithm>
- #include <cstdlib>
- #include <iostream>
- using namespace boost::lambda;
- using namespace std;
- // to prevent unused variables warnings
- template <class T> void dummy(const T&) {}
- void erroneous_exception_related_lambda_expressions() {
- int i = 0;
- dummy(i);
- // Uncommenting any of the below code lines should result in a compile
- // time error
- // this should fail (a rethrow binder outside of catch
- // rethrow()();
-
- // this should fail too for the same reason
- // try_catch(rethrow(), catch_all(cout << constant("Howdy")))();
- // this fails too (_e outside of catch_exception)
- // (_1 + _2 + _e)(i, i, i);
- // and this (_e outside of catch_exception)
- // try_catch( throw_exception(1), catch_all(cout << _e));
- // and this (_3 in catch_exception
- // try_catch( throw_exception(1), catch_exception<int>(cout << _3));
- }
- class A1 {};
- class A2 {};
- class A3 {};
- class A4 {};
- class A5 {};
- class A6 {};
- class A7 {};
- class A8 {};
- class A9 {};
- void throw_AX(int j) {
- int i = j;
- switch(i) {
- case 1: throw A1();
- case 2: throw A2();
- case 3: throw A3();
- case 4: throw A4();
- case 5: throw A5();
- case 6: throw A6();
- case 7: throw A7();
- case 8: throw A8();
- case 9: throw A9();
- }
- }
- void test_different_number_of_catch_blocks() {
- int ecount;
- // no catch(...) cases
- ecount = 0;
- for(int i=1; i<=1; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 1);
- ecount = 0;
- for(int i=1; i<=2; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 2);
- ecount = 0;
- for(int i=1; i<=3; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 3);
- ecount = 0;
- for(int i=1; i<=4; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 4);
- ecount = 0;
- for(int i=1; i<=5; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 5);
- ecount = 0;
- for(int i=1; i<=6; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- ),
- catch_exception<A6>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 6);
- ecount = 0;
- for(int i=1; i<=7; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- ),
- catch_exception<A6>(
- var(ecount)++
- ),
- catch_exception<A7>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 7);
- ecount = 0;
- for(int i=1; i<=8; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- ),
- catch_exception<A6>(
- var(ecount)++
- ),
- catch_exception<A7>(
- var(ecount)++
- ),
- catch_exception<A8>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 8);
- ecount = 0;
- for(int i=1; i<=9; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- ),
- catch_exception<A6>(
- var(ecount)++
- ),
- catch_exception<A7>(
- var(ecount)++
- ),
- catch_exception<A8>(
- var(ecount)++
- ),
- catch_exception<A9>(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 9);
- // with catch(...) blocks
- ecount = 0;
- for(int i=1; i<=1; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 1);
- ecount = 0;
- for(int i=1; i<=2; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 2);
- ecount = 0;
- for(int i=1; i<=3; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 3);
- ecount = 0;
- for(int i=1; i<=4; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 4);
- ecount = 0;
- for(int i=1; i<=5; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 5);
- ecount = 0;
- for(int i=1; i<=6; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- ),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 6);
- ecount = 0;
- for(int i=1; i<=7; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- ),
- catch_exception<A6>(
- var(ecount)++
- ),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 7);
- ecount = 0;
- for(int i=1; i<=8; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- ),
- catch_exception<A6>(
- var(ecount)++
- ),
- catch_exception<A7>(
- var(ecount)++
- ),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 8);
- ecount = 0;
- for(int i=1; i<=9; i++)
- {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>(
- var(ecount)++
- ),
- catch_exception<A2>(
- var(ecount)++
- ),
- catch_exception<A3>(
- var(ecount)++
- ),
- catch_exception<A4>(
- var(ecount)++
- ),
- catch_exception<A5>(
- var(ecount)++
- ),
- catch_exception<A6>(
- var(ecount)++
- ),
- catch_exception<A7>(
- var(ecount)++
- ),
- catch_exception<A8>(
- var(ecount)++
- ),
- catch_all(
- var(ecount)++
- )
- )(i);
- }
- BOOST_CHECK(ecount == 9);
- }
- void test_empty_catch_blocks() {
- try_catch(
- bind(throw_AX, _1),
- catch_exception<A1>()
- )(make_const(1));
- try_catch(
- bind(throw_AX, _1),
- catch_all()
- )(make_const(1));
- }
- void return_type_matching() {
- // Rules for return types of the lambda functors in try and catch parts:
- // 1. The try part dictates the return type of the whole
- // try_catch lambda functor
- // 2. If return type of try part is void, catch parts can return anything,
- // but the return types are ignored
- // 3. If the return type of the try part is A, then each catch return type
- // must be implicitly convertible to A, or then it must throw for sure
- int i = 1;
-
- BOOST_CHECK(
-
- try_catch(
- _1 + 1,
- catch_exception<int>((&_1, rethrow())), // no match, but ok since throws
- catch_exception<char>(_e) // ok, char convertible to int
- )(i)
-
- == 2
- );
-
- // note that while e.g. char is convertible to int, it is not convertible
- // to int&, (some lambda functors return references)
-
- // try_catch(
- // _1 += 1,
- // catch_exception<char>(_e) // NOT ok, char not convertible to int&
- // )(i);
- // if you don't care about the return type, you can use make_void
- try_catch(
- make_void(_1 += 1),
- catch_exception<char>(_e) // since try is void, catch can return anything
- )(i);
- BOOST_CHECK(i == 2);
-
- try_catch(
- (_1 += 1, throw_exception('a')),
- catch_exception<char>(_e) // since try throws, it is void,
- // so catch can return anything
- )(i);
- BOOST_CHECK(i == 3);
- char a = 'a';
- try_catch(
- try_catch(
- throw_exception(1),
- catch_exception<int>(throw_exception('b'))
- ),
- catch_exception<char>( _1 = _e )
- )(a);
- BOOST_CHECK(a == 'b');
- }
-
- int test_main(int, char *[]) {
- try
- {
- test_different_number_of_catch_blocks();
- return_type_matching();
- test_empty_catch_blocks();
- }
- catch (int)
- {
- BOOST_CHECK(false);
- }
- catch(...)
- {
- BOOST_CHECK(false);
- }
- return EXIT_SUCCESS;
- }
|