$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r50279 - in branches/release: . boost/proto boost/proto/context boost/proto/transform libs/proto/doc libs/proto/doc/reference libs/proto/doc/reference/transform libs/proto/example libs/proto/test
From: eric_at_[hidden]
Date: 2008-12-15 12:23:58
Author: eric_niebler
Date: 2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
New Revision: 50279
URL: http://svn.boost.org/trac/boost/changeset/50279
Log:
Merged revisions 50265-50266,50270 via svnmerge from 
https://svn.boost.org/svn/boost/trunk
........
  r50265 | eric_niebler | 2008-12-13 20:35:21 -0800 (Sat, 13 Dec 2008) | 1 line
  
  add support for nullary expressions with tag types other than proto::tag::terminal
........
  r50266 | eric_niebler | 2008-12-13 21:53:21 -0800 (Sat, 13 Dec 2008) | 1 line
  
  allow 0- and 1-argument variants of proto::or_ and proto::and_
........
  r50270 | eric_niebler | 2008-12-14 08:40:27 -0800 (Sun, 14 Dec 2008) | 1 line
  
  fix nullary_expr bug
........
Properties modified: 
   branches/release/   (props changed)
Text files modified: 
   branches/release/boost/proto/context/callable.hpp           |     4 +-                                      
   branches/release/boost/proto/context/default.hpp            |     6 +-                                      
   branches/release/boost/proto/context/null.hpp               |     2                                         
   branches/release/boost/proto/debug.hpp                      |     8 ++-                                     
   branches/release/boost/proto/deep_copy.hpp                  |     2                                         
   branches/release/boost/proto/expr.hpp                       |    18 ++++++----                              
   branches/release/boost/proto/extends.hpp                    |    11 +++--                                   
   branches/release/boost/proto/fusion.hpp                     |     4 +-                                      
   branches/release/boost/proto/matches.hpp                    |    65 +++++++++++++++++++++++++++++++-----    
   branches/release/boost/proto/proto_fwd.hpp                  |    29 +++-------------                        
   branches/release/boost/proto/traits.hpp                     |    45 ++++++++++++++++++++++++-               
   branches/release/boost/proto/transform/default.hpp          |    24 ++++++------                            
   branches/release/libs/proto/doc/reference.xml               |     5 ++                                      
   branches/release/libs/proto/doc/reference/generate.xml      |     2                                         
   branches/release/libs/proto/doc/reference/matches.xml       |    14 ++-----                                 
   branches/release/libs/proto/doc/reference/traits.xml        |    70 +++++++++++++++++++++++++++++++++++++-- 
   branches/release/libs/proto/doc/reference/transform/arg.xml |    10 ++--                                    
   branches/release/libs/proto/example/virtual_member.cpp      |    48 ++++++++++++++------------              
   branches/release/libs/proto/test/matches.cpp                |    25 ++++++++++++++                          
   19 files changed, 279 insertions(+), 113 deletions(-)
Modified: branches/release/boost/proto/context/callable.hpp
==============================================================================
--- branches/release/boost/proto/context/callable.hpp	(original)
+++ branches/release/boost/proto/context/callable.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -46,7 +46,7 @@
             template<typename Context, long Arity>
             struct callable_context_wrapper;
 
-            template<typename Expr, typename Context, long Arity = Expr::proto_arity::value>
+            template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
             struct is_expr_handled;
 
             template<typename Expr, typename Context>
@@ -86,7 +86,7 @@
             template<
                 typename Expr
               , typename Context
-              , long Arity          BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity::value)
+              , long Arity          BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity_c)
             >
             struct callable_eval
             {};
Modified: branches/release/boost/proto/context/default.hpp
==============================================================================
--- branches/release/boost/proto/context/default.hpp	(original)
+++ branches/release/boost/proto/context/default.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -42,7 +42,7 @@
                 typename Expr
               , typename Context
               , typename Tag        BOOST_PROTO_WHEN_BUILDING_DOCS(= typename Expr::proto_tag)
-              , long Arity          BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity::value)
+              , long Arity          BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity_c)
             >
             struct default_eval
             {};
@@ -190,8 +190,8 @@
               : memfun_eval<Expr, Context, is_member_function_eval<Expr, Context>::value>
             {};
 
