/*=============================================================================
    Spirit v1.6.2
    Copyright (c) 2003 Hartmut Kaiser
    http://spirit.sourceforge.net/

    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 BOOST_SPIRIT_SWITCH_IPP
#define BOOST_SPIRIT_SWITCH_IPP

#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/repeat_from_to.hpp>

#include <boost/spirit/core/parser.hpp>
#include <boost/spirit/core/primitives/primitives.hpp>
#include <boost/spirit/core/composite/composite.hpp>
#include <boost/spirit/core/meta/impl/parser_type.hpp>

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

#include <boost/spirit/phoenix/actor.hpp>
#include <boost/spirit/phoenix/tuples.hpp>

#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {

// forward declaration
template <int N, typename ParserT, bool IsDefault> struct case_parser;

///////////////////////////////////////////////////////////////////////////////
namespace impl {

///////////////////////////////////////////////////////////////////////////////
//  parse helper functions
template <typename ParserT, typename ScannerT>
inline typename parser_result<ParserT, ScannerT>::type
delegate_parse(ParserT const &p, ScannerT const &scan,
    typename ScannerT::iterator_t const save)
{
    typedef typename parser_result<ParserT, ScannerT>::type result_t;

    result_t result (p.subject().parse(scan));
    if (!result)
        scan.first = save;
    return result;
}

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

template <bool IsDefault, bool HasDefault>
struct default_delegate_parse_base {
    template<int N>
    struct inner {
        template <
            typename ParserT, typename DefaultT,
            typename ValueT, typename ScannerT,
            typename IteratorT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse(ValueT const &value, ParserT const &p, DefaultT const &,
            ScannerT const &scan, IteratorT const save)
        {
            if (value == N)
                return delegate_parse(p, scan, save);
            return scan.no_match();
        }
    };
};

template <>
struct default_delegate_parse_base<true,true> {
    template<int N>
    struct inner {
        template <
            typename ParserT, typename DefaultT,
            typename ValueT, typename ScannerT,
            typename IteratorT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse (ValueT const& value, ParserT const &, DefaultT const &d,
            ScannerT const &scan, typename IteratorT const save)
        {
            //  Since there is a default_p case branch defined, the corresponding
            //  parser shouldn't be the nothing_parser
            BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
            return delegate_parse(d, scan, save);
        }
    };
};

template <>
struct default_delegate_parse_base<true,false> {
    template<int N>
    struct inner : default_delegate_parse_base<true,true>::inner<N> {};
};

template <>
struct default_delegate_parse_base<false,true> {
    template<int N>
    struct inner {
        template <
            typename ParserT, typename DefaultT,
            typename ValueT, typename ScannerT,
            typename IteratorT
        >
        static typename parser_result<ParserT, ScannerT>::type
        parse (ValueT const &value, ParserT const &p, DefaultT const &d,
            ScannerT const &scan, typename IteratorT const save)
        {
            //  Since there is a default_p case branch defined, the corresponding
            //  parser shouldn't be the nothing_parser
            BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
            if (value == N)
                return delegate_parse(p, scan, save);

            return delegate_parse(d, scan, save);
        }
    };
};

template <int N, bool IsDefault, bool HasDefault>
struct default_delegate_parse : default_delegate_parse_base<IsDefault,HasDefault>::inner<N> 
{
};

#else 
///////////////////////////////////////////////////////////////////////////////
//  General default case handling (no default_p case branch given).
//  First try to match the current parser node (if the condition value is
//  matched) and, if that fails, return a no_match
template <int N, bool IsDefault, bool HasDefault>
struct default_delegate_parse {

    template <
        typename ParserT, typename DefaultT,
        typename ValueT, typename ScannerT
    >
    static typename parser_result<ParserT, ScannerT>::type
    parse (ValueT const &value, ParserT const &p, DefaultT const &,
        ScannerT const &scan, typename ScannerT::iterator_t const save)
    {
        if (value == N)
            return delegate_parse(p, scan, save);
        return scan.no_match();
    }
};

//  The current case parser node is the default parser.
//  Ignore the given case value and try to match the given default parser.
template <int N, bool HasDefault>
struct default_delegate_parse<N, true, HasDefault> {

    template <
        typename ParserT, typename DefaultT,
        typename ValueT, typename ScannerT
    >
    static typename parser_result<ParserT, ScannerT>::type
    parse (ValueT const& /*value*/, ParserT const &, DefaultT const &d,
        ScannerT const &scan, typename ScannerT::iterator_t const save)
    {
        //  Since there is a default_p case branch defined, the corresponding
        //  parser shouldn't be the nothing_parser
        BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
        return delegate_parse(d, scan, save);
    }
};

