code:
    ///////////////////////////////////////////////////////////////////////////////
    /// \file traits.hpp
    /// Definitions of proto::function, proto::nary_expr and proto::result_of::child_c
    //
    //  Copyright 2008 Eric Niebler. 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)
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 0>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child0 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child0>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 0>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child0 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child0>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child0;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 0>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child0 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child0>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child0;
                }
            };
        }

        template<typename A0>
        struct function
        <
            A0
            , void , void , void , void , void , void , void , void , void
        >
          : proto::transform<
                function<
                    A0
                    , void , void , void , void , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list1<A0>, 1> type;
            typedef proto::basic_expr<proto::tag::function, list1<A0>, 1> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0;
            typedef detail::if_vararg<A0> proto_child1; typedef detail::if_vararg<A0> proto_child2; typedef detail::if_vararg<A0> proto_child3; typedef detail::if_vararg<A0> proto_child4; typedef detail::if_vararg<A0> proto_child5; typedef detail::if_vararg<A0> proto_child6; typedef detail::if_vararg<A0> proto_child7; typedef detail::if_vararg<A0> proto_child8; typedef detail::if_vararg<A0> proto_child9;
        };

        template<typename Tag , typename A0>
        struct nary_expr
        <
            Tag
            , A0
            , void , void , void , void , void , void , void , void , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0
                    , void , void , void , void , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list1<A0>, 1> type;
            typedef proto::basic_expr<Tag, list1<A0>, 1> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0;
            typedef detail::if_vararg<A0> proto_child1; typedef detail::if_vararg<A0> proto_child2; typedef detail::if_vararg<A0> proto_child3; typedef detail::if_vararg<A0> proto_child4; typedef detail::if_vararg<A0> proto_child5; typedef detail::if_vararg<A0> proto_child6; typedef detail::if_vararg<A0> proto_child7; typedef detail::if_vararg<A0> proto_child8; typedef detail::if_vararg<A0> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename> class T
              , typename A0
            >
            struct is_callable_<T<A0> BOOST_PROTO_TEMPLATE_ARITY_PARAM(1)>
              : is_same<A0, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 1>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child1 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child1>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 1>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child1 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child1>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child1;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 1>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child1 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child1>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child1;
                }
            };
        }

        template<typename A0 , typename A1>
        struct function
        <
            A0 , A1
            , void , void , void , void , void , void , void , void
        >
          : proto::transform<
                function<
                    A0 , A1
                    , void , void , void , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list2<A0 , A1>, 2> type;
            typedef proto::basic_expr<proto::tag::function, list2<A0 , A1>, 2> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1;
            typedef detail::if_vararg<A1> proto_child2; typedef detail::if_vararg<A1> proto_child3; typedef detail::if_vararg<A1> proto_child4; typedef detail::if_vararg<A1> proto_child5; typedef detail::if_vararg<A1> proto_child6; typedef detail::if_vararg<A1> proto_child7; typedef detail::if_vararg<A1> proto_child8; typedef detail::if_vararg<A1> proto_child9;
        };

        template<typename Tag , typename A0 , typename A1>
        struct nary_expr
        <
            Tag
            , A0 , A1
            , void , void , void , void , void , void , void , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1
                    , void , void , void , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list2<A0 , A1>, 2> type;
            typedef proto::basic_expr<Tag, list2<A0 , A1>, 2> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1;
            typedef detail::if_vararg<A1> proto_child2; typedef detail::if_vararg<A1> proto_child3; typedef detail::if_vararg<A1> proto_child4; typedef detail::if_vararg<A1> proto_child5; typedef detail::if_vararg<A1> proto_child6; typedef detail::if_vararg<A1> proto_child7; typedef detail::if_vararg<A1> proto_child8; typedef detail::if_vararg<A1> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename , typename> class T
              , typename A0 , typename A1
            >
            struct is_callable_<T<A0 , A1> BOOST_PROTO_TEMPLATE_ARITY_PARAM(2)>
              : is_same<A1, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 2>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child2 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child2>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 2>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child2 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child2>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child2;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 2>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child2 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child2>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child2;
                }
            };
        }

        template<typename A0 , typename A1 , typename A2>
        struct function
        <
            A0 , A1 , A2
            , void , void , void , void , void , void , void
        >
          : proto::transform<
                function<
                    A0 , A1 , A2
                    , void , void , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list3<A0 , A1 , A2>, 3> type;
            typedef proto::basic_expr<proto::tag::function, list3<A0 , A1 , A2>, 3> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2;
            typedef detail::if_vararg<A2> proto_child3; typedef detail::if_vararg<A2> proto_child4; typedef detail::if_vararg<A2> proto_child5; typedef detail::if_vararg<A2> proto_child6; typedef detail::if_vararg<A2> proto_child7; typedef detail::if_vararg<A2> proto_child8; typedef detail::if_vararg<A2> proto_child9;
        };

        template<typename Tag , typename A0 , typename A1 , typename A2>
        struct nary_expr
        <
            Tag
            , A0 , A1 , A2
            , void , void , void , void , void , void , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1 , A2
                    , void , void , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list3<A0 , A1 , A2>, 3> type;
            typedef proto::basic_expr<Tag, list3<A0 , A1 , A2>, 3> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2;
            typedef detail::if_vararg<A2> proto_child3; typedef detail::if_vararg<A2> proto_child4; typedef detail::if_vararg<A2> proto_child5; typedef detail::if_vararg<A2> proto_child6; typedef detail::if_vararg<A2> proto_child7; typedef detail::if_vararg<A2> proto_child8; typedef detail::if_vararg<A2> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename , typename , typename> class T
              , typename A0 , typename A1 , typename A2
            >
            struct is_callable_<T<A0 , A1 , A2> BOOST_PROTO_TEMPLATE_ARITY_PARAM(3)>
              : is_same<A2, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 3>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child3 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child3>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 3>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child3 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child3>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child3;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 3>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child3 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child3>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child3;
                }
            };
        }

        template<typename A0 , typename A1 , typename A2 , typename A3>
        struct function
        <
            A0 , A1 , A2 , A3
            , void , void , void , void , void , void
        >
          : proto::transform<
                function<
                    A0 , A1 , A2 , A3
                    , void , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list4<A0 , A1 , A2 , A3>, 4> type;
            typedef proto::basic_expr<proto::tag::function, list4<A0 , A1 , A2 , A3>, 4> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3;
            typedef detail::if_vararg<A3> proto_child4; typedef detail::if_vararg<A3> proto_child5; typedef detail::if_vararg<A3> proto_child6; typedef detail::if_vararg<A3> proto_child7; typedef detail::if_vararg<A3> proto_child8; typedef detail::if_vararg<A3> proto_child9;
        };

        template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3>
        struct nary_expr
        <
            Tag
            , A0 , A1 , A2 , A3
            , void , void , void , void , void , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1 , A2 , A3
                    , void , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list4<A0 , A1 , A2 , A3>, 4> type;
            typedef proto::basic_expr<Tag, list4<A0 , A1 , A2 , A3>, 4> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3;
            typedef detail::if_vararg<A3> proto_child4; typedef detail::if_vararg<A3> proto_child5; typedef detail::if_vararg<A3> proto_child6; typedef detail::if_vararg<A3> proto_child7; typedef detail::if_vararg<A3> proto_child8; typedef detail::if_vararg<A3> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename , typename , typename , typename> class T
              , typename A0 , typename A1 , typename A2 , typename A3
            >
            struct is_callable_<T<A0 , A1 , A2 , A3> BOOST_PROTO_TEMPLATE_ARITY_PARAM(4)>
              : is_same<A3, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 4>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child4 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child4>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 4>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child4 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child4>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child4;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 4>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child4 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child4>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child4;
                }
            };
        }

        template<typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
        struct function
        <
            A0 , A1 , A2 , A3 , A4
            , void , void , void , void , void
        >
          : proto::transform<
                function<
                    A0 , A1 , A2 , A3 , A4
                    , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list5<A0 , A1 , A2 , A3 , A4>, 5> type;
            typedef proto::basic_expr<proto::tag::function, list5<A0 , A1 , A2 , A3 , A4>, 5> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4;
            typedef detail::if_vararg<A4> proto_child5; typedef detail::if_vararg<A4> proto_child6; typedef detail::if_vararg<A4> proto_child7; typedef detail::if_vararg<A4> proto_child8; typedef detail::if_vararg<A4> proto_child9;
        };

        template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
        struct nary_expr
        <
            Tag
            , A0 , A1 , A2 , A3 , A4
            , void , void , void , void , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1 , A2 , A3 , A4
                    , void , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list5<A0 , A1 , A2 , A3 , A4>, 5> type;
            typedef proto::basic_expr<Tag, list5<A0 , A1 , A2 , A3 , A4>, 5> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4;
            typedef detail::if_vararg<A4> proto_child5; typedef detail::if_vararg<A4> proto_child6; typedef detail::if_vararg<A4> proto_child7; typedef detail::if_vararg<A4> proto_child8; typedef detail::if_vararg<A4> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename , typename , typename , typename , typename> class T
              , typename A0 , typename A1 , typename A2 , typename A3 , typename A4
            >
            struct is_callable_<T<A0 , A1 , A2 , A3 , A4> BOOST_PROTO_TEMPLATE_ARITY_PARAM(5)>
              : is_same<A4, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 5>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child5 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child5>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 5>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child5 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child5>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child5;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 5>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child5 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child5>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child5;
                }
            };
        }

        template<typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
        struct function
        <
            A0 , A1 , A2 , A3 , A4 , A5
            , void , void , void , void
        >
          : proto::transform<
                function<
                    A0 , A1 , A2 , A3 , A4 , A5
                    , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list6<A0 , A1 , A2 , A3 , A4 , A5>, 6> type;
            typedef proto::basic_expr<proto::tag::function, list6<A0 , A1 , A2 , A3 , A4 , A5>, 6> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5;
            typedef detail::if_vararg<A5> proto_child6; typedef detail::if_vararg<A5> proto_child7; typedef detail::if_vararg<A5> proto_child8; typedef detail::if_vararg<A5> proto_child9;
        };

        template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5>
        struct nary_expr
        <
            Tag
            , A0 , A1 , A2 , A3 , A4 , A5
            , void , void , void , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1 , A2 , A3 , A4 , A5
                    , void , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list6<A0 , A1 , A2 , A3 , A4 , A5>, 6> type;
            typedef proto::basic_expr<Tag, list6<A0 , A1 , A2 , A3 , A4 , A5>, 6> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5;
            typedef detail::if_vararg<A5> proto_child6; typedef detail::if_vararg<A5> proto_child7; typedef detail::if_vararg<A5> proto_child8; typedef detail::if_vararg<A5> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename , typename , typename , typename , typename , typename> class T
              , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5
            >
            struct is_callable_<T<A0 , A1 , A2 , A3 , A4 , A5> BOOST_PROTO_TEMPLATE_ARITY_PARAM(6)>
              : is_same<A5, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 6>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child6 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child6>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 6>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child6 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child6>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child6;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 6>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child6 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child6>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child6;
                }
            };
        }

        template<typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
        struct function
        <
            A0 , A1 , A2 , A3 , A4 , A5 , A6
            , void , void , void
        >
          : proto::transform<
                function<
                    A0 , A1 , A2 , A3 , A4 , A5 , A6
                    , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list7<A0 , A1 , A2 , A3 , A4 , A5 , A6>, 7> type;
            typedef proto::basic_expr<proto::tag::function, list7<A0 , A1 , A2 , A3 , A4 , A5 , A6>, 7> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5; typedef A6 proto_child6;
            typedef detail::if_vararg<A6> proto_child7; typedef detail::if_vararg<A6> proto_child8; typedef detail::if_vararg<A6> proto_child9;
        };

        template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6>
        struct nary_expr
        <
            Tag
            , A0 , A1 , A2 , A3 , A4 , A5 , A6
            , void , void , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1 , A2 , A3 , A4 , A5 , A6
                    , void , void , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list7<A0 , A1 , A2 , A3 , A4 , A5 , A6>, 7> type;
            typedef proto::basic_expr<Tag, list7<A0 , A1 , A2 , A3 , A4 , A5 , A6>, 7> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5; typedef A6 proto_child6;
            typedef detail::if_vararg<A6> proto_child7; typedef detail::if_vararg<A6> proto_child8; typedef detail::if_vararg<A6> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename , typename , typename , typename , typename , typename , typename> class T
              , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6
            >
            struct is_callable_<T<A0 , A1 , A2 , A3 , A4 , A5 , A6> BOOST_PROTO_TEMPLATE_ARITY_PARAM(7)>
              : is_same<A6, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 7>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child7 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child7>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 7>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child7 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child7>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child7;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 7>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child7 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child7>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child7;
                }
            };
        }

        template<typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
        struct function
        <
            A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7
            , void , void
        >
          : proto::transform<
                function<
                    A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7
                    , void , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list8<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7>, 8> type;
            typedef proto::basic_expr<proto::tag::function, list8<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7>, 8> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5; typedef A6 proto_child6; typedef A7 proto_child7;
            typedef detail::if_vararg<A7> proto_child8; typedef detail::if_vararg<A7> proto_child9;
        };

        template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7>
        struct nary_expr
        <
            Tag
            , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7
            , void , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7
                    , void , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list8<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7>, 8> type;
            typedef proto::basic_expr<Tag, list8<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7>, 8> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5; typedef A6 proto_child6; typedef A7 proto_child7;
            typedef detail::if_vararg<A7> proto_child8; typedef detail::if_vararg<A7> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename , typename , typename , typename , typename , typename , typename , typename> class T
              , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7
            >
            struct is_callable_<T<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7> BOOST_PROTO_TEMPLATE_ARITY_PARAM(8)>
              : is_same<A7, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 8>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child8 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child8>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 8>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child8 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child8>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child8;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 8>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child8 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child8>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child8;
                }
            };
        }

        template<typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
        struct function
        <
            A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8
            , void
        >
          : proto::transform<
                function<
                    A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8
                    , void
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list9<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8>, 9> type;
            typedef proto::basic_expr<proto::tag::function, list9<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8>, 9> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5; typedef A6 proto_child6; typedef A7 proto_child7; typedef A8 proto_child8;
            typedef detail::if_vararg<A8> proto_child9;
        };

        template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8>
        struct nary_expr
        <
            Tag
            , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8
            , void
        >
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8
                    , void
                >
              , int
            >
        {
            typedef proto::expr<Tag, list9<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8>, 9> type;
            typedef proto::basic_expr<Tag, list9<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8>, 9> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5; typedef A6 proto_child6; typedef A7 proto_child7; typedef A8 proto_child8;
            typedef detail::if_vararg<A8> proto_child9;
        };
        namespace detail
        {
            template<
                template<typename , typename , typename , typename , typename , typename , typename , typename , typename> class T
              , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8
            >
            struct is_callable_<T<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8> BOOST_PROTO_TEMPLATE_ARITY_PARAM(9)>
              : is_same<A8, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 9>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child9 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child9>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 9>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child9 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child9>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child9;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 9>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child9 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child9>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child9;
                }
            };
        }

        template<typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
        struct function
          : proto::transform<
                function<
                    A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9

                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, list10<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9>, 10> type;
            typedef proto::basic_expr<proto::tag::function, list10<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9>, 10> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            typedef proto::tag::function proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5; typedef A6 proto_child6; typedef A7 proto_child7; typedef A8 proto_child8; typedef A9 proto_child9;

        };

        template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9>
        struct nary_expr
          : proto::transform<
                nary_expr<
                    Tag
                    , A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9

                >
              , int
            >
        {
            typedef proto::expr<Tag, list10<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9>, 10> type;
            typedef proto::basic_expr<Tag, list10<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9>, 10> proto_grammar;
            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            typedef Tag proto_tag;
            typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4; typedef A5 proto_child5; typedef A6 proto_child6; typedef A7 proto_child7; typedef A8 proto_child8; typedef A9 proto_child9;

        };
        namespace detail
        {
            template<
                template<typename , typename , typename , typename , typename , typename , typename , typename , typename , typename> class T
              , typename A0 , typename A1 , typename A2 , typename A3 , typename A4 , typename A5 , typename A6 , typename A7 , typename A8 , typename A9
            >
            struct is_callable_<T<A0 , A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9> BOOST_PROTO_TEMPLATE_ARITY_PARAM(10)>
              : is_same<A9, callable>
            {};
        }
        namespace result_of
        {

            template<typename Expr>
            struct child_c<Expr, 10>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child10 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child10>::value_type type;
            };
            template<typename Expr>
            struct child_c<Expr &, 10>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child10 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child10>::reference type;

                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().child10;
                }
            };
            template<typename Expr>
            struct child_c<Expr const &, 10>
            {

                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                typedef typename Expr::proto_child10 value_type;

                typedef typename detail::expr_traits<typename Expr::proto_child10>::const_reference type;

                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().child10;
                }
            };
        }