-            template<typename Expr, typename Context>
-            struct default_eval<Expr, Context, proto::tag::terminal, 0>
+            template<typename Expr, typename Context, typename Tag>
+            struct default_eval<Expr, Context, Tag, 0>
             {
                 typedef
                     typename proto::result_of::value<Expr &>::type
Modified: branches/release/boost/proto/context/null.hpp
==============================================================================
--- branches/release/boost/proto/context/null.hpp	(original)
+++ branches/release/boost/proto/context/null.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -26,7 +26,7 @@
         template<
             typename Expr
           , typename Context
-          , long Arity          BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity::value)
+          , long Arity          BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity_c)
         >
         struct null_eval
         {};
Modified: branches/release/boost/proto/debug.hpp
==============================================================================
--- branches/release/boost/proto/debug.hpp	(original)
+++ branches/release/boost/proto/debug.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -65,6 +65,7 @@
         }                                                                       \
         /**/
 
+        BOOST_PROTO_DEFINE_TAG_NAME(terminal)
         BOOST_PROTO_DEFINE_TAG_NAME(unary_plus)
         BOOST_PROTO_DEFINE_TAG_NAME(negate)
         BOOST_PROTO_DEFINE_TAG_NAME(dereference)
@@ -138,11 +139,12 @@
 
             /// \brief Pretty-print the current node in a Proto expression
             /// tree.
-            template<typename Args>
-            void operator()(proto::expr<tag::terminal, Args, 0> const &expr) const
+            template<typename Tag, typename Args>
+            void operator()(proto::expr<Tag, Args, 0> const &expr) const
             {
+                using namespace tag;
                 this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", ")
-                    << "terminal(" << proto::value(expr) << ")\n";
+                    << proto_tag_name(Tag()) << "(" << proto::value(expr) << ")\n";
                 this->first_ = false;
             }
 
Modified: branches/release/boost/proto/deep_copy.hpp
==============================================================================
--- branches/release/boost/proto/deep_copy.hpp	(original)
+++ branches/release/boost/proto/deep_copy.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -25,7 +25,7 @@
     {
         namespace detail
         {
-            template<typename Expr, long Arity = Expr::proto_arity::value>
+            template<typename Expr, long Arity = Expr::proto_arity_c>
             struct deep_copy_impl;
 
             template<typename Expr>
Modified: branches/release/boost/proto/expr.hpp
==============================================================================
--- branches/release/boost/proto/expr.hpp	(original)
+++ branches/release/boost/proto/expr.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -161,18 +161,21 @@
         /// \c Tag is type that represents the operation encoded by
         ///             this expression. It is typically one of the structs
         ///             in the \c boost::proto::tag namespace, but it doesn't
-        ///             have to be. If the \c Tag type is \c boost::proto::tag::terminal
-        ///             then this \c expr\<\> type represents a leaf in the
-        ///             expression tree.
+        ///             have to be.
         ///
         /// \c Args is a type list representing the type of the children
         ///             of this expression. It is an instantiation of one
         ///             of \c proto::list1\<\>, \c proto::list2\<\>, etc. The
         ///             child types must all themselves be either \c expr\<\>
-        ///             or <tt>proto::expr\<\>&</tt>, unless the \c Tag
-        ///             type is \c boost::proto::tag::terminal, in which case
-        ///             \c Args must be \c proto::term\<T\>, where \c T can be any
-        ///             type.
+        ///             or <tt>proto::expr\<\>&</tt>. If \c Args is an
+        ///             instantiation of \c proto::term\<\> then this
+        ///             \c expr\<\> type represents a terminal expression;
+        ///             the parameter to the \c proto::term\<\> template
+        ///             represents the terminal's value type.
+        ///
+        /// \c Arity is an integral constant representing the number of child
+        ///             nodes this node contains. If \c Arity is 0, then this
+        ///             node is a terminal.
         ///
         /// \c proto::expr\<\> is a valid Fusion random-access sequence, where
         /// the elements of the sequence are the child expressions.
@@ -180,6 +183,7 @@
         struct expr<Tag, Args, BOOST_PP_ITERATION() >
         {
             typedef Tag proto_tag;
+            BOOST_STATIC_CONSTANT(long, proto_arity_c = BOOST_PP_ITERATION());
             typedef mpl::long_<BOOST_PP_ITERATION() > proto_arity;
             typedef expr proto_base_expr;
             typedef Args proto_args;
Modified: branches/release/boost/proto/extends.hpp
==============================================================================
--- branches/release/boost/proto/extends.hpp	(original)
+++ branches/release/boost/proto/extends.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -123,12 +123,12 @@
 
     /// INTERNAL ONLY
     ///
-    #define BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, DATA)                                         \
+    #define BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, DATA)                                             \
         BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, 1)
 
     /// INTERNAL ONLY
     ///
-    #define BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, DATA)                                     \
+    #define BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, DATA)                                         \
         BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, 0)
 
     /// INTERNAL ONLY
@@ -157,6 +157,7 @@
         typedef typename proto_base_expr::proto_arity proto_arity;                                  \
         typedef typename proto_base_expr::address_of_hack_type_ proto_address_of_hack_type_;        \
         typedef void proto_is_expr_; /**< INTERNAL ONLY */                                          \
+        BOOST_STATIC_CONSTANT(long, proto_arity_c = proto_base_expr::proto_arity_c);                \
         BOOST_PROTO_FUSION_DEFINE_TAG(boost::proto::tag::proto_expr)                                \
         BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_CHILD, ~)                        \
                                                                                                     \
