summaryrefslogtreecommitdiff
path: root/boost/phoenix/statement/try_catch.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/phoenix/statement/try_catch.hpp')
-rw-r--r--boost/phoenix/statement/try_catch.hpp182
1 files changed, 169 insertions, 13 deletions
diff --git a/boost/phoenix/statement/try_catch.hpp b/boost/phoenix/statement/try_catch.hpp
index a7ea8bf4b3..eb75e2aa63 100644
--- a/boost/phoenix/statement/try_catch.hpp
+++ b/boost/phoenix/statement/try_catch.hpp
@@ -15,7 +15,10 @@
#include <boost/phoenix/core/expression.hpp>
#include <boost/phoenix/core/meta_grammar.hpp>
#include <boost/phoenix/core/is_nullary.hpp>
+#include <boost/phoenix/scope/local_variable.hpp>
+#include <boost/phoenix/scope/scoped_environment.hpp>
#include <boost/proto/functional/fusion/pop_front.hpp>
+#include <boost/core/enable_if.hpp>
#ifdef _MSC_VER
#pragma warning(push)
@@ -52,8 +55,13 @@ namespace boost { namespace phoenix
// bring in the expression definitions
#include <boost/phoenix/statement/detail/try_catch_expression.hpp>
- template <typename A0, typename A1>
+ template <typename A0, typename A1, typename A2 = void>
struct catch_
+ : proto::nary_expr<tag::catch_, A0, A1, A2>
+ {};
+
+ template <typename A0, typename A1>
+ struct catch_<A0, A1, void>
: proto::binary_expr<tag::catch_, A0, A1>
{};
@@ -65,11 +73,26 @@ namespace boost { namespace phoenix
namespace rule
{
- struct catch_
- : expression::catch_<
+ typedef
+ expression::catch_<
proto::terminal<catch_exception<proto::_> >
+ , local_variable
, meta_grammar
>
+ captured_catch;
+
+ typedef
+ expression::catch_<
+ proto::terminal<catch_exception<proto::_> >
+ , meta_grammar
+ >
+ non_captured_catch;
+
+ struct catch_
+ : proto::or_<
+ captured_catch
+ , non_captured_catch
+ >
{};
struct catch_all
@@ -110,6 +133,48 @@ namespace boost { namespace phoenix
void operator()(Try const &, Context const &) const
{}
+ template <typename Catch, typename Exception, typename Context>
+ typename enable_if<proto::matches<Catch, rule::non_captured_catch> >::type
+ eval_catch_body(Catch const &c, Exception & /*unused*/, Context const &ctx) const
+ {
+ phoenix::eval(proto::child_c<1>(c), ctx);
+ }
+
+ template <typename Catch, typename Exception, typename Context>
+ typename enable_if<proto::matches<Catch, rule::captured_catch> >::type
+ eval_catch_body(Catch const &c, Exception &e, Context const &ctx) const
+ {
+ typedef
+ typename proto::detail::uncvref<
+ typename proto::result_of::value<
+ typename proto::result_of::child_c<Catch, 1>::type
+ >::type
+ >::type
+ capture_type;
+ typedef
+ typename proto::detail::uncvref<
+ typename result_of::env<Context>::type
+ >::type
+ env_type;
+ typedef vector1<Exception &> local_type;
+ typedef detail::map_local_index_to_tuple<capture_type> map_type;
+
+ typedef
+ phoenix::scoped_environment<
+ env_type
+ , env_type
+ , local_type
+ , map_type
+ >
+ scoped_env_tpe;
+
+ local_type local = {e};
+
+ scoped_env_tpe env(phoenix::env(ctx), phoenix::env(ctx), local);
+
+ phoenix::eval(proto::child_c<2>(c), phoenix::context(env, phoenix::actions(ctx)));
+ }
+
// bring in the operator overloads
#include <boost/phoenix/statement/detail/try_catch_eval.hpp>
};
@@ -135,12 +200,31 @@ namespace boost { namespace phoenix
>
, proto::when<
phoenix::rule::catch_
- , proto::call<
- evaluator(
- proto::_child_c<1>
- , proto::_data
- , proto::make<proto::empty_env()>
- )
+ , proto::or_<
+ proto::when<
+ phoenix::rule::captured_catch
+ , proto::call<
+ evaluator(
+ proto::_child_c<2>
+ , proto::call<
+ phoenix::functional::context(
+ proto::make<mpl::true_()>
+ , proto::make<detail::scope_is_nullary_actions()>
+ )
+ >
+ , proto::make<proto::empty_env()>
+ )
+ >
+ >
+ , proto::otherwise<
+ proto::call<
+ evaluator(
+ proto::_child_c<1>
+ , proto::_data
+ , proto::make<proto::empty_env()>
+ )
+ >
+ >
>
>
, proto::when<
@@ -181,13 +265,48 @@ namespace boost { namespace phoenix
template <
typename TryCatch
, typename Exception
+ , typename Capture
, typename Expr
, long Arity = proto::arity_of<TryCatch>::value
>
struct catch_push_back;
+ template <typename TryCatch, typename Exception, typename Capture, typename Expr>
+ struct catch_push_back<TryCatch, Exception, Capture, Expr, 1>
+ {
+ typedef
+ typename proto::result_of::make_expr<
+ phoenix::tag::catch_
+ , proto::basic_default_domain
+ , catch_exception<Exception>
+ , Capture
+ , Expr
+ >::type
+ catch_expr;
+
+ typedef
+ phoenix::expression::try_catch<
+ TryCatch
+ , catch_expr
+ >
+ gen_type;
+ typedef typename gen_type::type type;
+
+ static type make(TryCatch const & try_catch, Capture const & capture, Expr const & catch_)
+ {
+ return
+ gen_type::make(
+ try_catch
+ , proto::make_expr<
+ phoenix::tag::catch_
+ , proto::basic_default_domain
+ >(catch_exception<Exception>(), capture, catch_)
+ );
+ }
+ };
+
template <typename TryCatch, typename Exception, typename Expr>
- struct catch_push_back<TryCatch, Exception, Expr, 1>
+ struct catch_push_back<TryCatch, Exception, void, Expr, 1>
{
typedef
typename proto::result_of::make_expr<
@@ -271,9 +390,39 @@ namespace boost { namespace phoenix
>
{};
- template <typename TryCatch, typename Exception>
+ template <typename TryCatch, typename Exception, typename Capture = void>
struct catch_gen
{
+ catch_gen(TryCatch const& try_catch_, Capture const& capture)
+ : try_catch(try_catch_)
+ , capture(capture) {}
+
+ template <typename Expr>
+ typename boost::disable_if<
+ proto::matches<
+ typename proto::result_of::child_c<
+ TryCatch
+ , proto::arity_of<TryCatch>::value - 1
+ >::type
+ , rule::catch_all
+ >
+ , typename detail::catch_push_back<TryCatch, Exception, Capture, Expr>::type
+ >::type
+ operator[](Expr const& expr) const
+ {
+ return
+ detail::catch_push_back<TryCatch, Exception, Capture, Expr>::make(
+ try_catch, capture, expr
+ );
+ }
+
+ TryCatch const & try_catch;
+ Capture const & capture;
+ };
+
+ template <typename TryCatch, typename Exception>
+ struct catch_gen<TryCatch, Exception, void>
+ {
catch_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {}
template <typename Expr>
@@ -285,12 +434,12 @@ namespace boost { namespace phoenix
>::type
, rule::catch_all
>
- , typename detail::catch_push_back<TryCatch, Exception, Expr>::type
+ , typename detail::catch_push_back<TryCatch, Exception, void, Expr>::type
>::type
operator[](Expr const& expr) const
{
return
- detail::catch_push_back<TryCatch, Exception, Expr>::make(
+ detail::catch_push_back<TryCatch, Exception, void, Expr>::make(
try_catch, expr
);
}
@@ -349,6 +498,13 @@ namespace boost { namespace phoenix
return catch_gen<that_type, Exception>(*this);
}
+ template <typename Exception, typename Capture>
+ catch_gen<that_type, Exception, Capture> const
+ catch_(Capture const &expr) const
+ {
+ return catch_gen<that_type, Exception, Capture>(*this, expr);
+ }
+
catch_all_gen<that_type> const catch_all;
};