code:
    ///////////////////////////////////////////////////////////////////////////////
    /// \file vararg_matches_impl.hpp
    /// Specializations of the vararg_matches_impl template
    //
    //  Copyright 2008 Eric Niebler. 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)
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 2, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child1>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child1>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 2 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 2, 2>
      : matches_<
            typename detail::expr_traits<typename Args::child1>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child1>::value_type::proto_grammar
          , Back
        >
    {};
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 3, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child2>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child2>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 3 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 3, 3>
      : matches_<
            typename detail::expr_traits<typename Args::child2>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child2>::value_type::proto_grammar
          , Back
        >
    {};
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 4, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child3>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child3>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 4 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 4, 4>
      : matches_<
            typename detail::expr_traits<typename Args::child3>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child3>::value_type::proto_grammar
          , Back
        >
    {};
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 5, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child4>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child4>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 5 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 5, 5>
      : matches_<
            typename detail::expr_traits<typename Args::child4>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child4>::value_type::proto_grammar
          , Back
        >
    {};
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 6, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child5>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child5>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 6 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 6, 6>
      : matches_<
            typename detail::expr_traits<typename Args::child5>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child5>::value_type::proto_grammar
          , Back
        >
    {};
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 7, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child6>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child6>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 7 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 7, 7>
      : matches_<
            typename detail::expr_traits<typename Args::child6>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child6>::value_type::proto_grammar
          , Back
        >
    {};
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 8, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child7>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child7>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 8 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 8, 8>
      : matches_<
            typename detail::expr_traits<typename Args::child7>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child7>::value_type::proto_grammar
          , Back
        >
    {};
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 9, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child8>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child8>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 9 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 9, 9>
      : matches_<
            typename detail::expr_traits<typename Args::child8>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child8>::value_type::proto_grammar
          , Back
        >
    {};
    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, 10, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::child9>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::child9>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, 10 + 1, To>
        >
    {};
    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, 10, 10>
      : matches_<
            typename detail::expr_traits<typename Args::child9>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::child9>::value_type::proto_grammar
          , Back
        >
    {};

