diff options
Diffstat (limited to 'src/boost/libs/lambda/test/exception_test.cpp')
-rw-r--r-- | src/boost/libs/lambda/test/exception_test.cpp | 618 |
1 files changed, 618 insertions, 0 deletions
diff --git a/src/boost/libs/lambda/test/exception_test.cpp b/src/boost/libs/lambda/test/exception_test.cpp new file mode 100644 index 000000000..661541f30 --- /dev/null +++ b/src/boost/libs/lambda/test/exception_test.cpp @@ -0,0 +1,618 @@ +// -- 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/core/lightweight_test.hpp> +#define BOOST_CHECK BOOST_TEST + +#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 main() { + + try + { + test_different_number_of_catch_blocks(); + return_type_matching(); + test_empty_catch_blocks(); + } + catch (int) + { + BOOST_CHECK(false); + } + catch(...) + { + BOOST_CHECK(false); + } + + + return boost::report_errors(); +} |