@@ -439,8 +440,8 @@
     template<
         typename Expr
       , typename Derived
-      , typename Domain     BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain)
-      , typename Tag        BOOST_PROTO_WHEN_BUILDING_DOCS(= typename Expr::proto_tag)
+      , typename Domain     BOOST_PROTO_WHEN_BUILDING_DOCS(= proto::default_domain)
+      , long Arity          BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity_c)
     >
     struct extends
     {
@@ -485,7 +486,7 @@
     /// \brief extends\<\> class template for adding behaviors to a Proto expression template
     ///
     template<typename Expr, typename Derived, typename Domain>
-    struct extends<Expr, Derived, Domain, tag::terminal>
+    struct extends<Expr, Derived, Domain, 0>
     {
         extends()
           : proto_expr_()
Modified: branches/release/boost/proto/fusion.hpp
==============================================================================
--- branches/release/boost/proto/fusion.hpp	(original)
+++ branches/release/boost/proto/fusion.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -511,7 +511,7 @@
         {
             template<typename Sequence>
             struct apply
-              : mpl::long_<0 == Sequence::proto_arity::value ? 1 : Sequence::proto_arity::value>
+              : mpl::long_<0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c>
             {};
         };
 
@@ -545,7 +545,7 @@
                 typedef
                     proto::detail::expr_iterator<
                         Sequence
-                      , 0 == Sequence::proto_arity::value ? 1 : Sequence::proto_arity::value
+                      , 0 == Sequence::proto_arity_c ? 1 : Sequence::proto_arity_c
                     >
                 type;
 
Modified: branches/release/boost/proto/matches.hpp
==============================================================================
--- branches/release/boost/proto/matches.hpp	(original)
+++ branches/release/boost/proto/matches.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -89,6 +89,18 @@
             template<typename And>
             struct last;
 
+            template<>
+            struct last<proto::and_<> >
+            {
+                typedef proto::_ type;
+            };
+
+            template<typename G0>
+            struct last<proto::and_<G0> >
+            {
+                typedef G0 type;
+            };
+
             template<typename T, typename U>
             struct array_matches
               : mpl::false_
@@ -319,12 +331,22 @@
               : vararg_matches< Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
             {};
 
-            template<typename Args1, typename Args2, long N2>
-            struct matches_< proto::expr<tag::terminal, Args1, 0>, proto::expr<proto::_, Args2, N2> >
+            template<typename Tag, typename Args1, typename Args2>
+            struct matches_< proto::expr<Tag, Args1, 0>, proto::expr<Tag, Args2, 0> >
+              : terminal_matches<typename Args1::child0, typename Args2::child0>
+            {};
+
+            template<typename Tag, typename Args1, typename Args2, long N2>
+            struct matches_< proto::expr<Tag, Args1, 0>, proto::expr<proto::_, Args2, N2> >
               : mpl::false_
             {};
 
             template<typename Tag, typename Args1, typename Args2>
+            struct matches_< proto::expr<Tag, Args1, 0>, proto::expr<proto::_, Args2, 0> >
+              : terminal_matches<typename Args1::child0, typename Args2::child0>
+            {};
+
+            template<typename Tag, typename Args1, typename Args2>
             struct matches_< proto::expr<Tag, Args1, 1>, proto::expr<Tag, Args2, 1> >
               : matches_<typename detail::expr_traits<typename Args1::child0>::value_type::proto_base_expr, typename Args2::child0::proto_base_expr>
             {};
@@ -334,11 +356,6 @@
               : matches_<typename detail::expr_traits<typename Args1::child0>::value_type::proto_base_expr, typename Args2::child0::proto_base_expr>
             {};
 
-            template<typename Args1, typename Args2>
-            struct matches_< proto::expr<tag::terminal, Args1, 0>, proto::expr<tag::terminal, Args2, 0> >
-              : terminal_matches<typename Args1::child0, typename Args2::child0>
-            {};
-
         #define BOOST_PROTO_MATCHES_N_FUN(Z, N, DATA)                                               \
             matches_<                                                                               \
                 typename detail::expr_traits<typename Args1::BOOST_PP_CAT(child, N)>::value_type::proto_base_expr\
@@ -388,6 +405,32 @@
               : detail::uncvref<typename when<_, If>::template impl<Expr, int, int>::result_type>::type
             {};
 
+            // handle degenerate cases of proto::or_
+            template<typename Expr>
+            struct matches_<Expr, or_<> >
+              : mpl::false_
+            {
+                typedef not_<_> which;
+            };
+
+            template<typename Expr, typename G0>
+            struct matches_<Expr, or_<G0> >
+              : matches_<Expr, typename G0::proto_base_expr>
+            {
+                typedef G0 which;
+            };
+
+            // handle degenerate cases of proto::and_
+            template<typename Expr>
+            struct matches_<Expr, and_<> >
+              : mpl::true_
+            {};
+
+            template<typename Expr, typename G0>
+            struct matches_<Expr, and_<G0> >
+              : matches_<Expr, typename G0::proto_base_expr>
+            {};
+
             // handle proto::not_
             template<typename Expr, typename Grammar>
             struct matches_<Expr, not_<Grammar> >
@@ -442,9 +485,9 @@
             /// \li An expression \c E matches <tt>switch_\<C\></tt> if
             ///     \c E matches <tt>C::case_\<E::proto_tag\></tt>.
             ///
-            /// A terminal expression <tt>expr\<tag::terminal,term\<A\> \></tt> matches
-            /// a grammar <tt>expr\<BT,term\<B\> \></tt> if \c BT is \c _ or
-            /// \c tag::terminal and one of the following is true:
+            /// A terminal expression <tt>expr\<AT,term\<A\> \></tt> matches
+            /// a grammar <tt>expr\<BT,term\<B\> \></tt> if \c BT is \c AT or
+            /// \c proto::_ and if one of the following is true:
             ///
             /// \li \c B is the wildcard pattern, \c _
             /// \li \c A is \c B
@@ -476,6 +519,8 @@
                 >
             {};
 
+            /// INTERNAL ONLY
+            ///
             template<typename Expr, typename Grammar>
             struct matches<Expr &, Grammar>
               : detail::matches_<
Modified: branches/release/boost/proto/proto_fwd.hpp
==============================================================================
--- branches/release/boost/proto/proto_fwd.hpp	(original)
+++ branches/release/boost/proto/proto_fwd.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -16,7 +16,6 @@
 #include <boost/version.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/arithmetic/sub.hpp>
 #include <boost/preprocessor/punctuation/comma.hpp>
 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
@@ -298,7 +297,7 @@
             typename Expr
           , typename Derived
           , typename Domain = default_domain
-          , typename Tag = typename Expr::proto_tag
+          , long Arity = Expr::proto_arity_c
         >
         struct extends;
 
@@ -317,26 +316,10 @@
 
     namespace control
     {
-        template<
-            typename Grammar0
-          , typename Grammar1
-          , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
-                BOOST_PP_SUB(BOOST_PROTO_MAX_LOGICAL_ARITY,2)
-              , typename G
-              , void
-            )
-        >
+        template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G, void)>
         struct or_;
 
-        template<
-            typename Grammar0
-          , typename Grammar1
-          , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
-                BOOST_PP_SUB(BOOST_PROTO_MAX_LOGICAL_ARITY,2)
-              , typename G
-              , void
-            )
-        >
+        template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G, void)>
         struct and_;
 
         template<typename Grammar>