license: mit


code:
//==============================================================================
//         Copyright 2003 - 2011  LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2011  LRI    UMR 8623 CNRS/Univ Paris Sud XI
//         Copyright 2011         Eric Niebler
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_PROTO_PREPROCESSOR_REMOVE_TYPENAME_HPP_INCLUDED
#define BOOST_PROTO_PREPROCESSOR_REMOVE_TYPENAME_HPP_INCLUDED

/*!
 * \file
 * \brief Defines the BOOST_PROTO_REMOVE_TYPENAME macro
 */
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/expand.hpp>
#include <boost/preprocessor/tuple/eat.hpp>
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/detail/is_unary.hpp>

//==============================================================================
// Boost.Preprocessor author P. Mensodines confirmed on an Boost email thread
// (subject ``check if a token is a keyword (was "BOOST_PP_IS_UNARY()")'')
// that it is OK to used `PP_IS_UNARY()` to check if tokens match predefined
// "keyword" as it is done by the macros below (even if `PP_IS_UNARY()` is
// technically only part of Boost.Preprocessor private API).
//==============================================================================

//==============================================================================
// `checking_prefix ## tokens` expand to unary (e.g., `(1)`) iff `tokens` start
// with keyword to check.
//==============================================================================
#define BOOST_PROTO_DETAILS_KEYWORD_FACILITY_IS_FRONT(T, CHECKING_PREFIX)                           \
    BOOST_PP_IS_UNARY(BOOST_PP_CAT(CHECKING_PREFIX, T))                                             \
    /**/

