533 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			533 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*============================================================================== | ||
|  |     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 <boost/phoenix/config.hpp> | ||
|  | #include <boost/phoenix/core/limits.hpp> | ||
|  | #include <boost/phoenix/core/call.hpp> | ||
|  | #include <boost/phoenix/core/expression.hpp> | ||
|  | #include <boost/phoenix/core/meta_grammar.hpp> | ||
|  | #include <boost/phoenix/core/is_nullary.hpp> | ||
|  | #include <boost/phoenix/scope/local_variable.hpp> | ||
|  | #include <boost/phoenix/scope/scoped_environment.hpp> | ||
|  | #include <boost/proto/functional/fusion/pop_front.hpp> | ||
|  | #include <boost/core/enable_if.hpp> | ||
|  | 
 | ||
|  | #ifdef _MSC_VER | ||
|  | #pragma warning(push) | ||
|  | #pragma warning(disable: 4355) // 'this' : used in base member initializer list | ||
|  | #endif | ||
|  | 
 | ||
|  | namespace boost { namespace phoenix | ||
|  | { | ||
|  |     template <typename Expr> | ||
|  |     struct try_catch_actor; | ||
|  | 
 | ||
|  |     template <typename Exception> | ||
|  |     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 <boost/phoenix/statement/detail/try_catch_expression.hpp> | ||
|  | 
 | ||
|  |         template <typename A0, typename A1, typename A2 = void> | ||
|  |         struct catch_ | ||
|  |             : proto::nary_expr<tag::catch_, A0, A1, A2> | ||
|  |         {}; | ||
|  | 
 | ||
|  |         template <typename A0, typename A1> | ||
|  |         struct catch_<A0, A1, void> | ||
|  |             : proto::binary_expr<tag::catch_, A0, A1> | ||
|  |         {}; | ||
|  |          | ||
|  |         template <typename A0> | ||
|  |         struct catch_all | ||
|  |             : proto::unary_expr<tag::catch_all, A0> | ||
|  |         {}; | ||
|  |     } | ||
|  | 
 | ||
|  |     namespace rule | ||
|  |     { | ||
|  |         typedef | ||
|  |             expression::catch_< | ||
|  |                 proto::terminal<catch_exception<proto::_> > | ||
|  |               , local_variable | ||
|  |               , meta_grammar | ||
|  |             > | ||
|  |         captured_catch; | ||
|  | 
 | ||
|  |         typedef | ||
|  |             expression::catch_< | ||
|  |                 proto::terminal<catch_exception<proto::_> > | ||
|  |               , 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<rule::catch_> | ||
|  |                 > | ||
|  |               , expression::try_catch< | ||
|  |                      meta_grammar | ||
|  |                    , rule::catch_all | ||
|  |                 > | ||
|  |               , expression::try_catch< | ||
|  |                      meta_grammar | ||
|  |                    , proto::vararg<rule::catch_> | ||
|  |                    , rule::catch_all | ||
|  |                 > | ||
|  |             > | ||
|  |         {}; | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename Dummy> | ||
|  |     struct meta_grammar::case_<tag::try_catch, Dummy> | ||
|  |         : enable_rule<rule::try_catch, Dummy> | ||
|  |     {}; | ||
|  | 
 | ||
|  |     struct try_catch_eval | ||
|  |     { | ||
|  |         typedef void result_type; | ||
|  | 
 | ||
|  |         template <typename Try, typename Context> | ||
|  |         void operator()(Try const &, Context const &) const | ||
|  |         {} | ||
|  | 
 | ||
|  |         template <typename Catch, typename Exception, typename Context> | ||
|  |         typename enable_if<proto::matches<Catch, rule::non_captured_catch> >::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 Catch, typename Exception, typename Context> | ||
|  |         typename enable_if<proto::matches<Catch, rule::captured_catch> >::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<Catch, 1>::type | ||
|  |                     >::type | ||
|  |                 >::type | ||
|  |             capture_type; | ||
|  |             typedef | ||
|  |                 typename proto::detail::uncvref< | ||
|  |                     typename result_of::env<Context>::type | ||
|  |                 >::type | ||
|  |             env_type; | ||
|  |             typedef vector1<Exception &> local_type; | ||
|  |             typedef detail::map_local_index_to_tuple<capture_type> 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 <boost/phoenix/statement/detail/try_catch_eval.hpp> | ||
|  |     }; | ||
|  |      | ||
|  |     template <typename Dummy> | ||
|  |     struct default_actions::when<rule::try_catch, Dummy> | ||
|  |         : call<try_catch_eval, Dummy> | ||
|  |     {}; | ||
|  | 
 | ||
|  |     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::empty_env()> | ||
|  |                         ) | ||
|  |                     > | ||
|  |                 > | ||
|  |               , 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<mpl::true_()> | ||
|  |                                           , proto::make<detail::scope_is_nullary_actions()> | ||
|  |                                         ) | ||
|  |                                     > | ||
|  |                                   , proto::make<proto::empty_env()> | ||
|  |                                 ) | ||
|  |                             > | ||
|  |                         > | ||
|  |                       , proto::otherwise< | ||
|  |                             proto::call< | ||
|  |                                 evaluator( | ||
|  |                                     proto::_child_c<1> | ||
|  |                                   , proto::_data | ||
|  |                                   , proto::make<proto::empty_env()> | ||
|  |                                 ) | ||
|  |                             > | ||
|  |                         > | ||
|  |                     > | ||
|  |                 > | ||
|  |               , proto::when< | ||
|  |                     phoenix::rule::try_catch | ||
|  |                   , proto::make< | ||
|  |                         mpl::and_< | ||
|  |                             proto::call< | ||
|  |                                 evaluator( | ||
|  |                                     proto::_child_c<0> | ||
|  |                                   , proto::_data | ||
|  |                                   , proto::make<proto::empty_env()> | ||
|  |                                 ) | ||
|  |                             > | ||
|  |                           , proto::fold< | ||
|  |                                 proto::call< | ||
|  |                                     proto::functional::pop_front(proto::_) | ||
|  |                                 > | ||
|  |                               , proto::make<mpl::true_()> | ||
|  |                               , proto::make< | ||
|  |                                     mpl::and_< | ||
|  |                                         proto::_state | ||
|  |                                       , proto::call< | ||
|  |                                             try_catch_is_nullary( | ||
|  |                                                 proto::_ | ||
|  |                                               , proto::make<proto::empty_env()> | ||
|  |                                               , proto::_data | ||
|  |                                             ) | ||
|  |                                         > | ||
|  |                                     >() | ||
|  |                                 > | ||
|  |                             > | ||
|  |                         >() | ||
|  |                     > | ||
|  |                 > | ||
|  |             > | ||
|  |         {}; | ||
|  | 
 | ||
