189 lines
5.8 KiB
C++
189 lines
5.8 KiB
C++
/*=============================================================================
|
|
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
|