//==============================================================================
// `is_front_macro(tokens)` is 1 iff `tokens` start with keyword to remove.
// `removing_prefix ## <keyword-to-remove>` must expand to nothing.
//==============================================================================
#define BOOST_PROTO_DETAILS_KEYWORD_FACILITY_REMOVE_FRONT(TOKENS, IS_FRONT_MACRO, REMOVING_PREFIX)  \
    BOOST_PP_EXPAND( /* without EXPAND doesn't expand on MSVC */                                    \
        BOOST_PP_IIF(                                                                               \
            IS_FRONT_MACRO(TOKENS)                                                                  \
          , BOOST_PP_CAT                                                                            \
          , TOKENS BOOST_PP_TUPLE_EAT(2)                                                            \
        )(REMOVING_PREFIX, TOKENS)                                                                  \
    )                                                                                \
    /**/

#define BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS_typename (1) /* unary */
#define typename_BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS (1) /* unary */
#define BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE_typename /* nothing */
#define typename_BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE /* nothing */

#define BOOST_PROTO_DETAILS_KEYWORD_IS_TYPENAME_FRONT(TOKENS)                                       \
    BOOST_PROTO_DETAILS_KEYWORD_FACILITY_IS_FRONT(TOKENS, BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS_) \
    /**/

//==============================================================================
/*!
 * \ingroup preprocessor
 * For any symbol \c X, this macro returns the same symbol from which a potential
 * leading \c typename keyword has been removed. If no typename keyword is present,
 * this macros evaluates to \c X itself without error.
 *
 * The original implementation of this macro is from Lorenzo Caminiti.
 *
 * \param X Symbol to remove \c typename from
 */
//==============================================================================
#define BOOST_PROTO_REMOVE_TYPENAME(X)                                                              \
    BOOST_PROTO_DETAILS_KEYWORD_FACILITY_REMOVE_FRONT(                                              \
        X                                                                                \
      , BOOST_PROTO_DETAILS_KEYWORD_IS_TYPENAME_FRONT                                               \
      , BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE_                                                \
    )                                                                                \
    /**/

#endif


code:
///////////////////////////////////////////////////////////////////////////////
/// \file static_const.hpp
/// Contains definition of static_const for declaring static constants that
//
//  Copyright 2008 Eric Niebler. 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_PROTO_DETAIL_STATIC_CONST_HPP_EAN_20_07_2012
#define BOOST_PROTO_DETAIL_STATIC_CONST_HPP_EAN_20_07_2012

namespace boost { namespace proto
{
    namespace detail
    {
        template<typename T>
        struct static_const
        {
            static T const value;
        };

        template<typename T>
        T const static_const<T>::value = {};
    }
}}

#endif


code:
///////////////////////////////////////////////////////////////////////////////
/// \file template_arity.hpp
/// Replace all nodes stored by reference by nodes stored by value.
//
//  Copyright 2011 Eric Niebler. 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)
//
//  This file is based on a similar one in MPL from Aleksey Gurtovoy.

#ifndef BOOST_PROTO_DETAIL_TEMPLATE_ARITY_HPP_EAN_2011_05_07
#define BOOST_PROTO_DETAIL_TEMPLATE_ARITY_HPP_EAN_2011_05_07

// Somewhat indirect definition of BOOST_PROTO_TEMPLATE_ARITY_PARAM is
// to overcome a shortcoming of the Wave tool used to generate the
// pre-preprocessed headers.
#define BOOST_PROTO_TEMPLATE_ARITY_PARAM BOOST_PROTO_TEMPLATE_ARITY_PARAM2
#define BOOST_PROTO_TEMPLATE_ARITY_PARAM2(param)

#if defined(BOOST_PROTO_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) ||                                   \
  (defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES))

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/mpl/int.hpp>
#include <boost/proto/proto_fwd.hpp>

#undef BOOST_PROTO_TEMPLATE_ARITY_PARAM2
#define BOOST_PROTO_TEMPLATE_ARITY_PARAM2(param) , param

namespace boost { namespace proto { namespace detail
{
    sized_type<1>::type template_arity_helper(...);

    // Other overloads generated by the preprocessor
    #include <boost/proto/detail/template_arity_helper.hpp>

    template<typename F, int N, int Size>
    struct template_arity_impl2
      : mpl::int_<Size - 1>
    {};

    template<typename F, int N = BOOST_PROTO_MAX_ARITY>
    struct template_arity
      : template_arity_impl2<
            F
          , N
          , sizeof(detail::template_arity_helper((F **)0, (mpl::int_<N> *)0))
        >
    {};

    template<typename F, int N>
    struct template_arity_impl2<F, N, 1>
      : template_arity<F, N-1>
    {};

    template<typename F>
    struct template_arity_impl2<F, 0, 1>
      : mpl::int_<-1>
    {};

}}}

#endif // BOOST_PROTO_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
#endif // BOOST_PROTO_DETAIL_TEMPLATE_ARITY_HPP_EAN_2011_05_07


code:
#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)

    #include <boost/proto/detail/preprocessed/template_arity_helper.hpp>

#elif !defined(BOOST_PP_IS_ITERATING)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 2, line: 0, output: "preprocessed/template_arity_helper.hpp")
    #endif

    ///////////////////////////////////////////////////////////////////////////////
    // template_arity_helper.hpp
    // Overloads of template_arity_helper, used by the template_arity\<\> class template
    //
    //  Copyright 2008 Eric Niebler. 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)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 1)
    #endif

    #define BOOST_PP_ITERATION_PARAMS_1                                                             \
        (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/template_arity_helper.hpp>))
    #include BOOST_PP_ITERATE()

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(output: null)
    #endif

#else

    #define N BOOST_PP_ITERATION()

    template<
        template<BOOST_PP_ENUM_PARAMS(N, typename P)> class F
      , BOOST_PP_ENUM_PARAMS(N, typename T)
    >
    sized_type<BOOST_PP_INC(N)>::type
    template_arity_helper(F<BOOST_PP_ENUM_PARAMS(N, T)> **, mpl::int_<N> *);

    #undef N

#endif // BOOST_PROTO_DONT_USE_PREPROCESSED_FILES


code:
#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)

    #include <boost/proto/detail/preprocessed/traits.hpp>