|  |         template < | ||
|  |             typename TryCatch | ||
|  |           , typename Exception | ||
|  |           , typename Capture | ||
|  |           , typename Expr | ||
|  |           , long Arity = proto::arity_of<TryCatch>::value | ||
|  |         > | ||
|  |         struct catch_push_back; | ||
|  | 
 | ||
|  |         template <typename TryCatch, typename Exception, typename Capture, typename Expr> | ||
|  |         struct catch_push_back<TryCatch, Exception, Capture, Expr, 1> | ||
|  |         { | ||
|  |             typedef | ||
|  |                 typename proto::result_of::make_expr< | ||
|  |                     phoenix::tag::catch_ | ||
|  |                   , proto::basic_default_domain | ||
|  |                   , catch_exception<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<Exception>(), capture, catch_) | ||
|  |                     ); | ||
|  |             } | ||
|  |         }; | ||
|  | 
 | ||
|  |         template <typename TryCatch, typename Exception, typename Expr> | ||
|  |         struct catch_push_back<TryCatch, Exception, void, Expr, 1> | ||
|  |         { | ||
|  |             typedef | ||
|  |                 typename proto::result_of::make_expr< | ||
|  |                     phoenix::tag::catch_ | ||
|  |                   , proto::basic_default_domain | ||
|  |                   , catch_exception<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<Exception>(), catch_) | ||
|  |                     ); | ||
|  |             } | ||
|  |         }; | ||
|  |          | ||
|  |         template < | ||
|  |             typename TryCatch | ||
|  |           , typename Expr | ||
|  |           , long Arity = proto::arity_of<TryCatch>::value | ||
|  |         > | ||
|  |         struct catch_all_push_back; | ||
|  | 
 | ||
