/*=============================================================================
    Copyright (c) 2002-2003 Joel de Guzman
    Copyright (c) 2002-2003 Hartmut Kaiser
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to 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)
=============================================================================*/
#if !defined(BOOST_SPIRIT_SUBRULE_IPP)
#define BOOST_SPIRIT_SUBRULE_IPP

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    template <typename FirstT, typename RestT>
    struct subrule_list;

    template <int ID, typename DefT, typename ContextT>
    struct subrule_parser;

    namespace impl {

    #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

        template <int N, typename ListT>
        struct get_subrule;

        template <int N, typename ListT>
        struct get_subrule_chooser
        {
                static ListT t();
                static char test(nil_t);
                static int  test(...);

                //  Set value to
                //      0: ListT is empty
                //      1: ListT's first item has same ID
                //      2: ListT's first item has a different ID

                enum
                {
                id = ListT::first_t::id,
                is_same_id = N == id,
                    is_nil_t = sizeof(char) == sizeof(test(t())),
                    value = is_nil_t ? 0 : (is_same_id ? 1 : 2)
                };
          };

        template <int N>
        struct subrule_chooser;

        template <>
        struct subrule_chooser<0>
        {
            //  First case. ListT is empty

            template <int N, typename ListT>
            struct result
            { typedef nil_t type; };
        };

        template <>
        struct subrule_chooser<1>
        {
            //  Second case. ListT is non-empty and the list's
            //  first item has the ID we are looking for.

            template <int N, typename ListT>
            struct result
            { typedef typename ListT::first_t::def_t type; };
        };

        template <>
        struct subrule_chooser<2>
        {
            //  Third case. ListT is non-empty but the list's
            //  first item does not have the ID we are looking for.

            template <int N, typename ListT>
            struct result
            { typedef typename get_subrule<N, ListT::rest_t>::type type; };
        };

        template <int N, typename ListT>
        struct get_subrule
        {
            enum { n = get_subrule_chooser<N, ListT>::value };
            typedef typename subrule_chooser<n>::template
                result<N, ListT>::type type;
        };

    #else

        template <int N, typename ListT>
        struct get_subrule
        {
            //  First case. ListT is non-empty but the list's
            //  first item does not have the ID we are looking for.

            typedef typename get_subrule<N, typename ListT::rest_t>::type type;
        };

        template <int ID, typename DefT, typename ContextT, typename RestT>
        struct get_subrule<
            ID,
            subrule_list<
                subrule_parser<ID, DefT, ContextT>,
                RestT> >
        {
            //  Second case. ListT is non-empty and the list's
            //  first item has the ID we are looking for.

            typedef DefT type;
        };

        template <int ID>
        struct get_subrule<ID, nil_t>
        {
            //  Third case. ListT is empty
            typedef nil_t type;
        };

    #endif

        template <typename T1, typename T2>
        struct get_result_t {

        //  If the result type dictated by the context is nil_t (no closures
        //  present), then the whole subrule_parser return type is equal to
        //  the return type of the right hand side of this subrule_parser,
        //  otherwise it is equal to the dictated return value.

            typedef typename mpl::if_<
                boost::is_same<T1, nil_t>, T2, T1
            >::type type;
        };

        template <int ID, typename ScannerT, typename ContextResultT>
        struct get_subrule_result
        {
            typedef typename
                impl::get_subrule<ID, typename ScannerT::list_t>::type
            parser_t;

            typedef typename parser_result<parser_t, ScannerT>::type
            def_result_t;

            typedef typename match_result<ScannerT, ContextResultT>::type
            context_result_t;

            typedef typename get_result_t<context_result_t, def_result_t>::type
            type;
        };

        template <typename DefT, typename ScannerT, typename ContextResultT>
        struct get_subrule_parser_result
        {
            typedef typename parser_result<DefT, ScannerT>::type
            def_result_t;

            typedef typename match_result<ScannerT, ContextResultT>::type
            context_result_t;

            typedef typename get_result_t<context_result_t, def_result_t>::type
            type;
        };

        template <typename SubruleT, int ID>
        struct same_subrule_id
        {
            BOOST_STATIC_CONSTANT(bool, value = (SubruleT::id == ID));
        };

        template <typename RT, typename ScannerT, int ID>
        struct parse_subrule
        {
            template <typename ListT>
            static void
            do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::true_)
            {
                r = list.first.rhs.parse(scan);
            }

            template <typename ListT>
            static void
            do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::false_)
            {
                typedef typename ListT::rest_t::first_t subrule_t;
                mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id;
                do_parse(r, scan, list.rest, same_id);
            }

            static void
            do_(RT& r, ScannerT const& scan)
            {
                typedef typename ScannerT::list_t::first_t subrule_t;
                mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id;
                do_parse(r, scan, scan.list, same_id);
            }
        };

}

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

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

#endif