#elif !defined(BOOST_PP_IS_ITERATING)

    #define BOOST_PROTO_CHILD(Z, N, DATA)                                                           \
        /** INTERNAL ONLY */                                                                        \
        typedef BOOST_PP_CAT(DATA, N) BOOST_PP_CAT(proto_child, N);                                 \
        /**/

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 2, line: 0, output: "preprocessed/traits.hpp")
    #endif

    ///////////////////////////////////////////////////////////////////////////////
    /// \file traits.hpp
    /// Definitions of proto::function, proto::nary_expr and proto::result_of::child_c
    //
    //  Copyright 2008 Eric Niebler. 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)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 1)
    #endif

    #define BOOST_PP_ITERATION_PARAMS_1                                                             \
        (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/traits.hpp>))
    #include BOOST_PP_ITERATE()

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(output: null)
    #endif

    #undef BOOST_PROTO_CHILD

#else // BOOST_PP_IS_ITERATING

    #define N BOOST_PP_ITERATION()

    #if N > 0
        /// \brief A metafunction for generating function-call expression types,
        /// a grammar element for matching function-call expressions, and a
        /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
        /// transform.
        template<BOOST_PP_ENUM_PARAMS(N, typename A)>
        struct function
        #if N != BOOST_PROTO_MAX_ARITY
        <
            BOOST_PP_ENUM_PARAMS(N, A)
            BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
        >
        #endif
          : proto::transform<
                function<
                    BOOST_PP_ENUM_PARAMS(N, A)
                    BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
                >
              , int
            >
        {
            typedef proto::expr<proto::tag::function, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> type;
            typedef proto::basic_expr<proto::tag::function, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> proto_grammar;

            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<function, deduce_domain, Expr, State, Data>
            {};

            /// INTERNAL ONLY
            typedef proto::tag::function proto_tag;
            BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A)
            BOOST_PP_REPEAT_FROM_TO(
                N
              , BOOST_PROTO_MAX_ARITY
              , BOOST_PROTO_CHILD
              , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
            )
        };

        /// \brief A metafunction for generating n-ary expression types with a
        /// specified tag type,
        /// a grammar element for matching n-ary expressions, and a
        /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
        /// transform.
        ///
        /// Use <tt>nary_expr\<_, vararg\<_\> \></tt> as a grammar element to match any
        /// n-ary expression; that is, any non-terminal.
        template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
        struct nary_expr
        #if N != BOOST_PROTO_MAX_ARITY
        <
            Tag
            BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
            BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
        >
        #endif
          : proto::transform<
                nary_expr<
                    Tag
                    BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
                    BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
                >
              , int
            >
        {
            typedef proto::expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> type;
            typedef proto::basic_expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> proto_grammar;

            template<typename Expr, typename State, typename Data>
            struct impl
              : detail::pass_through_impl<nary_expr, deduce_domain, Expr, State, Data>
            {};

            /// INTERNAL ONLY
            typedef Tag proto_tag;
            BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A)
            BOOST_PP_REPEAT_FROM_TO(
                N
              , BOOST_PROTO_MAX_ARITY
              , BOOST_PROTO_CHILD
              , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
            )
        };

        namespace detail
        {
            template<
                template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
              , BOOST_PP_ENUM_PARAMS(N, typename A)
            >
            struct is_callable_<T<BOOST_PP_ENUM_PARAMS(N, A)> BOOST_PROTO_TEMPLATE_ARITY_PARAM(N)>
              : is_same<BOOST_PP_CAT(A, BOOST_PP_DEC(N)), callable>
            {};
        }

    #endif

        namespace result_of
        {
            /// \brief A metafunction that returns the type of the Nth child
            /// of a Proto expression.
            ///
            /// A metafunction that returns the type of the Nth child
            /// of a Proto expression. \c N must be less than
            /// \c Expr::proto_arity::value.
            template<typename Expr>
            struct child_c<Expr, N>
            {
                /// Verify that we are not operating on a terminal
                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                /// The raw type of the Nth child as it is stored within
                /// \c Expr. This may be a value or a reference
                typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;

                /// The "value" type of the child, suitable for return by value,
                /// computed as follows:
                /// \li <tt>T const &</tt> becomes <tt>T</tt>
                /// \li <tt>T &</tt> becomes <tt>T</tt>
                /// \li <tt>T</tt> becomes <tt>T</tt>
                typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::value_type type;
            };

            template<typename Expr>
            struct child_c<Expr &, N>
            {
                /// Verify that we are not operating on a terminal
                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                /// The raw type of the Nth child as it is stored within
                /// \c Expr. This may be a value or a reference
                typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;

                /// The "reference" type of the child, suitable for return by
                /// reference, computed as follows:
                /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
                /// \li <tt>T &</tt> becomes <tt>T &</tt>
                /// \li <tt>T</tt> becomes <tt>T &</tt>
                typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::reference type;

                /// INTERNAL ONLY
                ///
                BOOST_FORCEINLINE
                static type call(Expr &e)
                {
                    return e.proto_base().BOOST_PP_CAT(child, N);
                }
            };

            template<typename Expr>
            struct child_c<Expr const &, N>
            {
                /// Verify that we are not operating on a terminal
                BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);

                /// The raw type of the Nth child as it is stored within
                /// \c Expr. This may be a value or a reference
                typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;

                /// The "const reference" type of the child, suitable for return by
                /// const reference, computed as follows:
                /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
                /// \li <tt>T &</tt> becomes <tt>T &</tt>
                /// \li <tt>T</tt> becomes <tt>T const &</tt>
                typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::const_reference type;

                /// INTERNAL ONLY
                ///
                BOOST_FORCEINLINE
                static type call(Expr const &e)
                {
                    return e.proto_base().BOOST_PP_CAT(child, N);
                }
            };
        }

    #undef N

#endif


code:
#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)

    #include <boost/proto/detail/preprocessed/unpack_expr_.hpp>

