$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r49812 - in trunk: boost/proto libs/proto/test
From: eric_at_[hidden]
Date: 2008-11-16 18:22:53
Author: eric_niebler
Date: 2008-11-16 18:22:53 EST (Sun, 16 Nov 2008)
New Revision: 49812
URL: http://svn.boost.org/trac/boost/changeset/49812
Log:
fix #2407
Added:
   trunk/libs/proto/test/bug2407.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/proto/generate.hpp   |    16 --------                                
   trunk/boost/proto/operators.hpp  |    74 +++++++++++++++++++++++++++++++-------- 
   trunk/libs/proto/test/Jamfile.v2 |     1                                         
   3 files changed, 59 insertions(+), 32 deletions(-)
Modified: trunk/boost/proto/generate.hpp
==============================================================================
--- trunk/boost/proto/generate.hpp	(original)
+++ trunk/boost/proto/generate.hpp	2008-11-16 18:22:53 EST (Sun, 16 Nov 2008)
@@ -18,7 +18,6 @@
     #include <boost/utility/enable_if.hpp>
     #include <boost/proto/proto_fwd.hpp>
     #include <boost/proto/args.hpp>
-    #include <boost/proto/matches.hpp>
     #include <boost/proto/detail/suffix.hpp>
 
     namespace boost { namespace proto
@@ -26,21 +25,6 @@
 
         namespace detail
         {
-            template<typename Domain, typename Expr>
-            struct generate_if
-              : lazy_enable_if<
-                    matches<Expr, typename Domain::proto_grammar>
-                  , typename Domain::template result<void(Expr)>
-                >
-            {};
-
-            // Optimization, generate fewer templates...
-            template<typename Expr>
-            struct generate_if<proto::default_domain, Expr>
-            {
-                typedef Expr type;
-            };
-
             template<typename Expr>
             struct expr_params;
 
Modified: trunk/boost/proto/operators.hpp
==============================================================================
--- trunk/boost/proto/operators.hpp	(original)
+++ trunk/boost/proto/operators.hpp	2008-11-16 18:22:53 EST (Sun, 16 Nov 2008)
@@ -19,6 +19,7 @@
 #include <boost/proto/proto_fwd.hpp>
 #include <boost/proto/tags.hpp>
 #include <boost/proto/expr.hpp>
+#include <boost/proto/matches.hpp>
 #include <boost/proto/generate.hpp>
 #include <boost/proto/make_expr.hpp>
 #include <boost/proto/detail/suffix.hpp>
@@ -27,21 +28,66 @@
 {
     namespace detail
     {
+        template<typename Domain, typename Expr>
+        struct generate_if
+          : lazy_enable_if_c<
+                matches<Expr, typename Domain::proto_grammar>::value
+              , typename Domain::template result<void(Expr)>
+            >
+        {};
+
+        // Optimization, generate fewer templates...
+        template<typename Expr>
+        struct generate_if<proto::default_domain, Expr>
+        {
+            typedef Expr type;
+        };
+
+        template<typename Domain, typename Tag, typename Left, typename Right>
+        struct generate_if_left
+          : lazy_enable_if_c<
+                matches<proto::expr<Tag, proto::list2<Left &, Right> >, typename Domain::proto_grammar>::value
+              , typename Domain::template result<void(
+                    proto::expr<Tag, proto::list2<Left &, typename Domain::template result<void(Right)>::type> >
+                )>
+            >
+        {};
+
+        // Optimization, generate fewer templates...
+        template<typename Tag, typename Left, typename Right>
+        struct generate_if_left<proto::default_domain, Tag, Left, Right>
+        {
+            typedef proto::expr<Tag, proto::list2<Left &, Right> > type;
+        };
+
+        template<typename Domain, typename Tag, typename Left, typename Right>
+        struct generate_if_right
+          : lazy_enable_if_c<
+                matches<proto::expr<Tag, proto::list2<Left, Right &> >, typename Domain::proto_grammar>::value
+              , typename Domain::template result<void(
+                    proto::expr<Tag, proto::list2<typename Domain::template result<void(Left)>::type, Right &> >
+                )>
+            >
+        {};
+
+        // Optimization, generate fewer templates...
+        template<typename Tag, typename Left, typename Right>
+        struct generate_if_right<proto::default_domain, Tag, Left, Right>
+        {
+            typedef proto::expr<Tag, proto::list2<Left, Right &> > type;
+        };
+
         template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void>
         struct as_expr_if2
         {};
 
         template<typename Tag, typename Left, typename Right>
         struct as_expr_if2<Tag, Left, Right, typename Left::proto_is_expr_, void>
-          : generate_if<
+          : generate_if_left<
                 typename Left::proto_domain
-              , proto::expr<
-                    Tag
-                  , list2<
-                        Left &
-                      , typename Left::proto_domain::template result<void(proto::expr<tag::terminal, term<Right &> >)>::type
-                    >
-                >
+              , Tag
+              , Left
+              , proto::expr<tag::terminal, term<Right &> >
             >
         {
             typedef proto::expr<tag::terminal, term<Right &> > term_type;
@@ -58,15 +104,11 @@
 
         template<typename Tag, typename Left, typename Right>
         struct as_expr_if2<Tag, Left, Right, void, typename Right::proto_is_expr_>
-          : generate_if<
+          : generate_if_right<
                 typename Right::proto_domain
-              , proto::expr<
-                    Tag
-                  , list2<
-                        typename Right::proto_domain::template result<void(proto::expr<tag::terminal, term<Left &> >)>::type
-                      , Right &
-                    >
-                >
+              , Tag
+              , proto::expr<tag::terminal, term<Left &> >
+              , Right
             >
         {
             typedef proto::expr<tag::terminal, term<Left &> > term_type;
Modified: trunk/libs/proto/test/Jamfile.v2
==============================================================================
--- trunk/libs/proto/test/Jamfile.v2	(original)
+++ trunk/libs/proto/test/Jamfile.v2	2008-11-16 18:22:53 EST (Sun, 16 Nov 2008)
@@ -29,5 +29,6 @@
         [ run proto_fusion_s.cpp ]
         [ run toy_spirit.cpp ]
         [ run toy_spirit2.cpp ]
+        [ compile bug2407.cpp ]
     ;
 
Added: trunk/libs/proto/test/bug2407.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/proto/test/bug2407.cpp	2008-11-16 18:22:53 EST (Sun, 16 Nov 2008)
@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////////
+// bug2407.hpp
+//
+//  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)
+
+#include <iostream>
+#include <boost/proto/proto.hpp>
+
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using proto::_;
+
+template<class E>
+struct e;
+
+struct g
+  : proto::or_<
+        proto::terminal<int>
+      , proto::plus<g,g>
+    >
+{};
+
+struct d
+  : proto::domain<proto::generator<e>, g>
+{};
+
+template<class E>
+struct e
+  : proto::extends<E, e<E>, d>
+{
+    BOOST_MPL_ASSERT((proto::matches<E, g>));
+
+    e(E const &x = E())
+      : proto::extends<E, e<E>, d>(x)
+    {}
+};
+
+e<proto::terminal<int>::type> i;
+
+template<class E>
+std::ostream &operator<<(std::ostream &sout, e<E> const &x)
+{
+    return sout;
+}
+
+int main()
+{
+    std::cout << (i+i);
+}