@@ -374,18 +357,18 @@
     {
         struct null_context;
 
-        template<typename Expr, typename Context, long Arity = Expr::proto_arity::value>
+        template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
         struct null_eval;
 
         struct default_context;
 
-        template<typename Expr, typename Context, typename Tag = typename Expr::proto_tag, long Arity = Expr::proto_arity::value>
+        template<typename Expr, typename Context, typename Tag = typename Expr::proto_tag, long Arity = Expr::proto_arity_c>
         struct default_eval;
 
         template<typename Derived, typename DefaultCtx = default_context>
         struct callable_context;
 
-        template<typename Expr, typename Context, long Arity = Expr::proto_arity::value>
+        template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
         struct callable_eval;
     }
 
Modified: branches/release/boost/proto/traits.hpp
==============================================================================
--- branches/release/boost/proto/traits.hpp	(original)
+++ branches/release/boost/proto/traits.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -589,6 +589,49 @@
                 typedef V proto_child2;
             };
 
+            /// \brief A metafunction for generating nullary expression types with a
+            /// specified tag type,
+            /// a grammar element for matching nullary expressions, and a
+            /// PrimitiveTransform that returns the current expression unchanged.
+            ///
+            /// Use <tt>nullary_expr\<_, _\></tt> as a grammar element to match any
+            /// nullary expression.
+            template<typename Tag, typename T>
+            struct nullary_expr : transform<nullary_expr<Tag, T>, empty_base>
+            {
+                typedef proto::expr<Tag, term<T> > type;
+                typedef type proto_base_expr;
+
+                template<typename Expr, typename State, typename Data>
+                struct impl : transform_impl<Expr, State, Data>
+                {
+                    typedef Expr result_type;
+
+                    /// \param e The current expression
+                    /// \pre <tt>matches\<Expr, nullary_expr\<Tag, T\> \>::::value</tt> is \c true.
+                    /// \return \c e
+                    /// \throw nothrow
+                    #ifdef BOOST_HAS_DECLTYPE
+                    result_type
+                    #else
+                    typename impl::expr_param
+                    #endif
+                    operator ()(
+                        typename impl::expr_param e
+                      , typename impl::state_param
+                      , typename impl::data_param
+                    ) const
+                    {
+                        return e;
+                    }
+                };
+
+                /// INTERNAL ONLY
+                typedef Tag proto_tag;
+                /// INTERNAL ONLY
+                typedef T proto_child0;
+            };
+
             /// \brief A metafunction for generating unary expression types with a
             /// specified tag type,
             /// a grammar element for matching unary expressions, and a