#elif !defined(BOOST_PP_IS_ITERATING)

    /// INTERNAL ONLY
    ///
    #define BOOST_PROTO_FUSION_NEXT_ITERATOR_TYPE(Z, N, DATA)                                       \
        typedef typename fusion::result_of::next<                                                   \
            BOOST_PP_CAT(fusion_iterator, N)>::type                                                 \
                BOOST_PP_CAT(fusion_iterator, BOOST_PP_INC(N));                                     \
        /**/

    /// INTERNAL ONLY
    ///
    #define BOOST_PROTO_FUSION_ITERATORS_TYPE(N)                                                    \
        typedef                                                                                \
            typename fusion::result_of::begin<Sequence const>::type                                 \
        fusion_iterator0;                                                                           \
        BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_PROTO_FUSION_NEXT_ITERATOR_TYPE, fusion_iterator)    \
        /**/

    /// INTERNAL ONLY
    ///
    #define BOOST_PROTO_FUSION_AT_TYPE(Z, N, DATA)                                                  \
        typename add_const<                                                                         \
            typename fusion::result_of::value_of<                                                   \
                BOOST_PP_CAT(fusion_iterator, N)                                                    \
            >::type                                                                                \
        >::type                                                                                \
        /**/

    /// INTERNAL ONLY
    ///
    #define BOOST_PROTO_FUSION_NEXT_ITERATOR(Z, N, DATA)                                            \
        BOOST_PP_CAT(fusion_iterator, BOOST_PP_INC(N)) BOOST_PP_CAT(it, BOOST_PP_INC(N)) =          \
            fusion::next(BOOST_PP_CAT(it, N));                                                      \
        /**/

    /// INTERNAL ONLY
    ///
    #define BOOST_PROTO_FUSION_ITERATORS(N)                                                         \
        fusion_iterator0 it0 = fusion::begin(sequence);                                             \
        BOOST_PP_REPEAT(BOOST_PP_DEC(N), BOOST_PROTO_FUSION_NEXT_ITERATOR, fusion_iterator)         \
        /**/

    /// INTERNAL ONLY
    ///
    #define BOOST_PROTO_FUSION_AT(Z, N, DATA)                                                       \
        *BOOST_PP_CAT(it, N)                                                                        \
        /**/

    /// INTERNAL ONLY
    ///
    #define BOOST_PROTO_FUSION_AS_CHILD_AT_TYPE(Z, N, DATA)                                         \
        typename detail::protoify<                                                                  \
            BOOST_PROTO_FUSION_AT_TYPE(Z, N, DATA)                                                  \
          , Domain                                                                                \
        >::result_type                                                                              \
        /**/

    /// INTERNAL ONLY
    ///
    #define BOOST_PROTO_FUSION_AS_CHILD_AT(Z, N, DATA)                                              \
        detail::protoify<                                                                           \
            BOOST_PROTO_FUSION_AT_TYPE(Z, N, DATA)                                                  \
          , Domain                                                                                \
        >()(BOOST_PROTO_FUSION_AT(Z, N, DATA))                                                      \
        /**/

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 2, line: 0, output: "preprocessed/unpack_expr_.hpp")
    #endif

    ///////////////////////////////////////////////////////////////////////////////
    /// \file make_expr_.hpp
    /// Contains definition of make_expr_\<\> class template.
    //
    //  Copyright 2008 Eric Niebler. 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)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 1)
    #endif

    template<typename Tag, typename Domain, typename Sequence, std::size_t Size>
    struct unpack_expr_
    {};

    template<typename Domain, typename Sequence>
    struct unpack_expr_<tag::terminal, Domain, Sequence, 1u>
    {
        typedef
            typename add_const<
                typename fusion::result_of::value_of<
                    typename fusion::result_of::begin<Sequence>::type
                >::type
            >::type
        terminal_type;

        typedef
            typename proto::detail::protoify<
                terminal_type
              , Domain
            >::result_type
        type;

        BOOST_FORCEINLINE
        static type const call(Sequence const &sequence)
        {
            return proto::detail::protoify<terminal_type, Domain>()(fusion::at_c<0>(sequence));
        }
    };

    template<typename Sequence>
    struct unpack_expr_<tag::terminal, deduce_domain, Sequence, 1u>
      : unpack_expr_<tag::terminal, default_domain, Sequence, 1u>
    {};

    #define BOOST_PP_ITERATION_PARAMS_1                                                         \
        (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/unpack_expr_.hpp>))
    #include BOOST_PP_ITERATE()

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(output: null)
    #endif

    #undef BOOST_PROTO_FUSION_AT
    #undef BOOST_PROTO_FUSION_AT_TYPE
    #undef BOOST_PROTO_FUSION_AS_CHILD_AT
    #undef BOOST_PROTO_FUSION_AS_CHILD_AT_TYPE
    #undef BOOST_PROTO_FUSION_NEXT_ITERATOR
    #undef BOOST_PROTO_FUSION_NEXT_ITERATOR_TYPE
    #undef BOOST_PROTO_FUSION_ITERATORS
    #undef BOOST_PROTO_FUSION_ITERATORS_TYPE

#else // BOOST_PP_IS_ITERATING

    #define N BOOST_PP_ITERATION()
    #define M BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N)

    template<typename Tag, typename Domain, typename Sequence>
    struct unpack_expr_<Tag, Domain, Sequence, N>
    {
        BOOST_PROTO_FUSION_ITERATORS_TYPE(N)

        typedef
            BOOST_PP_CAT(list, N)<
                BOOST_PP_ENUM(N, BOOST_PROTO_FUSION_AS_CHILD_AT_TYPE, ~)
            >
        proto_args;

        typedef typename base_expr<Domain, Tag, proto_args>::type expr_type;
        typedef typename Domain::proto_generator proto_generator;
        typedef typename proto_generator::template result<proto_generator(expr_type)>::type type;

        BOOST_FORCEINLINE
        static type const call(Sequence const &sequence)
        {
            BOOST_PROTO_FUSION_ITERATORS(N)
            expr_type const that = {
                BOOST_PP_ENUM(N, BOOST_PROTO_FUSION_AS_CHILD_AT, ~)
            };
            return proto_generator()(that);
        }
    };

    template<typename Tag, typename Sequence>
    struct unpack_expr_<Tag, deduce_domain, Sequence, N>
    {
        BOOST_PROTO_FUSION_ITERATORS_TYPE(N)

        typedef
            unpack_expr_<
                Tag
              , typename BOOST_PP_CAT(deduce_domain, N)<
                    BOOST_PP_ENUM(N, BOOST_PROTO_FUSION_AT_TYPE, ~)
                >::type
              , Sequence
              , N
            >
        other;

        typedef typename other::type type;

        BOOST_FORCEINLINE
        static type const call(Sequence const &sequence)
        {
            return other::call(sequence);
        }
    };

    #undef N
    #undef M

#endif


code:
#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)

    #include <boost/proto/detail/preprocessed/vararg_matches_impl.hpp>

#elif !defined(BOOST_PP_IS_ITERATING)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 2, line: 0, output: "preprocessed/vararg_matches_impl.hpp")
    #endif

    ///////////////////////////////////////////////////////////////////////////////
    /// \file vararg_matches_impl.hpp
    /// Specializations of the vararg_matches_impl template
    //
    //  Copyright 2008 Eric Niebler. 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)

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(preserve: 1)
    #endif

    #define BOOST_PP_ITERATION_PARAMS_1                                                             \
        (3, (2, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/vararg_matches_impl.hpp>))
    #include BOOST_PP_ITERATE()

    #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
        #pragma wave option(output: null)
    #endif

#else // BOOST_PP_IS_ITERATING

    #define N BOOST_PP_ITERATION()

    template<typename Args, typename Back, long To>
    struct vararg_matches_impl<Args, Back, N, To>
      : and_2<
            matches_<
                typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_derived_expr
              , typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_grammar
              , Back
            >::value
          , vararg_matches_impl<Args, Back, N + 1, To>
        >
    {};

    template<typename Args, typename Back>
    struct vararg_matches_impl<Args, Back, N, N>
      : matches_<
            typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_derived_expr
          , typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_grammar
          , Back
        >
    {};

    #undef N

