165 lines
5.0 KiB
C++
165 lines
5.0 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2001-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_SWITCH_HPP
|
|
#define PHOENIX_STATEMENT_SWITCH_HPP
|
|
|
|
#include <boost/spirit/home/phoenix/core/composite.hpp>
|
|
#include <boost/spirit/home/phoenix/core/compose.hpp>
|
|
#include <boost/spirit/home/phoenix/core/nothing.hpp>
|
|
#include <boost/spirit/home/phoenix/statement/detail/switch_eval.hpp>
|
|
#include <boost/spirit/home/phoenix/statement/detail/switch.hpp>
|
|
#include <boost/utility/enable_if.hpp>
|
|
#include <boost/mpl/not.hpp>
|
|
|
|
namespace boost { namespace phoenix
|
|
{
|
|
template <typename Derived, typename Actor>
|
|
struct switch_case_base
|
|
{
|
|
typedef Derived derived_t;
|
|
typedef Actor actor_t;
|
|
typedef typename Actor::no_nullary no_nullary;
|
|
|
|
template <typename Env>
|
|
struct result
|
|
{
|
|
typedef typename Actor::eval_type::template result<Env>::type type;
|
|
};
|
|
|
|
switch_case_base(Actor const& actor)
|
|
: actor(actor) {}
|
|
|
|
template <typename Env>
|
|
typename result<Env>::type
|
|
eval(Env const& env) const
|
|
{
|
|
return actor.eval(env);
|
|
}
|
|
|
|
Actor actor;
|
|
};
|
|
|
|
template <typename Actor, typename K, K Value>
|
|
struct switch_case : switch_case_base<switch_case<Actor, K, Value>, Actor>
|
|
{
|
|
typedef switch_case_base<switch_case<Actor, K, Value>, Actor> base_t;
|
|
static K const value = Value;
|
|
static bool const is_default = false;
|
|
|
|
switch_case(Actor const& actor)
|
|
: base_t(actor) {}
|
|
};
|
|
|
|
template <typename Actor>
|
|
struct default_case : switch_case_base<default_case<Actor>, Actor>
|
|
{
|
|
typedef switch_case_base<default_case<Actor>, Actor> base_t;
|
|
static bool const is_default = true;
|
|
|
|
default_case(Actor const& actor)
|
|
: base_t(actor) {}
|
|
};
|
|
|
|
template <typename Cond>
|
|
struct switch_gen
|
|
{
|
|
switch_gen(Cond const& cond)
|
|
: cond(cond) {}
|
|
|
|
template <typename Cases>
|
|
typename lazy_enable_if<
|
|
fusion::traits::is_sequence<Cases>
|
|
, detail::switch_composite_actor<Cond, Cases>
|
|
>::type
|
|
operator[](Cases const& cases) const
|
|
{
|
|
typedef typename
|
|
detail::switch_composite<Cond, Cases>
|
|
switch_composite;
|
|
return switch_composite::eval(cond, cases);
|
|
}
|
|
|
|
template <typename D, typename A>
|
|
actor<typename detail::
|
|
switch_composite<Cond, fusion::vector<actor<D> > >::type>
|
|
operator[](switch_case_base<D, A> const& case_) const
|
|
{
|
|
typedef typename
|
|
detail::switch_composite<Cond, fusion::vector<actor<D> > >
|
|
switch_composite;
|
|
return switch_composite::eval(cond,
|
|
fusion::vector<actor<D> >(static_cast<D const&>(case_)));
|
|
}
|
|
|
|
Cond cond;
|
|
};
|
|
|
|
template <typename Cond>
|
|
inline switch_gen<typename as_actor<Cond>::type>
|
|
switch_(Cond const& cond)
|
|
{
|
|
return switch_gen<typename as_actor<Cond>::type>(
|
|
as_actor<Cond>::convert(cond));
|
|
}
|
|
|
|
template <int N, typename A0>
|
|
switch_case<typename as_actor<A0>::type, int, N>
|
|
case_(A0 const& _0)
|
|
{
|
|
return switch_case<typename as_actor<A0>::type, int, N>
|
|
(as_actor<A0>::convert(_0));
|
|
}
|
|
|
|
template <typename A0>
|
|
default_case<typename as_actor<A0>::type>
|
|
default_(A0 const& _0)
|
|
{
|
|
return default_case<typename as_actor<A0>::type>
|
|
(as_actor<A0>::convert(_0));
|
|
}
|
|
|
|
template <typename D0, typename A0, typename D1, typename A1>
|
|
inline typename detail::compose_case_a<D0, D1>::type
|
|
operator,(
|
|
switch_case_base<D0, A0> const& _0
|
|
, switch_case_base<D1, A1> const& _1
|
|
)
|
|
{
|
|
return detail::compose_case_a<D0, D1>::eval(
|
|
static_cast<D0 const&>(_0)
|
|
, static_cast<D1 const&>(_1)
|
|
);
|
|
}
|
|
|
|
template <typename Seq, typename D, typename A>
|
|
inline typename
|
|
lazy_enable_if<
|
|
fusion::traits::is_sequence<Seq>
|
|
, detail::compose_case_b<Seq, D>
|
|
>::type
|
|
operator,(Seq const& seq, switch_case_base<D, A> const& case_)
|
|
{
|
|
return detail::compose_case_b<Seq, D>::eval(
|
|
seq, static_cast<D const&>(case_));
|
|
}
|
|
|
|
// Implementation of routines in detail/switch.hpp that depend on
|
|
// the completeness of default_case.
|
|
namespace detail {
|
|
template <typename Cases>
|
|
typename ensure_default<Cases>::type
|
|
ensure_default<Cases>::eval(Cases const& cases, mpl::false_)
|
|
{
|
|
actor<default_case<actor<null_actor> > > default_
|
|
= default_case<actor<null_actor> >(nothing);
|
|
return fusion::push_front(cases, default_);
|
|
}
|
|
}
|
|
}}
|
|
|
|
#endif
|