try_catch.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /*==============================================================================
  2. Copyright (c) 2005-2007 Dan Marsden
  3. Copyright (c) 2005-2010 Joel de Guzman
  4. Copyright (c) 2010 Thomas Heller
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ==============================================================================*/
  8. #ifndef BOOST_PHOENIX_STATEMENT_TRY_CATCH_HPP
  9. #define BOOST_PHOENIX_STATEMENT_TRY_CATCH_HPP
  10. #include <boost/phoenix/core/limits.hpp>
  11. #include <boost/phoenix/core/call.hpp>
  12. #include <boost/phoenix/core/expression.hpp>
  13. #include <boost/phoenix/core/meta_grammar.hpp>
  14. #include <boost/phoenix/core/is_nullary.hpp>
  15. #include <boost/phoenix/scope/local_variable.hpp>
  16. #include <boost/phoenix/scope/scoped_environment.hpp>
  17. #include <boost/proto/functional/fusion/pop_front.hpp>
  18. #include <boost/core/enable_if.hpp>
  19. #ifdef _MSC_VER
  20. #pragma warning(push)
  21. #pragma warning(disable: 4355) // 'this' : used in base member initializer list
  22. #endif
  23. namespace boost { namespace phoenix
  24. {
  25. template <typename Expr>
  26. struct try_catch_actor;
  27. template <typename Exception>
  28. struct catch_exception
  29. {
  30. typedef Exception type;
  31. };
  32. namespace tag
  33. {
  34. struct try_catch {};
  35. struct catch_ {};
  36. struct catch_all {};
  37. }
  38. namespace expression
  39. {
  40. template <
  41. typename Try
  42. , BOOST_PHOENIX_typename_A_void(BOOST_PHOENIX_CATCH_LIMIT)
  43. , typename Dummy = void
  44. >
  45. struct try_catch;
  46. // bring in the expression definitions
  47. #include <boost/phoenix/statement/detail/try_catch_expression.hpp>
  48. template <typename A0, typename A1, typename A2 = void>
  49. struct catch_
  50. : proto::nary_expr<tag::catch_, A0, A1, A2>
  51. {};
  52. template <typename A0, typename A1>
  53. struct catch_<A0, A1, void>
  54. : proto::binary_expr<tag::catch_, A0, A1>
  55. {};
  56. template <typename A0>
  57. struct catch_all
  58. : proto::unary_expr<tag::catch_all, A0>
  59. {};
  60. }
  61. namespace rule
  62. {
  63. typedef
  64. expression::catch_<
  65. proto::terminal<catch_exception<proto::_> >
  66. , local_variable
  67. , meta_grammar
  68. >
  69. captured_catch;
  70. typedef
  71. expression::catch_<
  72. proto::terminal<catch_exception<proto::_> >
  73. , meta_grammar
  74. >
  75. non_captured_catch;
  76. struct catch_
  77. : proto::or_<
  78. captured_catch
  79. , non_captured_catch
  80. >
  81. {};
  82. struct catch_all
  83. : expression::catch_all<
  84. meta_grammar
  85. >
  86. {};
  87. struct try_catch
  88. : proto::or_<
  89. expression::try_catch<
  90. meta_grammar
  91. , proto::vararg<rule::catch_>
  92. >
  93. , expression::try_catch<
  94. meta_grammar
  95. , rule::catch_all
  96. >
  97. , expression::try_catch<
  98. meta_grammar
  99. , proto::vararg<rule::catch_>
  100. , rule::catch_all
  101. >
  102. >
  103. {};
  104. }
  105. template <typename Dummy>
  106. struct meta_grammar::case_<tag::try_catch, Dummy>
  107. : enable_rule<rule::try_catch, Dummy>
  108. {};
  109. struct try_catch_eval
  110. {
  111. typedef void result_type;
  112. template <typename Try, typename Context>
  113. void operator()(Try const &, Context const &) const
  114. {}
  115. template <typename Catch, typename Exception, typename Context>
  116. typename enable_if<proto::matches<Catch, rule::non_captured_catch> >::type
  117. eval_catch_body(Catch const &c, Exception & /*unused*/, Context const &ctx) const
  118. {
  119. phoenix::eval(proto::child_c<1>(c), ctx);
  120. }
  121. template <typename Catch, typename Exception, typename Context>
  122. typename enable_if<proto::matches<Catch, rule::captured_catch> >::type
  123. eval_catch_body(Catch const &c, Exception &e, Context const &ctx) const
  124. {
  125. typedef
  126. typename proto::detail::uncvref<
  127. typename proto::result_of::value<
  128. typename proto::result_of::child_c<Catch, 1>::type
  129. >::type
  130. >::type
  131. capture_type;
  132. typedef
  133. typename proto::detail::uncvref<
  134. typename result_of::env<Context>::type
  135. >::type
  136. env_type;
  137. typedef vector1<Exception &> local_type;
  138. typedef detail::map_local_index_to_tuple<capture_type> map_type;
  139. typedef
  140. phoenix::scoped_environment<
  141. env_type
  142. , env_type
  143. , local_type
  144. , map_type
  145. >
  146. scoped_env_tpe;
  147. local_type local = {e};
  148. scoped_env_tpe env(phoenix::env(ctx), phoenix::env(ctx), local);
  149. phoenix::eval(proto::child_c<2>(c), phoenix::context(env, phoenix::actions(ctx)));
  150. }
  151. // bring in the operator overloads
  152. #include <boost/phoenix/statement/detail/try_catch_eval.hpp>
  153. };
  154. template <typename Dummy>
  155. struct default_actions::when<rule::try_catch, Dummy>
  156. : call<try_catch_eval, Dummy>
  157. {};
  158. namespace detail
  159. {
  160. struct try_catch_is_nullary
  161. : proto::or_<
  162. proto::when<
  163. phoenix::rule::catch_all
  164. , proto::call<
  165. evaluator(
  166. proto::_child_c<0>
  167. , proto::_data
  168. , proto::make<proto::empty_env()>
  169. )
  170. >
  171. >
  172. , proto::when<
  173. phoenix::rule::catch_
  174. , proto::or_<
  175. proto::when<
  176. phoenix::rule::captured_catch
  177. , proto::call<
  178. evaluator(
  179. proto::_child_c<2>
  180. , proto::call<
  181. phoenix::functional::context(
  182. proto::make<mpl::true_()>
  183. , proto::make<detail::scope_is_nullary_actions()>
  184. )
  185. >
  186. , proto::make<proto::empty_env()>
  187. )
  188. >
  189. >
  190. , proto::otherwise<
  191. proto::call<
  192. evaluator(
  193. proto::_child_c<1>
  194. , proto::_data
  195. , proto::make<proto::empty_env()>
  196. )
  197. >
  198. >
  199. >
  200. >
  201. , proto::when<
  202. phoenix::rule::try_catch
  203. , proto::make<
  204. mpl::and_<
  205. proto::call<
  206. evaluator(
  207. proto::_child_c<0>
  208. , proto::_data
  209. , proto::make<proto::empty_env()>
  210. )
  211. >
  212. , proto::fold<
  213. proto::call<
  214. proto::functional::pop_front(proto::_)
  215. >
  216. , proto::make<mpl::true_()>
  217. , proto::make<
  218. mpl::and_<
  219. proto::_state
  220. , proto::call<
  221. try_catch_is_nullary(
  222. proto::_
  223. , proto::make<proto::empty_env()>
  224. , proto::_data
  225. )
  226. >
  227. >()
  228. >
  229. >
  230. >()
  231. >
  232. >
  233. >
  234. {};
  235. template <
  236. typename TryCatch
  237. , typename Exception
  238. , typename Capture
  239. , typename Expr
  240. , long Arity = proto::arity_of<TryCatch>::value
  241. >
  242. struct catch_push_back;
  243. template <typename TryCatch, typename Exception, typename Capture, typename Expr>
  244. struct catch_push_back<TryCatch, Exception, Capture, Expr, 1>
  245. {
  246. typedef
  247. typename proto::result_of::make_expr<
  248. phoenix::tag::catch_
  249. , proto::basic_default_domain
  250. , catch_exception<Exception>
  251. , Capture
  252. , Expr
  253. >::type
  254. catch_expr;
  255. typedef
  256. phoenix::expression::try_catch<
  257. TryCatch
  258. , catch_expr
  259. >
  260. gen_type;
  261. typedef typename gen_type::type type;
  262. static type make(TryCatch const & try_catch, Capture const & capture, Expr const & catch_)
  263. {
  264. return
  265. gen_type::make(
  266. try_catch
  267. , proto::make_expr<
  268. phoenix::tag::catch_
  269. , proto::basic_default_domain
  270. >(catch_exception<Exception>(), capture, catch_)
  271. );
  272. }
  273. };
  274. template <typename TryCatch, typename Exception, typename Expr>
  275. struct catch_push_back<TryCatch, Exception, void, Expr, 1>
  276. {
  277. typedef
  278. typename proto::result_of::make_expr<
  279. phoenix::tag::catch_
  280. , proto::basic_default_domain
  281. , catch_exception<Exception>
  282. , Expr
  283. >::type
  284. catch_expr;
  285. typedef
  286. phoenix::expression::try_catch<
  287. TryCatch
  288. , catch_expr
  289. >
  290. gen_type;
  291. typedef typename gen_type::type type;
  292. static type make(TryCatch const & try_catch, Expr const & catch_)
  293. {
  294. return
  295. gen_type::make(
  296. try_catch
  297. , proto::make_expr<
  298. phoenix::tag::catch_
  299. , proto::basic_default_domain
  300. >(catch_exception<Exception>(), catch_)
  301. );
  302. }
  303. };
  304. template <
  305. typename TryCatch
  306. , typename Expr
  307. , long Arity = proto::arity_of<TryCatch>::value
  308. >
  309. struct catch_all_push_back;
  310. template <typename TryCatch, typename Expr>
  311. struct catch_all_push_back<TryCatch, Expr, 1>
  312. {
  313. typedef
  314. typename proto::result_of::make_expr<
  315. phoenix::tag::catch_all
  316. , proto::basic_default_domain
  317. , Expr
  318. >::type
  319. catch_expr;
  320. typedef
  321. phoenix::expression::try_catch<
  322. TryCatch
  323. , catch_expr
  324. >
  325. gen_type;
  326. typedef typename gen_type::type type;
  327. static type make(TryCatch const& try_catch, Expr const& catch_)
  328. {
  329. return
  330. gen_type::make(
  331. try_catch
  332. , proto::make_expr<
  333. phoenix::tag::catch_all
  334. , proto::basic_default_domain
  335. >(catch_)
  336. );
  337. }
  338. };
  339. #include <boost/phoenix/statement/detail/catch_push_back.hpp>
  340. }
  341. template <typename Dummy>
  342. struct is_nullary::when<rule::try_catch, Dummy>
  343. : proto::call<
  344. detail::try_catch_is_nullary(
  345. proto::_
  346. , proto::make<proto::empty_env()>
  347. , _context
  348. )
  349. >
  350. {};
  351. template <typename TryCatch, typename Exception, typename Capture = void>
  352. struct catch_gen
  353. {
  354. catch_gen(TryCatch const& try_catch_, Capture const& capture)
  355. : try_catch(try_catch_)
  356. , capture(capture) {}
  357. template <typename Expr>
  358. typename boost::disable_if<
  359. proto::matches<
  360. typename proto::result_of::child_c<
  361. TryCatch
  362. , proto::arity_of<TryCatch>::value - 1
  363. >::type
  364. , rule::catch_all
  365. >
  366. , typename detail::catch_push_back<TryCatch, Exception, Capture, Expr>::type
  367. >::type
  368. operator[](Expr const& expr) const
  369. {
  370. return
  371. detail::catch_push_back<TryCatch, Exception, Capture, Expr>::make(
  372. try_catch, capture, expr
  373. );
  374. }
  375. TryCatch const & try_catch;
  376. Capture const & capture;
  377. };
  378. template <typename TryCatch, typename Exception>
  379. struct catch_gen<TryCatch, Exception, void>
  380. {
  381. catch_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {}
  382. template <typename Expr>
  383. typename boost::disable_if<
  384. proto::matches<
  385. typename proto::result_of::child_c<
  386. TryCatch
  387. , proto::arity_of<TryCatch>::value - 1
  388. >::type
  389. , rule::catch_all
  390. >
  391. , typename detail::catch_push_back<TryCatch, Exception, void, Expr>::type
  392. >::type
  393. operator[](Expr const& expr) const
  394. {
  395. return
  396. detail::catch_push_back<TryCatch, Exception, void, Expr>::make(
  397. try_catch, expr
  398. );
  399. }
  400. TryCatch const & try_catch;
  401. };
  402. template <typename TryCatch>
  403. struct catch_all_gen
  404. {
  405. catch_all_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {}
  406. template <typename Expr>
  407. typename boost::disable_if<
  408. proto::matches<
  409. typename proto::result_of::child_c<
  410. TryCatch
  411. , proto::arity_of<TryCatch>::value - 1
  412. >::type
  413. , rule::catch_all
  414. >
  415. , typename detail::catch_all_push_back<TryCatch, Expr>::type
  416. >::type
  417. operator[](Expr const& expr) const
  418. {
  419. return detail::catch_all_push_back<TryCatch, Expr>::make(
  420. try_catch, expr
  421. );
  422. }
  423. TryCatch const & try_catch;
  424. };
  425. template <
  426. typename Expr
  427. >
  428. struct try_catch_actor;
  429. template <typename Expr>
  430. struct try_catch_actor
  431. : actor<Expr>
  432. {
  433. typedef try_catch_actor<Expr> that_type;
  434. typedef actor<Expr> base_type;
  435. try_catch_actor(base_type const& expr)
  436. : base_type(expr)
  437. , catch_all(*this)
  438. {
  439. }
  440. template <typename Exception>
  441. catch_gen<that_type, Exception> const
  442. catch_() const
  443. {
  444. return catch_gen<that_type, Exception>(*this);
  445. }
  446. template <typename Exception, typename Capture>
  447. catch_gen<that_type, Exception, Capture> const
  448. catch_(Capture const &expr) const
  449. {
  450. return catch_gen<that_type, Exception, Capture>(*this, expr);
  451. }
  452. catch_all_gen<that_type> const catch_all;
  453. };
  454. struct try_gen
  455. {
  456. template <typename Try>
  457. typename expression::try_catch<Try>::type const
  458. operator[](Try const & try_) const
  459. {
  460. return expression::try_catch<Try>::make(try_);
  461. }
  462. };
  463. #ifndef BOOST_PHOENIX_NO_PREDEFINED_TERMINALS
  464. try_gen const try_ = {};
  465. #endif
  466. }}
  467. #ifdef _MSC_VER
  468. #pragma warning(pop)
  469. #endif
  470. #endif