//  The current case parser node is not the default parser, but there is a
//  default_p branch given inside the switch_p parser.
//  First try to match the current parser node (if the condition value is
//  matched) and, if that fails, match the given default_p parser.
template <int N>
struct default_delegate_parse<N, false, true> {

    template <
        typename ParserT, typename DefaultT,
        typename ValueT, typename ScannerT
    >
    static typename parser_result<ParserT, ScannerT>::type
    parse (ValueT const &value, ParserT const &p, DefaultT const &d,
        ScannerT const &scan, typename ScannerT::iterator_t const save)
    {
        //  Since there is a default_p case branch defined, the corresponding
        //  parser shouldn't be the nothing_parser
        BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
        if (value == N)
            return delegate_parse(p, scan, save);

        return delegate_parse(d, scan, save);
    }
};

#endif
///////////////////////////////////////////////////////////////////////////////
//  Look through the case parser chain to test, if there is a default case
//  branch defined (returned by 'value').
template <typename CaseT, bool IsSimple = CaseT::is_simple>
struct default_case;

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

    template<bool IsDefault>
    struct get_default_parser_base {
        template<typename ResultT>
        struct inner {
            template <typename ParserT>
            static ResultT
            get(parser<ParserT> const &p)
            {
                return default_case<BOOST_DEDUCED_TYPENAME ParserT::derived_t::left_t>::
                    get(p.derived().left());
            }
        };
    };

    template<>
    struct get_default_parser_base<true> {
        template<typename ResultT>
        struct inner {
            template <typename ParserT>
            static ResultT
            get(parser<ParserT> const &p) { return p.derived().right(); }
        };
    };

    template <typename ResultT, bool IsDefault>
    struct get_default_parser : get_default_parser_base<IsDefault>::inner<ResultT>
    {};

////////////////////////////////////////
#else 

    template <typename ResultT, bool IsDefault>
    struct get_default_parser {

        template <typename ParserT>
        static ResultT
        get(parser<ParserT> const &p)
        {
            return default_case<typename ParserT::derived_t::left_t>::
                get(p.derived().left());
        }
    };

    template <typename ResultT>
    struct get_default_parser<ResultT, true> {

        template <typename ParserT>
        static ResultT
        get(parser<ParserT> const &p) { return p.derived().right(); }
    };

#endif
////////////////////////////////////////

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

    template<bool IsDefault>
    struct get_default_parser_simple_base {
        template<typename ResultT>
        struct inner {
            template <typename ParserT>
            static ResultT
            get(parser<ParserT> const &p) { return p.derived(); }
        };
    };

    template<>
    struct get_default_parser_simple_base<false> {
        template<typename ResultT>
        struct inner {
            template <typename ParserT>
            static nothing_parser
            get(parser<ParserT> const &) { return nothing_p; }
        };
    };

    template <typename ResultT, bool IsDefault>
    struct get_default_parser_simple : get_default_parser_simple_base<IsDefault>::inner<ResultT>
    {};

#else
////////////////////////////////////////
    template <typename ResultT, bool IsDefault>
    struct get_default_parser_simple {

        template <typename ParserT>
        static ResultT
        get(parser<ParserT> const &p) { return p.derived(); }
    };

    template <typename ResultT>
    struct get_default_parser_simple<ResultT, false> {

        template <typename ParserT>
        static nothing_parser
        get(parser<ParserT> const &) { return nothing_p; }
    };
#endif

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

template <bool IsSimple>
struct default_case_base {
    template<typename CaseT>
    struct inner {
        //  The 'value' constant is true, if the current case_parser or one of its
        //  left siblings is a default_p generated case_parser.
        BOOST_STATIC_CONSTANT(bool, value =
            (CaseT::is_default || default_case<typename CaseT::left_t>::value));

        //  The 'is_epsilon' constant is true, if the current case_parser or one of
        //  its left siblings is a default_p generated parser with an attached
        //  epsilon_p (this is generated by the plain default_p).
        BOOST_STATIC_CONSTANT(bool, is_epsilon = (
            (CaseT::is_default && CaseT::is_epsilon) ||
                default_case<typename CaseT::left_t>::is_epsilon
        ));