|  |         template <typename TryCatch, typename Expr> | ||
|  |         struct catch_all_push_back<TryCatch, Expr, 1> | ||
|  |         { | ||
|  |             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 <boost/phoenix/statement/detail/catch_push_back.hpp> | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename Dummy> | ||
|  |     struct is_nullary::when<rule::try_catch, Dummy> | ||
|  |         : proto::call< | ||
|  |             detail::try_catch_is_nullary( | ||
|  |                 proto::_ | ||
|  |               , proto::make<proto::empty_env()> | ||
|  |               , _context | ||
|  |             ) | ||
|  |         > | ||
|  |     {}; | ||
|  | 
 | ||
|  |     template <typename TryCatch, typename Exception, typename Capture = void> | ||
|  |     struct catch_gen | ||
|  |     { | ||
|  |         catch_gen(TryCatch const& try_catch_, Capture const& capture) | ||
|  |             : try_catch(try_catch_) | ||
|  |             , capture(capture) {} | ||
|  | 
 | ||
|  |         template <typename Expr> | ||
|  |         typename boost::disable_if< | ||
|  |             proto::matches< | ||
|  |                 typename proto::result_of::child_c< | ||
|  |                     TryCatch | ||
|  |                   , proto::arity_of<TryCatch>::value - 1 | ||
|  |                 >::type | ||
|  |               , rule::catch_all | ||
|  |             > | ||
|  |           , typename detail::catch_push_back<TryCatch, Exception, Capture, Expr>::type | ||
|  |         >::type | ||
|  |         operator[](Expr const& expr) const | ||
|  |         { | ||
|  |             return | ||
|  |                 detail::catch_push_back<TryCatch, Exception, Capture, Expr>::make( | ||
|  |                     try_catch, capture, expr | ||
|  |                 ); | ||
|  |         } | ||
|  | 
 | ||
|  |         TryCatch const & try_catch; | ||
|  |         Capture const & capture; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename TryCatch, typename Exception> | ||
|  |     struct catch_gen<TryCatch, Exception, void> | ||
|  |     { | ||
|  |         catch_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {} | ||
|  | 
 | ||
|  |         template <typename Expr> | ||
|  |         typename boost::disable_if< | ||
|  |             proto::matches< | ||
|  |                 typename proto::result_of::child_c< | ||
|  |                     TryCatch | ||
|  |                   , proto::arity_of<TryCatch>::value - 1 | ||
|  |                 >::type | ||
|  |               , rule::catch_all | ||
|  |             > | ||
|  |           , typename detail::catch_push_back<TryCatch, Exception, void, Expr>::type | ||
|  |         >::type | ||
|  |         operator[](Expr const& expr) const | ||
|  |         { | ||
|  |             return | ||
|  |                 detail::catch_push_back<TryCatch, Exception, void, Expr>::make( | ||
|  |                     try_catch, expr | ||
|  |                 ); | ||
|  |         } | ||
|  | 
 | ||
|  |         TryCatch const & try_catch; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename TryCatch> | ||
|  |     struct catch_all_gen | ||
|  |     { | ||
|  |         catch_all_gen(TryCatch const& try_catch_) : try_catch(try_catch_) {} | ||
|  | 
 | ||
|  |         template <typename Expr> | ||
|  |         typename boost::disable_if< | ||
|  |             proto::matches< | ||
|  |                 typename proto::result_of::child_c< | ||
|  |                     TryCatch | ||
|  |                   , proto::arity_of<TryCatch>::value - 1 | ||
|  |                 >::type | ||
|  |               , rule::catch_all | ||
|  |             > | ||
|  |           , typename detail::catch_all_push_back<TryCatch, Expr>::type | ||
|  |         >::type | ||
|  |         operator[](Expr const& expr) const | ||
|  |         { | ||
|  |             return detail::catch_all_push_back<TryCatch, Expr>::make( | ||
|  |                 try_catch, expr | ||
|  |             ); | ||
|  |         } | ||
|  | 
 | ||
|  |         TryCatch const & try_catch; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template < | ||
|  |         typename Expr | ||
|  |     > | ||
|  |     struct try_catch_actor; | ||
|  | 
 | ||
|  |     template <typename Expr> | ||
|  |     struct try_catch_actor | ||
|  |         : actor<Expr> | ||
|  |     { | ||
|  |         typedef try_catch_actor<Expr> that_type; | ||
|  |         typedef actor<Expr> base_type; | ||
|  | 
 | ||
|  |         try_catch_actor(base_type const& expr) | ||
|  |             : base_type(expr) | ||
|  |             , catch_all(*this) | ||
|  |         { | ||
|  |         } | ||
|  | 
 | ||
|  |         template <typename Exception> | ||
|  |         catch_gen<that_type, Exception> const | ||
|  |         catch_() const | ||
|  |         { | ||
|  |             return catch_gen<that_type, Exception>(*this); | ||
|  |         } | ||
|  | 
 | ||
|  |         template <typename Exception, typename Capture> | ||
|  |         catch_gen<that_type, Exception, Capture> const | ||
|  |         catch_(Capture const &expr) const | ||
|  |         { | ||
|  |             return catch_gen<that_type, Exception, Capture>(*this, expr); | ||
|  |         } | ||
|  | 
 | ||
|  |         catch_all_gen<that_type> const catch_all; | ||
|  |     }; | ||
|  | 
 | ||
|  |     struct try_gen | ||
|  |     { | ||
|  |         template <typename Try> | ||
|  |         typename expression::try_catch<Try>::type const | ||
|  |         operator[](Try const & try_) const | ||
|  |         { | ||
|  |             return expression::try_catch<Try>::make(try_); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  | #ifndef BOOST_PHOENIX_NO_PREDEFINED_TERMINALS | ||
|  |     try_gen const try_ = {}; | ||
|  | #endif | ||
|  | }} | ||
|  | 
 | ||
|  | #ifdef _MSC_VER | ||
|  | #pragma warning(pop) | ||
|  | #endif | ||
|  | 
 | ||
|  | #endif |