blob: 35c875ebde80356fe77cf6c615bd111d08657a01 [file] [log] [blame]
/*=============================================================================
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