/usr/include/boost/lambda
Edit: /usr/include/boost/lambda/exceptions.hpp (59796B)
// -- Boost Lambda Library -- exceptions.hpp ----------------
//
// Copyright (C) 2000 Gary Powell (gwpowell@hotmail.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// 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 http://www.boost.org
// -----------------------------------------------------
#if !defined(BOOST_LAMBDA_EXCEPTIONS_HPP)
#define BOOST_LAMBDA_EXCEPTIONS_HPP
#include "boost/lambda/core.hpp"
#include "boost/lambda/detail/control_constructs_common.hpp"
namespace boost {
namespace lambda {
typedef lambda_functor
> placeholderE_type;
namespace {
boost::lambda::placeholderE_type freeE;
boost::lambda::placeholderE_type& _e = freeE;
}
// -- exception related actions -------------------
// catch actions.
template
struct catch_action {};
struct catch_all_action {};
template
struct return_try_catch_action {};
template
struct try_catch_action {};
// rethrow actions
struct throw_new_action {};
struct rethrow_action {};
template struct throw_action;
template<>
struct throw_action {
template
static RET apply() {
throw;
}
};
template<> struct throw_action {
template
static RET apply(T& t) {
throw t;
}
};
// return types for throw_actions --------------------------------------------
template
struct
return_type_N, Any> {
typedef void type;
};
// return types deductions -------------------------------------------------
// the return type of try_catch is the return type of the try lambda_functor
// (the return types of try and catch parts must match unless try returns void
// or the catch part throws for sure)
// NOTE, the exception placeholder deduction rule is defined
// in return_type_traits.hpp
// defined in control_constructs
class ifthenelse_action;
namespace detail {
// Templates for deducing, wether a lambda_functor throws inevitably of not -
// This mechanism is needed to make the compiler happy about
// return types of try and catch parts.
// a lambda_functor throws for sure if:
// - it is a throw expression
// - it is a comma expression, and one of its arguments throws for sure
// - it is an if_then_else expression and either the if statement or both
// the then and else throw.
// (there are other cases as well, but we do not cover them)
// e.g. _1 + (rethrow(), 3) does throw for sure but this is not checked
// This implies, that in such a case, the return types of try and catch parts
// must match if the try part returns other than void.
// (Such checks could be done though)
template
struct throws_for_sure_phase2 {
static const bool value = false;
};
template
struct throws_for_sure_phase2<
lambda_functor<
lambda_functor_base >, Args>
>
>
{
static const bool value = true;
};
// Both then and else or the if throw of an if_then_else.
template
struct throws_for_sure_phase2<
lambda_functor<
lambda_functor_base<
ifthenelse_action, Args
>
>
>
{
static const bool value =
throws_for_sure_phase2<
typename boost::tuples::element<0, Args>::type>::value
||
(
throws_for_sure_phase2<
typename boost::tuples::element<1, Args>::type
>::value
&&
throws_for_sure_phase2<
typename boost::tuples::element<2, Args>::type
>::value
);
};
template
struct throws_for_sure_phase2<
lambda_functor<
lambda_functor_base< other_action, Args>
>
>
{
static const bool value =
throws_for_sure_phase2<
typename boost::tuples::element<0, Args>::type
>::value
||
throws_for_sure_phase2<
typename boost::tuples::element<1, Args>::type
>::value;
};
// get rid of any qualifiers and references
// lambda_functors should be stored like that, so this is to be extra sure
template
struct throws_for_sure {
static const bool value
= throws_for_sure_phase2<
typename detail::remove_reference_and_cv::type
>::value;
};
// -- return_or_throw templates -----------------------------
// false case, catch and try return types are incompatible
// Now the catch part must throw for sure, otherwise a compile time error
// occurs.
template
struct return_or_throw_phase2 {
template
static RET call(Arg& arg, CALL_FORMAL_ARGS) {
BOOST_STATIC_ASSERT(throws_for_sure::value);
detail::select(arg, CALL_ACTUAL_ARGS); // this line throws
throw 1; // this line is never performed, hence 1 is just a dummy
// The line is needed to make compiler happy and not require
// a matching return type
}
};
// the try and catch return types are compatible
template<>
struct return_or_throw_phase2 {
template
static RET call(Arg& arg, CALL_FORMAL_ARGS) {
return detail::select(arg, CALL_ACTUAL_ARGS);
}
};
// the non-void case. Try part returns a value, so catch parts must
// return a value of the same type or throw
template
struct return_or_throw {
// Arg should be equal to ARG except that ARG may be a reference
// to be sure, that there are no suprises for peculiarly defined return types
// ARG is passed explicitely
template
static RET call(Arg& arg, CALL_FORMAL_ARGS)
{
// typedef typename Arg::return_type >::type RT;
typedef typename as_lambda_functor::type lf_type;
typedef typename lf_type::inherited::template
sig >::type RT;
return
return_or_throw_phase2<
::boost::is_convertible