@@ -1814,7 +1857,6 @@
                 /// \param expr The terminal expression node.
                 /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
                 /// \pre <tt>0 == Expr::proto_arity::value</tt>
-                /// \pre <tt>Expr::proto_tag</tt> is <tt>tag::terminal</tt>
                 /// \return <tt>proto::value(expr)</tt>
                 /// \throw nothrow
                 template<typename Expr>
@@ -2099,7 +2141,6 @@
         /// reference.
         ///
         /// \param expr The Proto terminal expression.
-        /// \pre \c Expr::proto_tag is \c tag::terminal.
         /// \pre <tt>N::value == 0</tt>
         /// \throw nothrow
         /// \return A reference to the terminal's value
Modified: branches/release/boost/proto/transform/default.hpp
==============================================================================
--- branches/release/boost/proto/transform/default.hpp	(original)
+++ branches/release/boost/proto/transform/default.hpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -38,8 +38,8 @@
             template<typename Expr, typename State, typename Data, typename Tag, long Arity>
             struct impl2;
 
-            template<typename Expr, typename State, typename Data>
-            struct impl2<Expr, State, Data, tag::terminal, 0>
+            template<typename Expr, typename State, typename Data, typename Tag>
+            struct impl2<Expr, State, Data, Tag, 0>
               : _value::impl<Expr, State, Data>
             {};
 
@@ -54,13 +54,13 @@
             public:                                                                                 \
                 BOOST_PROTO_DECLTYPE_(OP proto::detail::MAKE<r0>(), result_type)                    \
                 result_type operator ()(                                                            \
-                    typename impl2::expr_param e                                                 \
-                  , typename impl2::state_param s                                               \
-                  , typename impl2::data_param d                                                 \
+                    typename impl2::expr_param e                                                    \
+                  , typename impl2::state_param s                                                   \
+                  , typename impl2::data_param d                                                    \
                 ) const                                                                             \
                 {                                                                                   \
                     typename Grammar::template impl<e0, State, Data> t0;                            \
-                    return OP t0(proto::child_c<0>(e), s, d);                             \
+                    return OP t0(proto::child_c<0>(e), s, d);                                       \
                 }                                                                                   \
             };                                                                                      \
             /**/