        //  The computed 'type' represents the type of the default case branch
        //  parser (if there is one) or nothing_parser (if there isn't any default
        //  case branch).
        typedef typename boost::mpl::if_c<
                CaseT::is_default, typename CaseT::right_embed_t,
                typename default_case<typename CaseT::left_t>::type
            >::type type;

        //  The get function returns the parser attached to the default case branch
        //  (if there is one) or an instance of a nothing_parser (if there isn't
        //  any default case branch).
        template <typename ParserT>
        static type
        get(parser<ParserT> const &p)
        { return get_default_parser<type, CaseT::is_default>::get(p); }
    };
};

template <>
struct default_case_base<true> {
    template<typename CaseT>
    struct inner {
        //  The 'value' and 'is_epsilon' constant, the 'type' type and the function
        //  'get' are described above.

        BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default);
        BOOST_STATIC_CONSTANT(bool, is_epsilon = (
            CaseT::is_default && CaseT::is_epsilon
        ));

        typedef typename boost::mpl::if_c<
                CaseT::is_default, CaseT, nothing_parser
            >::type type;

        template <typename ParserT>
        static type
        get(parser<ParserT> const &p)
        { return get_default_parser_simple<type, value>::get(p); }    
    };
};

template <typename CaseT, bool IsSimple>
struct default_case : default_case_base<IsSimple>::inner<CaseT> {};

#else

template <typename CaseT, bool IsSimple>
struct default_case {

    //  The 'value' constant is true, if the current case_parser or one of its
    //  left siblings is a default_p generated case_parser.
    BOOST_STATIC_CONSTANT(bool, value =
        (CaseT::is_default || default_case<typename CaseT::left_t>::value));

    //  The 'is_epsilon' constant is true, if the current case_parser or one of
    //  its left siblings is a default_p generated parser with an attached
    //  epsilon_p (this is generated by the plain default_p).
    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
        (CaseT::is_default && CaseT::is_epsilon) ||
            default_case<typename CaseT::left_t>::is_epsilon
    ));

    //  The computed 'type' represents the type of the default case branch
    //  parser (if there is one) or nothing_parser (if there isn't any default
    //  case branch).
    typedef typename boost::mpl::if_c<
            CaseT::is_default, typename CaseT::right_embed_t,
            typename default_case<typename CaseT::left_t>::type
        >::type type;

    //  The get function returns the parser attached to the default case branch
    //  (if there is one) or an instance of a nothing_parser (if there isn't
    //  any default case branch).
    template <typename ParserT>
    static type
    get(parser<ParserT> const &p)
    { return get_default_parser<type, CaseT::is_default>::get(p); }
};

////////////////////////////////////////
//  Specialization of the default_case template for the last (leftmost) element
//  of the case parser chain.
template <typename CaseT>
struct default_case<CaseT, true> {

    //  The 'value' and 'is_epsilon' constant, the 'type' type and the function
    //  'get' are described above.

    BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default);
    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
        CaseT::is_default && CaseT::is_epsilon
    ));

    typedef typename boost::mpl::if_c<
            CaseT::is_default, CaseT, nothing_parser
        >::type type;

    template <typename ParserT>
    static type
    get(parser<ParserT> const &p)
    { return get_default_parser_simple<type, value>::get(p); }
};

#endif

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

template <bool IsSimple>
struct case_chain_base {
    template<typename CaseT>
    struct inner {
        BOOST_STATIC_CONSTANT(int, depth = (
            case_chain<typename CaseT::left_t>::depth + 1
        ));
    };
};

template <>
struct case_chain_base<true> {
    template<typename CaseT>
    struct inner {
        BOOST_STATIC_CONSTANT(int, depth = 0);
    };
};

template <typename CaseT, bool IsSimple = CaseT::is_simple>
struct case_chain : case_chain_base<IsSimple>::inner<CaseT>{};

#else
///////////////////////////////////////////////////////////////////////////////
//  The case_chain template calculates recursivly the depth of the left
//  subchain of the given case branch node.
template <typename CaseT, bool IsSimple = CaseT::is_simple>
struct case_chain {

    BOOST_STATIC_CONSTANT(int, depth = (
        case_chain<typename CaseT::left_t>::depth + 1
    ));
};

template <typename CaseT>
struct case_chain<CaseT, true> {

    BOOST_STATIC_CONSTANT(int, depth = 0);
};
#endif

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION


template <int Depth, typename CaseT>
struct chain_parser;

