| /*============================================================================= |
| 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 |