#endif


code:
///////////////////////////////////////////////////////////////////////////////
/// \file domain.hpp
/// Contains definition of domain\<\> class template and helpers for
/// defining domains with a generator and a grammar for controlling
/// operator overloading.
//
//  Copyright 2008 Eric Niebler. 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_PROTO_DOMAIN_HPP_EAN_02_13_2007
#define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007

#include <boost/ref.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/generate.hpp>
#include <boost/proto/detail/as_expr.hpp>
#include <boost/proto/detail/deduce_domain.hpp>

#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
#endif

namespace boost { namespace proto
{

    namespace detail
    {
        struct not_a_generator
        {};

        struct not_a_grammar
        {};

        struct not_a_domain
        {};
    }

    namespace domainns_
    {
        /// \brief For use in defining domain tags to be used
        /// with \c proto::extends\<\>. A \e Domain associates
        /// an expression type with a \e Generator, and optionally
        /// a \e Grammar.
        ///
        /// The Generator determines how new expressions in the
        /// domain are constructed. Typically, a generator wraps
        /// all new expressions in a wrapper that imparts
        /// domain-specific behaviors to expressions within its
        /// domain. (See \c proto::extends\<\>.)
        ///
        /// The Grammar determines whether a given expression is
        /// valid within the domain, and automatically disables
        /// any operator overloads which would cause an invalid
        /// expression to be created. By default, the Grammar
        /// parameter defaults to the wildcard, \c proto::_, which
        /// makes all expressions valid within the domain.
        ///
        /// The Super declares the domain currently being defined
        /// to be a sub-domain of Super. Expressions in sub-domains
        /// can be freely combined with expressions in its super-
        /// domain (and <I>its</I> super-domain, etc.).
        ///
        /// Example:
        /// \code
        /// template<typename Expr>
        /// struct MyExpr;
        ///
        /// struct MyGrammar
        ///   : or_< terminal<_>, plus<MyGrammar, MyGrammar> >
        /// {};
        ///
        /// // Define MyDomain, in which all expressions are
        /// // wrapped in MyExpr<> and only expressions that
        /// // conform to MyGrammar are allowed.
        /// struct MyDomain
        ///   : domain<generator<MyExpr>, MyGrammar>
        /// {};
        ///
        /// // Use MyDomain to define MyExpr
        /// template<typename Expr>
        /// struct MyExpr
        ///   : extends<Expr, MyExpr<Expr>, MyDomain>
        /// {
        ///     // ...
        /// };
        /// \endcode
        ///
        template<
            typename Generator // = default_generator
          , typename Grammar   // = proto::_
          , typename Super     // = no_super_domain
        >
        struct domain
          : Generator
        {
            typedef Generator proto_generator;
            typedef Grammar   proto_grammar;
            typedef Super     proto_super_domain;
            typedef domain    proto_base_domain;

            /// INTERNAL ONLY
            typedef void proto_is_domain_;

            /// \brief A unary MonomorphicFunctionObject that turns objects into Proto
            /// expression objects in this domain.
            ///
            /// The <tt>as_expr\<\></tt> function object turns objects into Proto expressions, if
            /// they are not already, by making them Proto terminals held by value if
            /// possible. Objects that are already Proto expressions are left alone.
            ///
            /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr;
            /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T:
            ///
            /// If \c T is not a Proto expression type the resulting terminal is
            /// calculated as follows:
            ///
            ///   If \c T is a function type, an abstract type, or a type derived from
            ///   \c std::ios_base, let \c A be <tt>T &</tt>.
            ///   Otherwise, let \c A be the type \c T stripped of cv-qualifiers.
            ///   Then, the result of applying <tt>as_expr\<T\>()(t)</tt> is
            ///   <tt>Generator()(E\<tag::terminal, term\<A\> \>::make(t))</tt>.
            ///
            /// If \c T is a Proto expression type and its generator type is different from
            /// \c Generator, the result is <tt>Generator()(t)</tt>.
            ///
            /// Otherwise, the result is \c t converted to an (un-const) rvalue.
            ///
            template<typename T, typename IsExpr = void, typename Callable = proto::callable>
            struct as_expr
              : detail::as_expr<
                    T
                  , typename detail::base_generator<Generator>::type
                  , wants_basic_expr<Generator>::value
                >
            {
                BOOST_PROTO_CALLABLE()
            };

            /// INTERNAL ONLY
            ///
            template<typename T>
            struct as_expr<T, typename T::proto_is_expr_, proto::callable>
            {
                BOOST_PROTO_CALLABLE()
                typedef typename remove_const<T>::type result_type;

                BOOST_FORCEINLINE
                result_type operator()(T &e) const
                {
                    return e;
                }
            };

            /// \brief A unary MonomorphicFunctionObject that turns objects into Proto
            /// expression objects in this domain.
            ///
            /// The <tt>as_child\<\></tt> function object turns objects into Proto expressions, if
            /// they are not already, by making them Proto terminals held by reference.
            /// Objects that are already Proto expressions are simply returned by reference.
            ///
            /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr;
            /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T:
            ///
            /// If \c T is not a Proto expression type the resulting terminal is
            /// <tt>Generator()(E\<tag::terminal, term\<T &\> \>::make(t))</tt>.
            ///
            /// If \c T is a Proto expression type and its generator type is different from
            /// \c Generator, the result is <tt>Generator()(t)</tt>.
            ///
            /// Otherwise, the result is the lvalue \c t.
            ///
            template<typename T, typename IsExpr = void, typename Callable = proto::callable>
            struct as_child
              : detail::as_child<
                    T
                  , typename detail::base_generator<Generator>::type
                  , wants_basic_expr<Generator>::value
                >
            {
                BOOST_PROTO_CALLABLE()
            };

            /// INTERNAL ONLY
            ///
            template<typename T>
            struct as_child<T, typename T::proto_is_expr_, proto::callable>
            {
                BOOST_PROTO_CALLABLE()
                typedef T &result_type;

                BOOST_FORCEINLINE
                result_type operator()(T &e) const
                {
                    return e;
                }
            };
        };

        /// \brief The domain expressions have by default, if
        /// \c proto::extends\<\> has not been used to associate
        /// a domain with an expression.
        ///
        struct default_domain
          : domain<>
        {};

        /// \brief A domain to use when you prefer the use of
        /// \c proto::basic_expr\<\> over \c proto::expr\<\>.
        ///
        struct basic_default_domain
          : domain<basic_default_generator>
        {};

        /// \brief A pseudo-domain for use in functions and
        /// metafunctions that require a domain parameter. It
        /// indicates that the domain of the parent node should
        /// be inferred from the domains of the child nodes.
        ///
        /// \attention \c deduce_domain is not itself a valid domain.
        ///
        struct deduce_domain
          : domain<detail::not_a_generator, detail::not_a_grammar, detail::not_a_domain>
        {};