@@ -81,15 +81,15 @@
                   , result_type                                                                     \
                 )                                                                                   \
                 result_type operator ()(                                                            \
-                    typename impl2::expr_param e                                                 \
-                  , typename impl2::state_param s                                               \
-                  , typename impl2::data_param d                                                 \
+                    typename impl2::expr_param e                                                    \
+                  , typename impl2::state_param s                                                   \
+                  , typename impl2::data_param d                                                    \
                 ) const                                                                             \
                 {                                                                                   \
                     typename Grammar::template impl<e0, State, Data> t0;                            \
                     typename Grammar::template impl<e1, State, Data> t1;                            \
-                    return t0(proto::child_c<0>(e), s, d)                                 \
-                        OP t1(proto::child_c<1>(e), s, d);                                \
+                    return t0(proto::child_c<0>(e), s, d)                                           \
+                        OP t1(proto::child_c<1>(e), s, d);                                          \
                 }                                                                                   \
             };                                                                                      \
             /**/
@@ -450,7 +450,7 @@
                   , State
                   , Data
                   , typename transform_impl<Expr, State, Data>::expr::proto_tag
-                  , transform_impl<Expr, State, Data>::expr::proto_arity::value
+                  , transform_impl<Expr, State, Data>::expr::proto_arity_c
                 >
             {};
         };
Modified: branches/release/libs/proto/doc/reference.xml
==============================================================================
--- branches/release/libs/proto/doc/reference.xml	(original)
+++ branches/release/libs/proto/doc/reference.xml	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -797,6 +797,11 @@
       </listitem>
       <listitem>
         <computeroutput>
+          <classname alt="boost::proto::nullary_expr">proto::nullary_expr</classname>
+        </computeroutput>
+      </listitem>
+      <listitem>
+        <computeroutput>
           <classname alt="boost::proto::tag::plus">proto::tag::plus</classname>
         </computeroutput>
       </listitem>
Modified: branches/release/libs/proto/doc/reference/generate.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/generate.xml	(original)
+++ branches/release/libs/proto/doc/reference/generate.xml	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -33,7 +33,7 @@
         </struct-specialization>
         <method-group name="public member functions">
           <method name="operator()" cv="const">
-            <type>Expr const &</type>
+            <type>Expr</type>
             <template>
               <template-type-parameter name="Expr"/>
             </template>
Modified: branches/release/libs/proto/doc/reference/matches.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/matches.xml	(original)
+++ branches/release/libs/proto/doc/reference/matches.xml	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -61,7 +61,7 @@
           </typedef>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
-              <type>typename impl::expr_param</type>
+              <type>Expr</type>
               <parameter name="expr">
                 <paramtype>typename impl::expr_param</paramtype>
                 <description>
@@ -117,7 +117,7 @@
           </typedef>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
-              <type>typename impl::expr_param</type>
+              <type>Expr</type>
               <parameter name="expr">
                 <paramtype>typename impl::expr_param</paramtype>
                 <description>
@@ -700,18 +700,14 @@
           <para>
             A terminal expression
             <computeroutput>
-              <classname>proto::expr</classname><<classname>proto::tag::terminal</classname>,
+              <classname>proto::expr</classname><AT,
               <classname>proto::term</classname><A> >
             </computeroutput> matches a grammar
             <computeroutput>
               <classname>proto::expr</classname><BT, <classname>proto::term</classname><B> >
             </computeroutput>
-            if <computeroutput>BT</computeroutput> is <computeroutput>
-              <classname>proto::_</classname>
-            </computeroutput> or
-            <computeroutput>
-              <classname>proto::tag::terminal</classname>
-            </computeroutput> and one of the following is true:
+            if <computeroutput>BT</computeroutput> is <computeroutput><classname>proto::_</classname></computeroutput>
+            or <computeroutput>AT</computeroutput> and one of the following is true:
             <itemizedlist>
               <listitem>
                 <para>
Modified: branches/release/libs/proto/doc/reference/traits.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/traits.xml	(original)
+++ branches/release/libs/proto/doc/reference/traits.xml	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -387,10 +387,6 @@
                 <para>
                   <computeroutput>0 == Expr::proto_arity::value</computeroutput>
                 </para>
-                <para>
-                  <computeroutput>Expr::proto_tag</computeroutput> is
-                  <computeroutput><classname>proto::tag::terminal</classname></computeroutput>
-                </para>
               </requires>
               <returns>
                 <para>
