File indexing completed on 2025-01-18 09:47:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_PHOENIX_STATEMENT_TRY_CATCH_HPP
0011 #define BOOST_PHOENIX_STATEMENT_TRY_CATCH_HPP
0012
0013 #include <boost/phoenix/config.hpp>
0014 #include <boost/phoenix/core/limits.hpp>
0015 #include <boost/phoenix/core/call.hpp>
0016 #include <boost/phoenix/core/expression.hpp>
0017 #include <boost/phoenix/core/meta_grammar.hpp>
0018 #include <boost/phoenix/core/is_nullary.hpp>
0019 #include <boost/phoenix/scope/local_variable.hpp>
0020 #include <boost/phoenix/scope/scoped_environment.hpp>
0021 #include <boost/proto/functional/fusion/pop_front.hpp>
0022 #include <boost/core/enable_if.hpp>
0023
0024 #ifdef _MSC_VER
0025 #pragma warning(push)
0026 #pragma warning(disable: 4355)
0027 #endif
0028
0029 namespace boost { namespace phoenix
0030 {
0031 template <typename Expr>
0032 struct try_catch_actor;
0033
0034 template <typename Exception>
0035 struct catch_exception
0036 {
0037 typedef Exception type;
0038 };
0039
0040 namespace tag
0041 {
0042 struct try_catch {};
0043 struct catch_ {};
0044 struct catch_all {};
0045 }
0046
0047 namespace expression
0048 {
0049 template <
0050 typename Try
0051 , BOOST_PHOENIX_typename_A_void(BOOST_PHOENIX_CATCH_LIMIT)
0052 , typename Dummy = void
0053 >
0054 struct try_catch;
0055
0056
0057 #include <boost/phoenix/statement/detail/try_catch_expression.hpp>
0058
0059 template <typename A0, typename A1, typename A2 = void>
0060 struct catch_
0061 : proto::nary_expr<tag::catch_, A0, A1, A2>
0062 {};
0063
0064 template <typename A0, typename A1>
0065 struct catch_<A0, A1, void>
0066 : proto::binary_expr<tag::catch_, A0, A1>
0067 {};
0068
0069 template <typename A0>
0070 struct catch_all
0071 : proto::unary_expr<tag::catch_all, A0>
0072 {};
0073 }
0074
0075 namespace rule
0076 {
0077 typedef
0078 expression::catch_<
0079 proto::terminal<catch_exception<proto::_> >
0080 , local_variable
0081 , meta_grammar
0082 >
0083 captured_catch;
0084
0085 typedef
0086 expression::catch_<
0087 proto::terminal<catch_exception<proto::_> >
0088 , meta_grammar
0089 >
0090 non_captured_catch;
0091
0092 struct catch_
0093 : proto::or_<
0094 captured_catch
0095 , non_captured_catch
0096 >
0097 {};
0098
0099 struct catch_all
0100 : expression::catch_all<
0101 meta_grammar
0102 >
0103 {};
0104
0105 struct try_catch
0106 : proto::or_<
0107 expression::try_catch<
0108 meta_grammar
0109 , proto::vararg<rule::catch_>
0110 >
0111 , expression::try_catch<
0112 meta_grammar
0113 , rule::catch_all
0114 >
0115 , expression::try_catch<
0116 meta_grammar
0117 , proto::vararg<rule::catch_>
0118 , rule::catch_all
0119 >
0120 >
0121 {};
0122 }
0123
0124 template <typename Dummy>
0125 struct meta_grammar::case_<tag::try_catch, Dummy>
0126 : enable_rule<rule::try_catch, Dummy>
0127 {};
0128
0129 struct try_catch_eval
0130 {
0131 typedef void result_type;
0132
0133 template <typename Try, typename Context>
0134 void operator()(Try const &, Context const &) const
0135 {}
0136
0137 template <typename Catch, typename Exception, typename Context>
0138 typename enable_if<proto::matches<Catch, rule::non_captured_catch> >::type
0139 eval_catch_body(Catch const &c, Exception & , Context const &ctx
0140 BOOST_PHOENIX_SFINAE_AND_OVERLOADS) const
0141 {
0142 phoenix::eval(proto::child_c<1>(c), ctx);
0143 }
0144
0145 template <typename Catch, typename Exception, typename Context>
0146 typename enable_if<proto::matches<Catch, rule::captured_catch> >::type
0147 eval_catch_body(Catch const &c, Exception &e, Context const &ctx) const
0148 {
0149 typedef
0150 typename proto::detail::uncvref<
0151 typename proto::result_of::value<
0152 typename proto::result_of::child_c<Catch, 1>::type
0153 >::type
0154 >::type
0155 capture_type;
0156 typedef
0157 typename proto::detail::uncvref<
0158 typename result_of::env<Context>::type
0159 >::type
0160 env_type;
0161 typedef vector1<Exception &> local_type;
0162 typedef detail::map_local_index_to_tuple<capture_type> map_type;
0163
0164 typedef
0165 phoenix::scoped_environment<
0166 env_type
0167 , env_type
0168 , local_type
0169 , map_type
0170 >
0171 scoped_env_tpe;
0172
0173 local_type local = {e};
0174
0175 scoped_env_tpe env(phoenix::env(ctx), phoenix::env(ctx), local);
0176
0177 phoenix::eval(proto::child_c<2>(c), phoenix::context(env, phoenix::actions(ctx)));
0178 }
0179
0180
0181 #include <boost/phoenix/statement/detail/try_catch_eval.hpp>
0182 };
0183
0184 template <typename Dummy>
0185 struct default_actions::when<rule::try_catch, Dummy>
0186 : call<try_catch_eval, Dummy>
0187 {};
0188
0189 namespace detail
0190 {
0191 struct try_catch_is_nullary
0192 : proto::or_<
0193 proto::when<
0194 phoenix::rule::catch_all
0195 , proto::call<
0196 evaluator(
0197 proto::_child_c<0>
0198 , proto::_data
0199 , proto::make<proto::empty_env()>
0200 )
0201 >
0202 >
0203 , proto::when<
0204 phoenix::rule::catch_
0205 , proto::or_<
0206 proto::when<
0207 phoenix::rule::captured_catch
0208 , proto::call<
0209 evaluator(
0210 proto::_child_c<2>
0211 , proto::call<
0212 phoenix::functional::context(
0213 proto::make<mpl::true_()>
0214 , proto::make<detail::scope_is_nullary_actions()>
0215 )
0216 >
0217 , proto::make<proto::empty_env()>
0218 )
0219 >
0220 >
0221 , proto::otherwise<
0222 proto::call<
0223 evaluator(
0224 proto::_child_c<1>
0225 , proto::_data
0226 , proto::make<proto::empty_env()>
0227 )
0228 >
0229 >
0230 >
0231 >
0232 , proto::when<
0233 phoenix::rule::try_catch
0234 , proto::make<
0235 mpl::and_<
0236 proto::call<
0237 evaluator(
0238 proto::_child_c<0>
0239 , proto::_data
0240 , proto::make<proto::empty_env()>
0241 )
0242 >
0243 , proto::fold<
0244 proto::call<
0245 proto::functional::pop_front(proto::_)
0246 >
0247 , proto::make<mpl::true_()>
0248 , proto::make<
0249 mpl::and_<
0250 proto::_state
0251 , proto::call<
0252 try_catch_is_nullary(
0253 proto::_
0254 , proto::make<proto::empty_env()>
0255 , proto::_data
0256 )
0257 >
0258 >()
0259 >
0260 >
0261 >()
0262 >
0263 >
0264 >
0265 {};
0266
0267 template <
0268 typename TryCatch
0269 , typename Exception
0270 , typename Capture
0271 , typename Expr
0272 , long Arity = proto::arity_of<TryCatch>::value
0273 >
0274 struct catch_push_back;
0275
0276 template <typename TryCatch, typename Exception, typename Capture, typename Expr>
0277 struct catch_push_back<TryCatch, Exception, Capture, Expr, 1>
0278 {
0279 typedef
0280 typename proto::result_of::make_expr<
0281 phoenix::tag::catch_
0282 , proto::basic_default_domain
0283 , catch_exception<Exception>
0284 , Capture
0285 , Expr
0286 >::type
0287 catch_expr;
0288
0289 typedef
0290 phoenix::expression::try_catch<
0291 TryCatch
0292 , catch_expr
0293 >
0294 gen_type;
0295 typedef typename gen_type::type type;
0296
0297 static type make(TryCatch const & try_catch, Capture const & capture, Expr const & catch_)
0298 {
0299 return
0300 gen_type::make(
0301 try_catch
0302 , proto::make_expr<
0303 phoenix::tag::catch_
0304 , proto::basic_default_domain
0305 >(catch_exception<Exception>(), capture, catch_)
0306 );
0307 }
0308 };
0309
0310 template <typename TryCatch, typename Exception, typename Expr>
0311 struct catch_push_back<TryCatch, Exception, void, Expr, 1>
0312 {
0313 typedef
0314 typename proto::result_of::make_expr<
0315 phoenix::tag::catch_
0316 , proto::basic_default_domain
0317 , catch_exception<Exception>
0318 , Expr
0319 >::type
0320 catch_expr;
0321
0322 typedef
0323 phoenix::expression::try_catch<
0324 TryCatch
0325 , catch_expr
0326 >
0327 gen_type;
0328 typedef typename gen_type::type type;
0329
0330 static type make(TryCatch const & try_catch, Expr const & catch_)
0331 {
0332 return
0333 gen_type::make(
0334 try_catch
0335 , proto::make_expr<
0336 phoenix::tag::catch_
0337 , proto::basic_default_domain
0338 >(catch_exception<Exception>(), catch_)
0339 );
0340 }
0341 };
0342
0343 template <
0344 typename TryCatch
0345 , typename Expr
0346 , long Arity = proto::arity_of<TryCatch>::value
0347 >
0348 struct catch_all_push_back;
0349
0350 template <typename TryCatch, typename Expr>
0351 struct catch_all_push_back<TryCatch, Expr, 1>
0352 {
0353 typedef
0354 typename proto::result_of::make_expr<
0355 phoenix::tag::catch_all
0356 , proto::basic_default_domain
0357 , Expr
0358 >::type
0359 catch_expr;
0360
0361 typedef
0362 phoenix::expression::try_catch<
0363 TryCatch
0364 , catch_expr
0365 >
0366 gen_type;
0367 typedef typename gen_type::type type;
0368
0369 static type make(TryCatch const& try_catch, Expr const& catch_)
0370 {
0371 return
0372 gen_type::make(
0373 try_catch
0374 , proto::make_expr<
0375 phoenix::tag::catch_all
0376 , proto::basic_default_domain
0377 >(catch_)
0378 );
0379 }
0380 };
0381 #include <boost/phoenix/statement/detail/catch_push_back.hpp>
0382 }
0383
0384 template <typename Dummy>
0385 struct is_nullary::when<rule::try_catch, Dummy>
0386 : proto::call<
0387 detail::try_catch_is_nullary(
0388 proto::_
0389 , proto::make<proto::empty_env()>
0390 , _context
0391 )
0392 >
0393 {};
0394
0395 template <typename TryCatch, typename Exception, typename Capture = void>
0396 struct catch_gen
0397 {
0398 catch_gen(TryCatch const& try_catch_, Capture const& capture)
0399 : try_catch(try_catch_)
0400 , capture(capture) {}
0401
0402 template <typename Expr>
0403 typename boost::disable_if<
0404 proto::matches<
0405 typename proto::result_of::child_c<
0406 TryCatch
0407 , proto::arity_of<TryCatch>::value - 1
0408 >::type
0409 , rule::catch_all
0410 >
0411 , typename detail::catch_push_back<TryCatch, Exception, Capture, Expr>::type
0412 >::type
0413 operator[](Expr const& expr) const
0414 {
0415 return
0416 detail::catch_push_back<TryCatch, Exception, Capture, Expr>::make(
0417 try_catch, capture, expr
0418 );
0419 }
0420
0421 TryCatch try_catch;
0422 Capture capture;
0423 };
0424
0425 template <typename TryCatch, typename Exception>
0426 struct catch_gen<TryCatch, Exception, void>
0427 {
0428 catch_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {}
0429
0430 template <typename Expr>
0431 typename boost::disable_if<
0432 proto::matches<
0433 typename proto::result_of::child_c<
0434 TryCatch
0435 , proto::arity_of<TryCatch>::value - 1
0436 >::type
0437 , rule::catch_all
0438 >
0439 , typename detail::catch_push_back<TryCatch, Exception, void, Expr>::type
0440 >::type
0441 operator[](Expr const& expr) const
0442 {
0443 return
0444 detail::catch_push_back<TryCatch, Exception, void, Expr>::make(
0445 try_catch, expr
0446 );
0447 }
0448
0449 TryCatch try_catch;
0450 };
0451
0452 template <typename TryCatch>
0453 struct catch_all_gen
0454 {
0455 catch_all_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {}
0456
0457 template <typename Expr>
0458 typename boost::disable_if<
0459 proto::matches<
0460 typename proto::result_of::child_c<
0461 TryCatch
0462 , proto::arity_of<TryCatch>::value - 1
0463 >::type
0464 , rule::catch_all
0465 >
0466 , typename detail::catch_all_push_back<TryCatch, Expr>::type
0467 >::type
0468 operator[](Expr const& expr) const
0469 {
0470 return detail::catch_all_push_back<TryCatch, Expr>::make(
0471 try_catch, expr
0472 );
0473 }
0474
0475 TryCatch try_catch;
0476 };
0477
0478 template <
0479 typename Expr
0480 >
0481 struct try_catch_actor;
0482
0483 template <typename Expr>
0484 struct try_catch_actor
0485 : actor<Expr>
0486 {
0487 typedef actor<Expr> base_type;
0488
0489 try_catch_actor(base_type const& expr)
0490 : base_type(expr)
0491 , catch_all(*this)
0492 {
0493 }
0494
0495 template <typename Exception>
0496 catch_gen<base_type, Exception> const
0497 catch_() const
0498 {
0499 return catch_gen<base_type, Exception>(*this);
0500 }
0501
0502 template <typename Exception, typename Capture>
0503 catch_gen<base_type, Exception, Capture> const
0504 catch_(Capture const &expr) const
0505 {
0506 return catch_gen<base_type, Exception, Capture>(*this, expr);
0507 }
0508
0509 catch_all_gen<base_type> const catch_all;
0510 };
0511
0512 template <typename Expr>
0513 struct is_actor<try_catch_actor<Expr> >
0514 : mpl::true_
0515 {};
0516
0517 struct try_gen
0518 {
0519 template <typename Try>
0520 typename expression::try_catch<Try>::type const
0521 operator[](Try const & try_) const
0522 {
0523 return expression::try_catch<Try>::make(try_);
0524 }
0525 };
0526
0527 #ifndef BOOST_PHOENIX_NO_PREDEFINED_TERMINALS
0528 try_gen const try_ = {};
0529 #endif
0530 }}
0531
0532 #ifdef _MSC_VER
0533 #pragma warning(pop)
0534 #endif
0535
0536 #endif