| /*============================================================================= |
| Copyright (c) 2005-2007 Dan Marsden |
| Copyright (c) 2005-2007 Joel de Guzman |
| |
| 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 PHOENIX_STATEMENT_TRY_CATCH_HPP |
| #define PHOENIX_STATEMENT_TRY_CATCH_HPP |
| |
| #include <boost/spirit/home/phoenix/core/actor.hpp> |
| #include <boost/spirit/home/phoenix/core/composite.hpp> |
| |
| #include <boost/fusion/include/push_back.hpp> |
| #include <boost/fusion/include/as_vector.hpp> |
| |
| #include <boost/spirit/home/phoenix/statement/detail/catch_composite.hpp> |
| #include <boost/spirit/home/phoenix/statement/detail/catch_eval.hpp> |
| #include <boost/spirit/home/phoenix/statement/detail/catch_all_eval.hpp> |
| |
| #if defined(BOOST_MSVC) |
| # pragma warning(push) |
| # pragma warning(disable:4355) |
| #endif |
| |
| namespace boost { namespace phoenix { |
| |
| template<typename Tuple> struct try_catch_composite; |
| |
| namespace meta |
| { |
| template<typename Composite, typename Actor> |
| struct try_catch_composite_push_back |
| { |
| typedef typename Composite::base_type actor_tuple; |
| typedef try_catch_composite< |
| typename fusion::result_of::as_vector< |
| typename fusion::result_of::push_back< |
| actor_tuple, Actor>::type>::type> type; |
| }; |
| |
| template<typename Composite, typename Actor> |
| struct catch_all_composite_push_back |
| { |
| typedef typename Composite::base_type actor_tuple; |
| |
| typedef composite< |
| catch_all_eval, |
| typename fusion::result_of::as_vector< |
| typename fusion::result_of::push_back< |
| actor_tuple, Actor>::type>::type> type; |
| }; |
| } |
| |
| namespace detail |
| { |
| struct try_catch_composite_push_back |
| { |
| template<typename Composite, typename Actor> |
| struct result |
| : meta::try_catch_composite_push_back<Composite, Actor> |
| {}; |
| |
| template<typename Composite, typename Actor> |
| typename result<Composite, Actor>::type |
| operator()( |
| const Composite& composite, const Actor& actor) const |
| { |
| typedef typename result<Composite, Actor>::type result; |
| return result( |
| fusion::as_vector( |
| fusion::push_back(composite, actor))); |
| } |
| }; |
| |
| struct catch_all_composite_push_back |
| { |
| template<typename Composite, typename Actor> |
| struct result |
| : meta::catch_all_composite_push_back<Composite, Actor> |
| {}; |
| |
| template<typename Composite, typename Actor> |
| typename result<Composite, Actor>::type |
| operator()( |
| const Composite& composite, const Actor& actor) const |
| { |
| typedef typename result<Composite, Actor>::type result; |
| return result( |
| fusion::as_vector( |
| fusion::push_back(composite, actor))); |
| } |
| }; |
| |
| } |
| |
| detail::try_catch_composite_push_back const try_catch_composite_push_back |
| = detail::try_catch_composite_push_back(); |
| detail::catch_all_composite_push_back const catch_all_composite_push_back |
| = detail::catch_all_composite_push_back(); |
| |
| template<typename Exception, typename SourceComposite> |
| struct catch_gen |
| { |
| explicit catch_gen( |
| const SourceComposite& sourceComposite) |
| : mSourceComposite(sourceComposite) { } |
| |
| template<typename Actor> |
| actor<typename meta::try_catch_composite_push_back< |
| SourceComposite, |
| detail::catch_composite<Exception, Actor> >::type> |
| operator[](const Actor& actor) const |
| { |
| return try_catch_composite_push_back( |
| mSourceComposite, detail::catch_composite<Exception, Actor>(actor)); |
| } |
| |
| const SourceComposite& mSourceComposite; |
| }; |
| |
| template<typename SourceComposite> |
| struct catch_all_gen |
| { |
| explicit catch_all_gen( |
| const SourceComposite& sourceComposite) |
| : mSourceComposite(sourceComposite) { } |
| |
| template<typename Actor> |
| actor<typename meta::catch_all_composite_push_back<SourceComposite, Actor>::type> |
| operator[](const Actor& actor) const |
| { |
| return catch_all_composite_push_back( |
| mSourceComposite, actor); |
| } |
| |
| const SourceComposite& mSourceComposite; |
| }; |
| |
| template<typename Tuple> |
| struct try_catch_composite |
| : composite<catch_eval, Tuple> |
| { |
| explicit try_catch_composite( |
| const Tuple& t) |
| : |
| composite<catch_eval, Tuple>(t), |
| catch_all(*this) { } |
| |
| try_catch_composite( |
| const try_catch_composite& rhs) |
| : composite<catch_eval, Tuple>(rhs), |
| catch_all(*this) { } |
| |
| template<typename Exception> |
| catch_gen<Exception, try_catch_composite> catch_() const |
| { |
| return catch_gen<Exception, try_catch_composite>( |
| *this); |
| } |
| |
| const catch_all_gen<try_catch_composite> catch_all; |
| |
| private: |
| try_catch_composite& operator=(const try_catch_composite&); |
| }; |
| |
| struct try_gen |
| { |
| template<typename Try> |
| try_catch_composite<fusion::vector<Try> > operator[]( |
| const Try& try_) const |
| { |
| typedef fusion::vector<Try> tuple_type; |
| return try_catch_composite<tuple_type>( |
| tuple_type(try_)); |
| } |
| }; |
| |
| try_gen const try_ = try_gen(); |
| }} |
| |
| #if defined(BOOST_MSVC) |
| # pragma warning(pop) |
| #endif |
| |
| #endif |