@@ -567,7 +563,7 @@
           </typedef>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
-              <type>typename impl::expr_param</type>
+              <type>Expr</type>
               <parameter name="expr">
                 <paramtype>typename impl::expr_param</paramtype>
                 <description>
@@ -1867,6 +1863,70 @@
         </typedef>
       </struct>
       
+      <struct name="nullary_expr">
+        <template>
+          <template-type-parameter name="Tag"/>
+          <template-type-parameter name="T"/>
+        </template>
+        <inherit><classname>proto::transform</classname>< nullary_expr<Tag, T> ></inherit>
+        <purpose>A metafunction for generating nullary expression types, a grammar element for matching
+          nullary expressions, and
+          a <conceptname>PrimitiveTransform</conceptname> that returns the current expression unchanged. </purpose>
+        <description>
+          <para>
+            Use <computeroutput>proto::nullary_expr<<classname>proto::_</classname>, <classname>proto::_</classname>></computeroutput>
+            as a grammar element to match any nullary expression.
+          </para>
+        </description>
+        <struct name="impl">
+          <template>
+            <template-type-parameter name="Expr"/>
+            <template-type-parameter name="State"/>
+            <template-type-parameter name="Data"/>
+          </template>
+          <inherit><classname>proto::transform_impl</classname>< Expr, State, Data ></inherit>
+          <typedef name="result_type">
+            <type>Expr</type>
+          </typedef>
+          <method-group name="public member functions">
+            <method name="operator()" cv="const">
+              <type>Expr</type>
+              <parameter name="expr">
+                <paramtype>typename impl::expr_param</paramtype>
+                <description>
+                  <para>The current expression </para>
+                </description>
+              </parameter>
+              <parameter name="">
+                <paramtype>typename impl::state_param</paramtype>
+              </parameter>
+              <parameter name="">
+                <paramtype>typename impl::data_param</paramtype>
+              </parameter>
+              <requires>
+                <para>
+                  <computeroutput><classname>proto::matches</classname><Expr, proto::nullary_expr<Tag, T> >::value</computeroutput> is <computeroutput>true</computeroutput>.
+                </para>
+              </requires>
+              <returns>
+                <para>
+                  <computeroutput>expr</computeroutput>
+                </para>
+              </returns>
+              <throws>
+                <simpara>Will not throw.</simpara>
+              </throws>
+            </method>
+          </method-group>
+        </struct>
+        <typedef name="type">
+          <type><classname>proto::expr</classname>< Tag, <classname>proto::term</classname>< T > ></type>
+        </typedef>
+        <typedef name="proto_base_expr">
+          <type>type</type>
+        </typedef>
+      </struct>
+
       <struct name="unary_expr">
         <template>
           <template-type-parameter name="Tag"/>
Modified: branches/release/libs/proto/doc/reference/transform/arg.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/transform/arg.xml	(original)
+++ branches/release/libs/proto/doc/reference/transform/arg.xml	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -26,7 +26,7 @@
           </typedef>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
-              <type>typename impl::expr_param</type>
+              <type>Expr</type>
               <parameter name="expr">
                 <paramtype>typename impl::expr_param</paramtype>
                 <description>
@@ -80,7 +80,7 @@
           </typedef>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
-              <type>typename impl::state_param</type>
+              <type>State</type>
               <parameter name="">
                 <paramtype>typename impl::expr_param</paramtype>
               </parameter>
@@ -135,7 +135,7 @@
           </typedef>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
-              <type>typename impl::data_param</type>
+              <type>Data</type>
               <parameter name="">
                 <paramtype>typename impl::expr_param</paramtype>
               </parameter>
@@ -194,7 +194,7 @@
           </typedef>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
-              <type>typename <classname>proto::result_of::child_c</classname>< typename impl::expr_param, N >::type</type>
+              <type>typename <classname>proto::result_of::child_c</classname>< Expr, N >::type</type>
               <parameter name="expr">
                 <paramtype>typename impl::expr_param</paramtype>
                 <description>
@@ -253,7 +253,7 @@
           </typedef>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
-              <type>typename <classname>proto::result_of::value</classname>< typename impl::expr_param >::type</type>
+              <type>typename <classname>proto::result_of::value</classname>< Expr >::type</type>
               <parameter name="expr">
                 <paramtype>typename impl::expr_param</paramtype>
                 <description>