template <int Depth>
struct chain_parser_base {
    template<typename CaseT>
    struct inner {
        typedef typename CaseT::left_t our_left_t;

        typedef typename chain_parser<Depth-1, our_left_t>::left_t  left_t;
        typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t;

        static left_t
        left(CaseT const &p)
        { return chain_parser<Depth-1, our_left_t>::left(p.left()); }

        static right_t
        right(CaseT const &p)
        { return chain_parser<Depth-1, our_left_t>::right(p.left()); }
    };
};

template<>
struct chain_parser_base<1> {
    template<typename CaseT>
    struct inner {
        typedef typename CaseT::left_t  left_t;
        typedef typename CaseT::right_t right_t;

        static left_t left(CaseT const &p) { return p.left(); }
        static right_t right(CaseT const &p) { return p.right(); }
    };
};

template<>
struct chain_parser_base<0> {
    template<typename CaseT>
    struct inner;
};

template <int Depth, typename CaseT>
struct chain_parser : chain_parser_base<Depth>::inner<CaseT>{};

#else
///////////////////////////////////////////////////////////////////////////////
//  The chain_parser template is used to extract the type and the instance of
//  a left or a right parser, burried arbitrary deep inside the case parser
//  chain.
template <int Depth, typename CaseT>
struct chain_parser {

    typedef typename CaseT::left_t our_left_t;

    typedef typename chain_parser<Depth-1, our_left_t>::left_t  left_t;
    typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t;

    static left_t
    left(CaseT const &p)
    { return chain_parser<Depth-1, our_left_t>::left(p.left()); }

    static right_t
    right(CaseT const &p)
    { return chain_parser<Depth-1, our_left_t>::right(p.left()); }
};

template <typename CaseT>
struct chain_parser<1, CaseT> {

    typedef typename CaseT::left_t  left_t;
    typedef typename CaseT::right_t right_t;

    static left_t left(CaseT const &p) { return p.left(); }
    static right_t right(CaseT const &p) { return p.right(); }
};

template <typename CaseT>
struct chain_parser<0, CaseT>;      // shouldn't be instantiated
#endif

///////////////////////////////////////////////////////////////////////////////
//  The parse_switch::do_ functions dispatch to the correct parser, which is
//  selected through the given conditional switch value.
template <int Value, int Depth, bool IsDefault>
struct parse_switch;

///////////////////////////////////////////////////////////////////////////////
//
//  The following generates a couple of parse_switch template specializations
//  with an increasing number of handled case branches (for 1..N).
//
//      template <int Value, bool IsDefault>
//      struct parse_switch<Value, N, IsDefault> {
//
//          template <typename ParserT, typename ScannerT>
//          static typename parser_result<ParserT, ScannerT>::type
//          do_(ParserT const &p, ScannerT const &scan, long cond_value,
//              typename ScannerT::iterator_t const &save)
//          {
//              typedef ParserT left_t0;
//              typedef typename left_t0::left left_t1;
//              ...
//
//              switch (cond_value) {
//              case left_tN::value:
//                  return delegate_parse(chain_parser<
//                          case_chain<ParserT>::depth, ParserT
//                      >::left(p), scan, save);
//              ...
//              case left_t1::value:
//                  return delegate_parse(chain_parser<
//                          1, left_t1
//                      >::right(p.left()), scan, save);
//
//              case left_t0::value:
//              default:
//                  typedef default_case<ParserT> default_t;
//                  typedef default_delegate_parse<
//                              Value, IsDefault, default_t::value>
//                      default_parse_t;
//
//                  return default_parse_t::parse(cond_value, p.right(),
//                      default_t::get(p), scan, save);
//              }
//          }
//      };
//
///////////////////////////////////////////////////////////////////////////////


#define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _)                         \
    typedef typename BOOST_PP_CAT(left_t, N)::left_t                        \
        BOOST_PP_CAT(left_t, BOOST_PP_INC(N));                              \
    /**/

#define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _)                            \
    case BOOST_PP_CAT(left_t, N)::value:                                    \
        return delegate_parse(chain_parser<N, left_t1>::right(p.left()),    \
            scan, save);                                                    \
    /**/

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

