/*============================================================================== 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 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::binary_expr {}; template struct catch_all : proto::unary_expr {}; } namespace rule { struct catch_ : expression::catch_< proto::terminal > , meta_grammar > {}; 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; // 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::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 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 , 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) : 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 const & 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 const & try_catch; }; template < typename Expr > struct try_catch_actor; template struct try_catch_actor : actor { typedef try_catch_actor that_type; 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); } catch_all_gen const catch_all; }; 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 }} #endif