Modified: branches/release/libs/proto/example/virtual_member.cpp
==============================================================================
--- branches/release/libs/proto/example/virtual_member.cpp	(original)
+++ branches/release/libs/proto/example/virtual_member.cpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -174,9 +174,12 @@
                 proto::terminal<_>
               , mpl::int_<0>()
             >
-          , proto::when<
-                proto::nary_expr<_, proto::vararg<_> >
-              , proto::fold<_, mpl::int_<0>(), mpl::max<arity_of, proto::_state>()>
+          , proto::otherwise<
+                proto::fold<
+                    _
+                  , mpl::int_<0>()
+                  , mpl::max<arity_of, proto::_state>()
+                >
             >
         >
     {};
@@ -226,25 +229,26 @@
             return grammar()(proto_base(), 0, args);            
         }
 
-        #define LAMBDA_EVAL(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \
-        template<typename_A(N)>                                               \
-        typename boost::result_of<grammar(                                    \
-            E const &                                                         \
-          , int const &                                                       \
-          , fusion::vector<A_const_ref(N)> &                                  \
-        )>::type                                                              \
-        operator ()(A_const_ref_a(N)) const                                   \
-        {                                                                     \
-            BOOST_MPL_ASSERT_RELATION(arity, <=, N);                          \
-            fusion::vector<A_const_ref(N)> args(ref_a(N));                    \
-            return grammar()(proto_base(), 0, args);                          \
-        }                                                                     \
-        /**/
-
-        // Repeats LAMBDA_EVAL macro for N=1 to 3 inclusive (because
-        // there are only 3 placeholders)
-        BOOST_PROTO_REPEAT_FROM_TO(1, 4, LAMBDA_EVAL)
-        #undef LAMBDA_EVAL
+        #define BOOST_PROTO_LOCAL_MACRO(                    \
+            N, typename_A, A_const_ref, A_const_ref_a, a    \
+        )                                                   \
+        template<typename_A(N)>                             \
+        typename boost::result_of<grammar(                  \
+            E const &                                       \
+          , int const &                                     \
+          , fusion::vector<A_const_ref(N)> &                \
+        )>::type                                            \
+        operator ()(A_const_ref_a(N)) const                 \
+        {                                                   \
+            BOOST_MPL_ASSERT_RELATION(arity, <=, N);        \
+            fusion::vector<A_const_ref(N)> args(a(N));      \
+            return grammar()(proto_base(), 0, args);        \
+        }
+        // Repeats BOOST_PROTO_LOCAL_MACRO macro for N=1 to 3
+        // inclusive (because there are only 3 placeholders)
+        #define BOOST_PROTO_LOCAL_a       BOOST_PROTO_a
+        #define BOOST_PROTO_LOCAL_LIMITS  (1, 3)
+        #include BOOST_PROTO_LOCAL_ITERATE()
     };
 
     namespace placeholders
Modified: branches/release/libs/proto/test/matches.cpp
==============================================================================
--- branches/release/libs/proto/test/matches.cpp	(original)
+++ branches/release/libs/proto/test/matches.cpp	2008-12-15 12:23:56 EST (Mon, 15 Dec 2008)
@@ -106,6 +106,8 @@
     >
 {};
 
+struct my_terminal
+{};
 
 void test_matches()
 {
@@ -247,6 +249,29 @@
 
     number<int, two_complement_c> num;
     assert_matches<NumberGrammar>(proto::as_expr(num));
+
+    // check custom terminal types
+    {
+        proto::nullary_expr<my_terminal, int>::type i = {0};
+
+        assert_matches<proto::nullary_expr<my_terminal, _> >( i );
+        assert_not_matches<proto::terminal<_> >( i );
+
+        proto::terminal<int>::type j = {0};
+        assert_matches<proto::terminal<_> >( j );
+        assert_not_matches<proto::nullary_expr<my_terminal, _> >( j );
+
+        assert_matches<proto::nullary_expr<_, _> >( i );
+    }
+
+    // check 0 and 1 arg forms or or_ and and_
+    {
+        assert_matches< proto::and_<> >( lit(1) );
+        assert_not_matches< proto::or_<> >( lit(1) );
+
+        assert_matches< proto::and_<proto::terminal<int> > >( lit(1) );
+        assert_matches< proto::or_<proto::terminal<int> > >( lit(1) );
+    }
 }
 
 using namespace unit_test;