#define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _)                                \
    template<>                                                              \
    struct parse_switch_base<BOOST_PP_INC(N)> {                             \
    template <int Value, bool IsDefault>                                    \
    struct inner {                                                          \
        template <typename ParserT, typename ScannerT,typename IteratorT>   \
        static typename parser_result<ParserT, ScannerT>::type              \
        do_(ParserT const &p, ScannerT const &scan, long cond_value,        \
            IteratorT const &save)                      \
        {                                                                   \
            typedef ParserT left_t0;                                        \
            BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N),               \
                BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _)                      \
                                                                            \
            switch (cond_value) {                                           \
            case BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value:              \
                return delegate_parse(                                      \
                    chain_parser<                                           \
                        case_chain<ParserT>::depth, ParserT                 \
                    >::left(p), scan, save);                                \
                                                                            \
            BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N),               \
                BOOST_SPIRIT_PARSE_SWITCH_CASES, _)                         \
                                                                            \
            case left_t0::value:                                            \
            default:                                                        \
                typedef default_case<ParserT> default_t;                    \
                typedef                                                     \
                    default_delegate_parse<Value, IsDefault, default_t::value> \
                    default_parse_t;                                        \
                                                                            \
                return default_parse_t::parse(cond_value, p.right(),        \
                    default_t::get(p), scan, save);                         \
            }                                                               \
        }                                                                   \
    };                                                                      \
    };                                                                      \
    /**/
#else
#define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _)                                \
    template <int Value, bool IsDefault>                                    \
    struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> {                \
                                                                            \
        template <typename ParserT, typename ScannerT>                      \
        static typename parser_result<ParserT, ScannerT>::type              \
        do_(ParserT const &p, ScannerT const &scan, long cond_value,        \
            typename ScannerT::iterator_t const &save)                      \
        {                                                                   \
            typedef ParserT left_t0;                                        \
            BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N),               \
                BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _)                      \
                                                                            \
            switch (cond_value) {                                           \
            case BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value:              \
                return delegate_parse(                                      \
                    chain_parser<                                           \
                        case_chain<ParserT>::depth, ParserT                 \
                    >::left(p), scan, save);                                \
                                                                            \
            BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N),               \
                BOOST_SPIRIT_PARSE_SWITCH_CASES, _)                         \
                                                                            \
            case left_t0::value:                                            \
            default:                                                        \
                typedef default_case<ParserT> default_t;                    \
                typedef                                                     \
                    default_delegate_parse<Value, IsDefault, default_t::value> \
                    default_parse_t;                                        \
                                                                            \
                return default_parse_t::parse(cond_value, p.right(),        \
                    default_t::get(p), scan, save);                         \
            }                                                               \
        }                                                                   \
    };                                                                      \
    /**/
#endif

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<int Depth>
struct parse_switch_base {
    template<int Value, bool IsDefault>
    struct inner;
};
#endif

BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_SPIRIT_SWITCH_CASE_LIMIT),
    BOOST_SPIRIT_PARSE_SWITCHES, _)

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <int Value, int Depth, bool IsDefault>
struct parse_switch : parse_switch_base<Depth>::inner<Value,IsDefault> {
};
#endif

#undef BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS
#undef BOOST_SPIRIT_PARSE_SWITCH_CASES
#undef BOOST_SPIRIT_PARSE_SWITCHES
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//  Type computing meta function for calculating the type of the return value
//  of the used conditional switch expression

#if BOOST_WORKAROUND( BOOST_MSVC, <= 1300)
} //namespace impl

BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER(condition_result_wrapper, result);

namespace impl {

template <typename TargetT, typename ScannerT>
struct condition_result {
    typedef typename impl::condition_result_wrapper<TargetT>
        ::template result_<ScannerT>::param_t::type type;
};
#else
template <typename TargetT, typename ScannerT>
struct condition_result {

