/*============================================================================== Copyright (c) 2005-2007 Dan Marsden Copyright (c) 2005-2010 Joel de Guzman Copyright (c) 2010 Thomas Heller 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) ==============================================================================*/ #ifndef BOOST_PHOENIX_STATEMENT_TRY_CATCH_HPP #define BOOST_PHOENIX_STATEMENT_TRY_CATCH_HPP #include #include #include #include #include #include #include #include #include #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4355) // 'this' : used in base member initializer list #endif namespace boost { namespace phoenix { template struct try_catch_actor; template struct catch_exception { typedef Exception type; }; namespace tag { struct try_catch {}; struct catch_ {}; struct catch_all {}; } namespace expression { template < typename Try , BOOST_PHOENIX_typename_A_void(BOOST_PHOENIX_CATCH_LIMIT) , typename Dummy = void > struct try_catch; // bring in the expression definitions #include template struct catch_ : proto::nary_expr {}; template struct catch_ : proto::binary_expr {}; template struct catch_all : proto::unary_expr {}; } namespace rule { typedef expression::catch_< proto::terminal > , local_variable , meta_grammar > captured_catch; typedef expression::catch_< proto::terminal > , meta_grammar > non_captured_catch; struct catch_ : proto::or_< captured_catch , non_captured_catch > {}; struct catch_all : expression::catch_all< meta_grammar > {}; struct try_catch : proto::or_< expression::try_catch< meta_grammar , proto::vararg > , expression::try_catch< meta_grammar , rule::catch_all > , expression::try_catch< meta_grammar , proto::vararg , rule::catch_all > > {}; } template struct meta_grammar::case_ : enable_rule {}; struct try_catch_eval { typedef void result_type; template void operator()(Try const &, Context const &) const {} template typename enable_if >::type eval_catch_body(Catch const &c, Exception & /*unused*/, Context const &ctx BOOST_PHOENIX_SFINAE_AND_OVERLOADS) const { phoenix::eval(proto::child_c<1>(c), ctx); } template typename enable_if >::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::type >::type >::type capture_type; typedef typename proto::detail::uncvref< typename result_of::env::type >::type env_type; typedef vector1 local_type; typedef detail::map_local_index_to_tuple 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 }; template struct default_actions::when : call {}; namespace detail { struct try_catch_is_nullary : proto::or_< proto::when< phoenix::rule::catch_all , proto::call< evaluator( proto::_child_c<0> , proto::_data , proto::make ) > > , proto::when< phoenix::rule::catch_ , proto::or_< proto::when< phoenix::rule::captured_catch , proto::call< evaluator( proto::_child_c<2> , proto::call< phoenix::functional::context( proto::make , proto::make ) > , proto::make ) > > , proto::otherwise< proto::call< evaluator( proto::_child_c<1> , proto::_data , proto::make ) > > > > , proto::when< phoenix::rule::try_catch , proto::make< mpl::and_< proto::call< evaluator( proto::_child_c<0> , proto::_data , proto::make ) > , proto::fold< proto::call< proto::functional::pop_front(proto::_) > , proto::make , proto::make< mpl::and_< proto::_state , proto::call< try_catch_is_nullary( proto::_ , proto::make , proto::_data ) > >() > > >() > > > {}; template < typename TryCatch , typename Exception , typename Capture , typename Expr , long Arity = proto::arity_of::value > struct catch_push_back; template struct catch_push_back { typedef typename proto::result_of::make_expr< phoenix::tag::catch_ , proto::basic_default_domain , catch_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(), capture, catch_) ); } }; template struct catch_push_back { typedef typename proto::result_of::make_expr< phoenix::tag::catch_ , proto::basic_default_domain , catch_exception , 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, Expr const & catch_) { return gen_type::make( try_catch , proto::make_expr< phoenix::tag::catch_ , proto::basic_default_domain >(catch_exception(), catch_) ); } }; template < typename TryCatch , typename Expr , long Arity = proto::arity_of::value > struct catch_all_push_back; template struct catch_all_push_back { typedef typename proto::result_of::make_expr< phoenix::tag::catch_all , proto::basic_default_domain , 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, Expr const& catch_) { return gen_type::make( try_catch , proto::make_expr< phoenix::tag::catch_all , proto::basic_default_domain >(catch_) ); } }; #include } template struct is_nullary::when : proto::call< detail::try_catch_is_nullary( proto::_ , proto::make , _context ) > {}; template struct catch_gen { catch_gen(TryCatch const& try_catch_, Capture const& capture) : try_catch(try_catch_) , capture(capture) {} template typename boost::disable_if< proto::matches< typename proto::result_of::child_c< TryCatch , proto::arity_of::value - 1 >::type , rule::catch_all > , typename detail::catch_push_back::type >::type operator[](Expr const& expr) const { return detail::catch_push_back::make( try_catch, capture, expr ); } TryCatch try_catch; Capture capture; }; template struct catch_gen { catch_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {} template typename boost::disable_if< proto::matches< typename proto::result_of::child_c< TryCatch , proto::arity_of::value - 1 >::type , rule::catch_all > , typename detail::catch_push_back::type >::type operator[](Expr const& expr) const { return detail::catch_push_back::make( try_catch, expr ); } TryCatch try_catch; }; template struct catch_all_gen { catch_all_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {} template typename boost::disable_if< proto::matches< typename proto::result_of::child_c< TryCatch , proto::arity_of::value - 1 >::type , rule::catch_all > , typename detail::catch_all_push_back::type >::type operator[](Expr const& expr) const { return detail::catch_all_push_back::make( try_catch, expr ); } TryCatch try_catch; }; template < typename Expr > struct try_catch_actor; template struct try_catch_actor : actor { typedef actor base_type; try_catch_actor(base_type const& expr) : base_type(expr) , catch_all(*this) { } template catch_gen const catch_() const { return catch_gen(*this); } template catch_gen const catch_(Capture const &expr) const { return catch_gen(*this, expr); } catch_all_gen const catch_all; }; template struct is_actor > : mpl::true_ {}; struct try_gen { template typename expression::try_catch::type const operator[](Try const & try_) const { return expression::try_catch::make(try_); } }; #ifndef BOOST_PHOENIX_NO_PREDEFINED_TERMINALS try_gen const try_ = {}; #endif }} #ifdef _MSC_VER #pragma warning(pop) #endif #endif