1 /*==============================================================================
2 Copyright (c) 2005-2007 Dan Marsden
3 Copyright (c) 2005-2010 Joel de Guzman
4 Copyright (c) 2010 Thomas Heller
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
10 #ifndef BOOST_PHOENIX_STATEMENT_TRY_CATCH_HPP
11 #define BOOST_PHOENIX_STATEMENT_TRY_CATCH_HPP
13 #include <boost/phoenix/config.hpp>
14 #include <boost/phoenix/core/limits.hpp>
15 #include <boost/phoenix/core/call.hpp>
16 #include <boost/phoenix/core/expression.hpp>
17 #include <boost/phoenix/core/meta_grammar.hpp>
18 #include <boost/phoenix/core/is_nullary.hpp>
19 #include <boost/phoenix/scope/local_variable.hpp>
20 #include <boost/phoenix/scope/scoped_environment.hpp>
21 #include <boost/proto/functional/fusion/pop_front.hpp>
22 #include <boost/core/enable_if.hpp>
26 #pragma warning(disable: 4355) // 'this' : used in base member initializer list
29 namespace boost { namespace phoenix
31 template <typename Expr>
32 struct try_catch_actor;
34 template <typename Exception>
35 struct catch_exception
37 typedef Exception type;
51 , BOOST_PHOENIX_typename_A_void(BOOST_PHOENIX_CATCH_LIMIT)
52 , typename Dummy = void
56 // bring in the expression definitions
57 #include <boost/phoenix/statement/detail/try_catch_expression.hpp>
59 template <typename A0, typename A1, typename A2 = void>
61 : proto::nary_expr<tag::catch_, A0, A1, A2>
64 template <typename A0, typename A1>
65 struct catch_<A0, A1, void>
66 : proto::binary_expr<tag::catch_, A0, A1>
69 template <typename A0>
71 : proto::unary_expr<tag::catch_all, A0>
79 proto::terminal<catch_exception<proto::_> >
87 proto::terminal<catch_exception<proto::_> >
100 : expression::catch_all<
107 expression::try_catch<
109 , proto::vararg<rule::catch_>
111 , expression::try_catch<
115 , expression::try_catch<
117 , proto::vararg<rule::catch_>
124 template <typename Dummy>
125 struct meta_grammar::case_<tag::try_catch, Dummy>
126 : enable_rule<rule::try_catch, Dummy>
129 struct try_catch_eval
131 typedef void result_type;
133 template <typename Try, typename Context>
134 void operator()(Try const &, Context const &) const
137 template <typename Catch, typename Exception, typename Context>
138 typename enable_if<proto::matches<Catch, rule::non_captured_catch> >::type
139 eval_catch_body(Catch const &c, Exception & /*unused*/, Context const &ctx
140 BOOST_PHOENIX_SFINAE_AND_OVERLOADS) const
142 phoenix::eval(proto::child_c<1>(c), ctx);
145 template <typename Catch, typename Exception, typename Context>
146 typename enable_if<proto::matches<Catch, rule::captured_catch> >::type
147 eval_catch_body(Catch const &c, Exception &e, Context const &ctx) const
150 typename proto::detail::uncvref<
151 typename proto::result_of::value<
152 typename proto::result_of::child_c<Catch, 1>::type
157 typename proto::detail::uncvref<
158 typename result_of::env<Context>::type
161 typedef vector1<Exception &> local_type;
162 typedef detail::map_local_index_to_tuple<capture_type> map_type;
165 phoenix::scoped_environment<
173 local_type local = {e};
175 scoped_env_tpe env(phoenix::env(ctx), phoenix::env(ctx), local);
177 phoenix::eval(proto::child_c<2>(c), phoenix::context(env, phoenix::actions(ctx)));
180 // bring in the operator overloads
181 #include <boost/phoenix/statement/detail/try_catch_eval.hpp>
184 template <typename Dummy>
185 struct default_actions::when<rule::try_catch, Dummy>
186 : call<try_catch_eval, Dummy>
191 struct try_catch_is_nullary
194 phoenix::rule::catch_all
199 , proto::make<proto::empty_env()>
204 phoenix::rule::catch_
207 phoenix::rule::captured_catch
212 phoenix::functional::context(
213 proto::make<mpl::true_()>
214 , proto::make<detail::scope_is_nullary_actions()>
217 , proto::make<proto::empty_env()>
226 , proto::make<proto::empty_env()>
233 phoenix::rule::try_catch
240 , proto::make<proto::empty_env()>
245 proto::functional::pop_front(proto::_)
247 , proto::make<mpl::true_()>
252 try_catch_is_nullary(
254 , proto::make<proto::empty_env()>
272 , long Arity = proto::arity_of<TryCatch>::value
274 struct catch_push_back;
276 template <typename TryCatch, typename Exception, typename Capture, typename Expr>
277 struct catch_push_back<TryCatch, Exception, Capture, Expr, 1>
280 typename proto::result_of::make_expr<
282 , proto::basic_default_domain
283 , catch_exception<Exception>
290 phoenix::expression::try_catch<
295 typedef typename gen_type::type type;
297 static type make(TryCatch const & try_catch, Capture const & capture, Expr const & catch_)
304 , proto::basic_default_domain
305 >(catch_exception<Exception>(), capture, catch_)
310 template <typename TryCatch, typename Exception, typename Expr>
311 struct catch_push_back<TryCatch, Exception, void, Expr, 1>
314 typename proto::result_of::make_expr<
316 , proto::basic_default_domain
317 , catch_exception<Exception>
323 phoenix::expression::try_catch<
328 typedef typename gen_type::type type;
330 static type make(TryCatch const & try_catch, Expr const & catch_)
337 , proto::basic_default_domain
338 >(catch_exception<Exception>(), catch_)
346 , long Arity = proto::arity_of<TryCatch>::value
348 struct catch_all_push_back;
350 template <typename TryCatch, typename Expr>
351 struct catch_all_push_back<TryCatch, Expr, 1>
354 typename proto::result_of::make_expr<
355 phoenix::tag::catch_all
356 , proto::basic_default_domain
362 phoenix::expression::try_catch<
367 typedef typename gen_type::type type;
369 static type make(TryCatch const& try_catch, Expr const& catch_)
375 phoenix::tag::catch_all
376 , proto::basic_default_domain
381 #include <boost/phoenix/statement/detail/catch_push_back.hpp>
384 template <typename Dummy>
385 struct is_nullary::when<rule::try_catch, Dummy>
387 detail::try_catch_is_nullary(
389 , proto::make<proto::empty_env()>
395 template <typename TryCatch, typename Exception, typename Capture = void>
398 catch_gen(TryCatch const& try_catch_, Capture const& capture)
399 : try_catch(try_catch_)
400 , capture(capture) {}
402 template <typename Expr>
403 typename boost::disable_if<
405 typename proto::result_of::child_c<
407 , proto::arity_of<TryCatch>::value - 1
411 , typename detail::catch_push_back<TryCatch, Exception, Capture, Expr>::type
413 operator[](Expr const& expr) const
416 detail::catch_push_back<TryCatch, Exception, Capture, Expr>::make(
417 try_catch, capture, expr
421 TryCatch const & try_catch;
422 Capture const & capture;
425 template <typename TryCatch, typename Exception>
426 struct catch_gen<TryCatch, Exception, void>
428 catch_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {}
430 template <typename Expr>
431 typename boost::disable_if<
433 typename proto::result_of::child_c<
435 , proto::arity_of<TryCatch>::value - 1
439 , typename detail::catch_push_back<TryCatch, Exception, void, Expr>::type
441 operator[](Expr const& expr) const
444 detail::catch_push_back<TryCatch, Exception, void, Expr>::make(
449 TryCatch const & try_catch;
452 template <typename TryCatch>
455 catch_all_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {}
457 template <typename Expr>
458 typename boost::disable_if<
460 typename proto::result_of::child_c<
462 , proto::arity_of<TryCatch>::value - 1
466 , typename detail::catch_all_push_back<TryCatch, Expr>::type
468 operator[](Expr const& expr) const
470 return detail::catch_all_push_back<TryCatch, Expr>::make(
475 TryCatch const & try_catch;
481 struct try_catch_actor;
483 template <typename Expr>
484 struct try_catch_actor
487 typedef try_catch_actor<Expr> that_type;
488 typedef actor<Expr> base_type;
490 try_catch_actor(base_type const& expr)
496 template <typename Exception>
497 catch_gen<that_type, Exception> const
500 return catch_gen<that_type, Exception>(*this);
503 template <typename Exception, typename Capture>
504 catch_gen<that_type, Exception, Capture> const
505 catch_(Capture const &expr) const
507 return catch_gen<that_type, Exception, Capture>(*this, expr);
510 catch_all_gen<that_type> const catch_all;
515 template <typename Try>
516 typename expression::try_catch<Try>::type const
517 operator[](Try const & try_) const
519 return expression::try_catch<Try>::make(try_);
523 #ifndef BOOST_PHOENIX_NO_PREDEFINED_TERMINALS
524 try_gen const try_ = {};