    typedef typename TargetT::template result<ScannerT>::type type;
};
#endif 


///////////////////////////////////////////////////////////////////////////////
template <typename LeftT, typename RightT, bool IsDefault>
struct compound_case_parser
:   public binary<LeftT, RightT,
        parser<compound_case_parser<LeftT, RightT, IsDefault> > >
{
    typedef compound_case_parser<LeftT, RightT, IsDefault>    self_t;
    typedef binary_parser_category                  parser_category_t;
    typedef binary<LeftT, RightT, parser<self_t> >  base_t;

    BOOST_STATIC_CONSTANT(int, value = RightT::value);
    BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
    BOOST_STATIC_CONSTANT(bool, is_simple = false);
    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
        is_default &&
            boost::is_same<typename RightT::subject_t, epsilon_parser>::value
    ));

    compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs)
    :   base_t(lhs.derived(), rhs.derived())
    {}

    compound_case_parser()
    : base_t() 
    {}

    template <typename ScannerT>
    struct result
    {
        typedef typename match_result<ScannerT, nil_t>::type type;
    };

    template <typename ScannerT, typename CondT>
    typename parser_result<self_t, ScannerT>::type
    parse(ScannerT const& scan, CondT const &cond) const
    {
        if (!scan.at_end()) {
            return parse_switch<value, case_chain<self_t>::depth, is_default>::
                do_(*this, scan, cond(scan), scan.first);
        }
        return default_case<self_t>::is_epsilon ? scan.empty_match() :
            scan.no_match();
    }

    template <int N1, typename ParserT1, bool IsDefault1>
    compound_case_parser<
        self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
    >
    operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
    {
        //  If the following compile time assertion fires, you've probably used
        //  more than one default_p case inside the switch_p parser construct.
        BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1);

        //  If this compile time assertion fires, you've probably want to use
        //  more case_p/default_p case branches, than possible.
        BOOST_STATIC_ASSERT(
            case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT
        );

        typedef case_parser<N1, ParserT1, IsDefault1> right_t;
        return compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
    }
};

///////////////////////////////////////////////////////////////////////////////
//  The switch condition is to be evaluated from a parser result value.
template <typename ParserT>
struct cond_functor {

    typedef cond_functor<ParserT> self_t;

    cond_functor(ParserT const &p_)
    :   p(p_)
    {}

    template <typename ScannerT>
    struct result
    {
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1300)                                                            
        typedef long type;
#else
        typedef typename parser_result<ParserT, ScannerT>::type::attr_t type;
#endif
    };

    template <typename ScannerT>
    typename condition_result<self_t, ScannerT>::type
    operator()(ScannerT const &scan) const
    {
        typedef typename parser_result<ParserT, ScannerT>::type result_t;
        typedef typename result_t::attr_t attr_t;

        result_t result(p.parse(scan));
        return !result ? attr_t() : result.value();
    }

    typename ParserT::embed_t p;
};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

///////////////////////////////////////////////////////////////////////////////
//  The switch condition is to be evaluated from a phoenix actor
template <typename ActorT>
struct cond_actor {

    typedef cond_actor<ActorT> self_t;

    cond_actor(ActorT const &actor_)
    :   actor(actor_)
    {}

    template <typename ScannerT>
    struct result
    {
        typedef typename phoenix::actor_result<ActorT, phoenix::tuple<> >::type
            type;
    };

    template <typename ScannerT>
    typename condition_result<self_t, ScannerT>::type
    operator()(ScannerT const& /*scan*/) const
    {
        return actor();
    }

    ActorT const &actor;
};

#endif

///////////////////////////////////////////////////////////////////////////////
//  The switch condition is to be taken directly from the input stream
struct get_next_token_cond {

    typedef get_next_token_cond self_t;

    template <typename ScannerT>
    struct result
    {
        typedef typename ScannerT::value_t type;
    };

    template <typename ScannerT>
    typename condition_result<self_t, ScannerT>::type
    operator()(ScannerT const &scan) const
    {
        typename ScannerT::value_t val(*scan);
        ++scan;
        return val;
    }
};

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

template <typename ParserT>
struct make_cond_functor {
    typedef as_parser<ParserT> as_parser_t;
    static cond_functor<typename as_parser_t::type>
    do_(ParserT const &cond)
    {
        return cond_functor<BOOST_DEDUCED_TYPENAME as_parser_t::type>(
            as_parser_t::convert(cond));
    }    
};

#else

template <typename ParserT>
struct make_cond_functor {

    typedef as_parser<ParserT> as_parser_t;

    static cond_functor<typename as_parser_t::type>
    do_(ParserT const &cond)
    {
        return cond_functor<typename as_parser_t::type>(
            as_parser_t::convert(cond));
    }
};

template <typename ActorT>
struct make_cond_functor<phoenix::actor<ActorT> > {

    static cond_actor<phoenix::actor<ActorT> >
    do_(phoenix::actor<ActorT> const &actor)
    {
        return cond_actor<phoenix::actor<ActorT> >(actor);
    }
};

#endif

template <>
struct make_cond_functor<get_next_token_cond> {

    static get_next_token_cond
    do_(get_next_token_cond const &cond)
    {
        return cond;
    }
};

///////////////////////////////////////////////////////////////////////////////
}   // namespace impl
}}  // namespace boost::spirit

#endif  // BOOST_SPIRIT_SWITCH_IPP