        /// \brief Given a domain, a tag type and an argument list,
        /// compute the type of the expression to generate. This is
        /// either an instance of \c proto::expr\<\> or
        /// \c proto::basic_expr\<\>.
        ///
        template<typename Domain, typename Tag, typename Args, bool WantsBasicExpr>
        struct base_expr
        {
            typedef proto::expr<Tag, Args, Args::arity> type;
        };

        /// INTERNAL ONLY
        ///
        template<typename Domain, typename Tag, typename Args>
        struct base_expr<Domain, Tag, Args, true>
        {
            typedef proto::basic_expr<Tag, Args, Args::arity> type;
        };

    }

    /// A metafunction that returns \c mpl::true_
    /// if the type \c T is the type of a Proto domain;
    /// \c mpl::false_ otherwise. If \c T inherits from
    /// \c proto::domain\<\>, \c is_domain\<T\> is
    /// \c mpl::true_.
    template<typename T, typename Void  /* = void*/>
    struct is_domain
      : mpl::false_
    {};

    /// INTERNAL ONLY
    ///
    template<typename T>
    struct is_domain<T, typename T::proto_is_domain_>
      : mpl::true_
    {};

    /// A metafunction that returns the domain of
    /// a given type. If \c T is a Proto expression
    /// type, it returns that expression's associated
    /// domain. If not, it returns
    /// \c proto::default_domain.
    template<typename T, typename Void /* = void*/>
    struct domain_of
    {
        typedef default_domain type;
    };

    /// INTERNAL ONLY
    ///
    template<typename T>
    struct domain_of<T, typename T::proto_is_expr_>
    {
        typedef typename T::proto_domain type;
    };

    /// INTERNAL ONLY
    ///
    template<typename T>
    struct domain_of<T &, void>
    {
        typedef typename domain_of<T>::type type;
    };

    /// INTERNAL ONLY
    ///
    template<typename T>
    struct domain_of<boost::reference_wrapper<T>, void>
    {
        typedef typename domain_of<T>::type type;
    };

    /// INTERNAL ONLY
    ///
    template<typename T>
    struct domain_of<boost::reference_wrapper<T> const, void>
    {
        typedef typename domain_of<T>::type type;
    };

    /// A metafunction that returns \c mpl::true_
    /// if the type \c SubDomain is a sub-domain of
    /// \c SuperDomain; \c mpl::false_ otherwise.
    template<typename SubDomain, typename SuperDomain>
    struct is_sub_domain_of
      : is_sub_domain_of<typename SubDomain::proto_super_domain, SuperDomain>
    {};

    /// INTERNAL ONLY
    ///
    template<typename SuperDomain>
    struct is_sub_domain_of<proto::no_super_domain, SuperDomain>
      : mpl::false_
    {};

    /// INTERNAL ONLY
    ///
    template<typename SuperDomain>
    struct is_sub_domain_of<SuperDomain, SuperDomain>
      : mpl::true_
    {};

}}

#if defined(_MSC_VER)
# pragma warning(pop)
#endif

#endif


code:
///////////////////////////////////////////////////////////////////////////////
/// \file eval.hpp
/// Contains the eval() expression evaluator.
//
//  Copyright 2008 Eric Niebler. 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_PROTO_EVAL_HPP_EAN_03_29_2007
#define BOOST_PROTO_EVAL_HPP_EAN_03_29_2007

#include <boost/proto/proto_fwd.hpp> // BOOST_PROTO_CALLABLE
#include <boost/type_traits/remove_reference.hpp>

namespace boost { namespace proto
{

    namespace result_of
    {
        /// \brief A metafunction for calculating the return type
        /// of \c proto::eval() given a certain \c Expr and \c Context
        /// types.
        ///
        /// \note The types \c Expr and \c Context should not be
        /// reference types. They may be cv-qualified, but the
        /// cv-qualification on the \c Context parameter is ignored.
        template<typename Expr, typename Context>
        struct eval
        {
            typedef typename Context::template eval<Expr>::result_type type;
        };
    }

    namespace functional
    {
        /// \brief A PolymorphicFunctionObject type for
        /// evaluating a given Proto expression with a given
        /// context.
        struct eval
        {
            BOOST_PROTO_CALLABLE()

            template<typename Sig>
            struct result;

            template<typename This, typename Expr, typename Context>
            struct result<This(Expr, Context)>
            {
                typedef
                    typename proto::result_of::eval<
                        typename remove_reference<Expr>::type
                      , typename remove_reference<Context>::type
                    >::type
                type;
            };

            /// \brief Evaluate a given Proto expression with a given
            /// context.
            /// \param expr The Proto expression to evaluate
            /// \param context The context in which the expression should be
            ///     evaluated.
            /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
            template<typename Expr, typename Context>
            typename proto::result_of::eval<Expr, Context>::type
            operator ()(Expr &e, Context &ctx) const
            {
                return typename Context::template eval<Expr>()(e, ctx);
            }

            /// \overload
            ///
            template<typename Expr, typename Context>
            typename proto::result_of::eval<Expr, Context>::type
            operator ()(Expr &e, Context const &ctx) const
            {
                return typename Context::template eval<Expr>()(e, ctx);
            }

            /// \overload
            ///
            template<typename Expr, typename Context>
            typename proto::result_of::eval<Expr const, Context>::type
            operator ()(Expr const &e, Context &ctx) const
            {
                return typename Context::template eval<Expr const>()(e, ctx);
            }

            /// \overload
            ///
            template<typename Expr, typename Context>
            typename proto::result_of::eval<Expr const, Context>::type
            operator ()(Expr const &e, Context const &ctx) const
            {
                return typename Context::template eval<Expr const>()(e, ctx);
            }
        };
    }

    /// \brief Evaluate a given Proto expression with a given
    /// context.
    /// \param expr The Proto expression to evaluate
    /// \param context The context in which the expression should be
    ///     evaluated.
    /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
    template<typename Expr, typename Context>
    typename proto::result_of::eval<Expr, Context>::type
    eval(Expr &e, Context &ctx)
    {
        return typename Context::template eval<Expr>()(e, ctx);
    }

    /// \overload
    ///
    template<typename Expr, typename Context>
    typename proto::result_of::eval<Expr, Context>::type
    eval(Expr &e, Context const &ctx)
    {
        return typename Context::template eval<Expr>()(e, ctx);
    }

    /// \overload
    ///
    template<typename Expr, typename Context>
    typename proto::result_of::eval<Expr const, Context>::type
    eval(Expr const &e, Context &ctx)
    {
        return typename Context::template eval<Expr const>()(e, ctx);
    }

    /// \overload
    ///
    template<typename Expr, typename Context>
    typename proto::result_of::eval<Expr const, Context>::type
    eval(Expr const &e, Context const &ctx)
    {
        return typename Context::template eval<Expr const>()(e, ctx);
    }
}}

#endif