$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: eric_at_[hidden]
Date: 2007-12-17 16:20:25
Author: eric_niebler
Date: 2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
New Revision: 42133
URL: http://svn.boost.org/trac/boost/changeset/42133
Log:
port deep_copy to c++03
Added:
   branches/proto/v3/boost/xpressive/proto/detail/cat_args.hpp   (contents, props changed)
   branches/proto/v3/boost/xpressive/proto/detail/deep_copy.hpp   (contents, props changed)
   branches/proto/v3/libs/xpressive/proto/test/deep_copy.cpp   (contents, props changed)
Text files modified: 
   branches/proto/v3/boost/xpressive/proto/deep_copy.hpp         |    68 ++++----------------------------        
   branches/proto/v3/boost/xpressive/proto/detail/apply_args.hpp |    12 ----                                    
   branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp         |     3 +                                       
   branches/proto/v3/boost/xpressive/proto/traits.hpp            |    82 ++++++++++++++++++++++++++++++++++++++++
   branches/proto/v3/libs/xpressive/proto/test/Jamfile.v2        |     1                                         
   5 files changed, 97 insertions(+), 69 deletions(-)
Modified: branches/proto/v3/boost/xpressive/proto/deep_copy.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/deep_copy.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/deep_copy.hpp	2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
@@ -14,77 +14,27 @@
 #include <boost/xpressive/proto/expr.hpp>
 #include <boost/xpressive/proto/traits.hpp>
 #include <boost/xpressive/proto/generate.hpp>
+#include <boost/xpressive/proto/detail/deep_copy.hpp>
 #include <boost/xpressive/proto/detail/define.hpp>
 
 namespace boost { namespace proto
 {
-    namespace detail
-    {
-        template<typename Expr, typename Args = typename Expr::proto_args>
-        struct deep_copy_impl;
-
-        struct deep_copy_cons
-        {
-            template<typename Sig>
-            struct result;
-
-            template<typename This, typename... Args>
-            struct result<This(Args...)>
-            {
-                typedef argsns_::cons<typename deep_copy_impl<UNCVREF(Args)>::type...> type;
-            };
-
-            template<typename... Args>
-            typename result<deep_copy_cons(Args...)>::type
-            operator()(Args const &... args) const
-            {
-                return result<deep_copy_cons(Args...)>::type::make(
-                    deep_copy_impl<Args>::call(args)...
-                );
-            }
-        };
-
-        template<typename Expr, typename T>
-        struct deep_copy_impl<Expr, term<T> >
-        {
-            // TODO don't unref reference to function!
-            typedef typename terminal<UNCVREF(T)>::type expr_type;
-            typedef typename Expr::proto_domain::template apply<expr_type>::type type;
 
-            static type call(Expr const &expr)
-            {
-                return Expr::proto_domain::make(expr_type::make(proto::arg(expr)));
-            }
-        };
-
-        template<typename Expr, typename... Args>
-        struct deep_copy_impl<Expr, args<Args...> >
+    namespace result_of
+    {
+        template<typename Expr>
+        struct deep_copy
         {
-            typedef expr<typename Expr::proto_tag, args<
-                typename deep_copy_impl<UNCVREF(Args)>::type...
-            > > expr_type;
+            typedef typename proto::detail::deep_copy_<typename Expr::proto_args>::type args_type;
+            typedef expr<typename Expr::proto_tag, args_type> expr_type;
             typedef typename Expr::proto_domain::template apply<expr_type>::type type;
 
             static type call(Expr const &expr)
             {
-                expr_type that = {
-                    argsns_::fanout_args(
-                        proto::detail::deep_copy_cons()
-                      , expr.proto_base().proto_args_
-                    )
-                };
+                expr_type that = {proto::detail::deep_copy_<typename Expr::proto_args>::call(expr.proto_base().proto_args_)};
                 return Expr::proto_domain::make(that);
             }
         };
-
-    }
-
-    namespace result_of
-    {
-        template<typename Expr>
-        struct deep_copy
-          : proto::detail::deep_copy_impl<Expr>
-        {};
     }
 
     namespace functional
@@ -112,6 +62,6 @@
 
 }}
 
-#include <boost/xpressive/proto/detail/define.hpp>
+#include <boost/xpressive/proto/detail/undef.hpp>
 
 #endif // BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006
Modified: branches/proto/v3/boost/xpressive/proto/detail/apply_args.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/detail/apply_args.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/detail/apply_args.hpp	2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
@@ -11,6 +11,7 @@
     #define BOOST_PROTO_DETAIL_APPLY_ARGS_HPP_EAN_11_07_2007
 
     #include <boost/xpressive/proto/proto_fwd.hpp>
+    #include <boost/xpressive/proto/detail/cat_args.hpp>
     #include <boost/xpressive/proto/detail/define.hpp>
 
     namespace boost { namespace proto { namespace op
@@ -22,15 +23,6 @@
             struct apply_args;
 
         #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
-            template<typename A0, typename A1>
-            struct cat_args;
-
-            template<typename... A0, typename... A1>
-            struct cat_args<args<A0...>, args<A1...> >
-            {
-                typedef args<A0..., A1...> type;
-            };
-
             template<typename... G>
             struct pad_args
             {
@@ -56,7 +48,7 @@
             >
             {
                 #define TMP(Z, N, DATA) typename boost::result_of<G##N(E##N, S, V)>::type
-                typedef typename cat_args<
+                typedef typename proto::detail::cat_args<
                     args<BOOST_PP_ENUM(BOOST_PROTO_MAX_ARITY, TMP, ~) >
                   , typename apply_args<args<ERest...>, S, V, typename pad_args<GRest...>::type>::type
                 >::type type;
Added: branches/proto/v3/boost/xpressive/proto/detail/cat_args.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/detail/cat_args.hpp	2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
@@ -0,0 +1,32 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file cat_args.hpp
+/// Definintion of cat_args, for concatenating arg lists
+//
+//  Copyright 2007 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_CAT_ARGS_HPP_EAN_11_07_2007
+#define BOOST_PROTO_DETAIL_CAT_ARGS_HPP_EAN_11_07_2007
+
+#include <boost/xpressive/proto/proto_fwd.hpp>
+
+namespace boost { namespace proto
+{
+    namespace detail
+    {
+
+    #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+        template<typename A0, typename A1>
+        struct cat_args;
+
+        template<typename... A0, typename... A1>
+        struct cat_args<args<A0...>, args<A1...> >
+        {
+            typedef args<A0..., A1...> type;
+        };
+    #endif
+    }
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto/detail/deep_copy.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto/detail/deep_copy.hpp	2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
@@ -0,0 +1,105 @@
+#ifndef BOOST_PP_IS_ITERATING
+    ///////////////////////////////////////////////////////////////////////////////
+    /// \file deep_copy.hpp
+    /// Definintion of the deep_copy_ helper
+    //
+    //  Copyright 2007 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_DEEP_COPY_HPP_EAN_11_07_2007
+    #define BOOST_PROTO_DETAIL_DEEP_COPY_HPP_EAN_11_07_2007
+
+    #include <boost/xpressive/proto/proto_fwd.hpp>
+    #include <boost/xpressive/proto/detail/cat_args.hpp>
+    #include <boost/xpressive/proto/detail/define.hpp>
+
+    namespace boost { namespace proto
+    {
+        namespace detail
+        {
+
+            template<typename Args>
+            struct deep_copy_;
+
+            template<typename A>
+            struct deep_copy_<term<A> >
+            {
+                typedef term<UNCVREF(A)> type;
+
+                template<typename Cons>
+                static typename type::cons_type call(Cons const &a)
+                {
+                    typename type::cons_type that = {a.car};
+                    return that;
+                }
+            };
+
+        #if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+            template<
+                BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
+              , typename... Rest
+            >
+            struct deep_copy_<args<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_ARITY, A), Rest...> >
+            {
+                #define TMP(Z, N, DATA) typename result_of::deep_copy<UNCVREF(A##N)>::type
+                typedef typename cat_args<
+                    args<BOOST_PP_ENUM(BOOST_PROTO_MAX_ARITY, TMP, ~) >
+                  , typename deep_copy_<args<Rest...> >::type
+                >::type type;
+                #undef TMP
+
+                template<typename Cons>
+                static typename type::cons_type call(Cons const &a)
+                {
+                    #define TMP0(Z, N, DATA) .cdr
+                    #define TMP1(Z, N, DATA) {result_of::deep_copy<UNCVREF(A##N)>::call(a BOOST_PP_REPEAT_ ## Z(N, TMP0, ~) .car)
+                    #define TMP2(Z, N, DATA) }
+                    typename type::cons_type that =
+                        BOOST_PP_ENUM(BOOST_PROTO_MAX_ARITY, TMP1, ~)
+                      , deep_copy_<args<Rest...> >::call(a BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, TMP0, ~))
+                        BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, TMP2, ~);
+                    return that;
+                    #undef TMP0
+                    #undef TMP1
+                    #undef TMP2
+                }
+            };
+
+        #endif
+
+        #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/detail/deep_copy.hpp>))
+        #include BOOST_PP_ITERATE()
+
+        }
+    }}
+
+    #include <boost/xpressive/proto/detail/undef.hpp>
+    #endif
+
+#else
+
+            template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename A)>
+            struct deep_copy_<args<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)> >
+            {
+                #define TMP(Z, N, DATA) typename result_of::deep_copy<UNCVREF(A##N)>::type
+                typedef args<BOOST_PP_ENUM(BOOST_PP_ITERATION(), TMP, ~) > type;
+                #undef TMP
+
+                template<typename Cons>
+                static typename type::cons_type call(Cons const &a)
+                {
+                    #define TMP0(Z, N, DATA) .cdr
+                    #define TMP1(Z, N, DATA) {result_of::deep_copy<UNCVREF(A##N)>::call(a BOOST_PP_REPEAT_ ## Z(N, TMP0, ~) .car)
+                    #define TMP2(Z, N, DATA) }
+                    typename type::cons_type that =
+                        BOOST_PP_ENUM(BOOST_PP_ITERATION(), TMP1, ~)
+                        BOOST_PP_REPEAT(BOOST_PP_ITERATION(), TMP2, ~);
+                    return that;
+                    #undef TMP0
+                    #undef TMP1
+                    #undef TMP2
+                }
+            };
+
+#endif
Modified: branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/proto_fwd.hpp	2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
@@ -249,6 +249,9 @@
         >
         struct make_expr;
         #endif
+
+        template<typename Expr>
+        struct deep_copy;
     }
 
     using result_of::matches;
Modified: branches/proto/v3/boost/xpressive/proto/traits.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto/traits.hpp	(original)
+++ branches/proto/v3/boost/xpressive/proto/traits.hpp	2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
@@ -392,12 +392,28 @@
               : result_of::as_arg<T, Domain>
             {};
 
+        #ifdef BOOST_HAS_RVALUE_REFS
             template<typename T>
             typename result_of::as_arg<T, Domain>::type
             operator ()(T &&t) const
             {
                 return result_of::as_arg<T, Domain>::call(t);
             }
+        #else
+            template<typename T>
+            typename result_of::as_arg<T &, Domain>::type
+            operator ()(T &t) const
+            {
+                return result_of::as_arg<T &, Domain>::call(t);
+            }
+
+            template<typename T>
+            typename result_of::as_arg<T const &, Domain>::type
+            operator ()(T const &t) const
+            {
+                return result_of::as_arg<T const &, Domain>::call(t);
+            }
+        #endif
         };
 
         template<typename Domain>
@@ -411,12 +427,28 @@
               : result_of::as_expr<T, Domain>
             {};
 
+        #ifdef BOOST_HAS_RVALUE_REFS
             template<typename T>
             typename result_of::as_expr<T, Domain>::type
             operator ()(T &&t) const
             {
                 return result_of::as_expr<T, Domain>::call(t);
             }
+        #else
+            template<typename T>
+            typename result_of::as_expr<T &, Domain>::type
+            operator ()(T &t) const
+            {
+                return result_of::as_expr<T &, Domain>::call(t);
+            }
+
+            template<typename T>
+            typename result_of::as_expr<T const &, Domain>::type
+            operator ()(T const &t) const
+            {
+                return result_of::as_expr<T const &, Domain>::call(t);
+            }
+        #endif
         };
 
         template<long N>
@@ -508,6 +540,7 @@
         return result_of::arg_c<Expr const, N>::call(expr.proto_base().proto_args_);
     }
 
+#ifdef BOOST_HAS_RVALUE_REFS
     template<typename T>
     typename result_of::as_expr<T>::type as_expr(T &&t)
     {
@@ -531,6 +564,55 @@
     {
         return result_of::as_arg<T, Domain>::call(t);
     }
+#else
+    template<typename T>
+    typename result_of::as_expr<T &>::type as_expr(T &t)
+    {
+        return result_of::as_expr<T &>::call(t);
+    }
+
+    template<typename Domain, typename T>
+    typename result_of::as_expr<T &, Domain>::type as_expr(T &t)
+    {
+        return result_of::as_expr<T &, Domain>::call(t);
+    }
+
+    template<typename T>
+    typename result_of::as_expr<T const &>::type as_expr(T const &t)
+    {
+        return result_of::as_expr<T const &>::call(t);
+    }
+
+    template<typename Domain, typename T>
+    typename result_of::as_expr<T const &, Domain>::type as_expr(T const &t)
+    {
+        return result_of::as_expr<T const &, Domain>::call(t);
+    }
+
+    template<typename T>
+    typename result_of::as_arg<T &>::type as_arg(T &t)
+    {
+        return result_of::as_arg<T &>::call(t);
+    }
+
+    template<typename Domain, typename T>
+    typename result_of::as_arg<T &, Domain>::type as_arg(T &t)
+    {
+        return result_of::as_arg<T &, Domain>::call(t);
+    }
+
+    template<typename T>
+    typename result_of::as_arg<T const &>::type as_arg(T const &t)
+    {
+        return result_of::as_arg<T const &>::call(t);
+    }
+
+    template<typename Domain, typename T>
+    typename result_of::as_arg<T const &, Domain>::type as_arg(T const &t)
+    {
+        return result_of::as_arg<T const &, Domain>::call(t);
+    }
+#endif
 
     /// is_callable
     ///
Modified: branches/proto/v3/libs/xpressive/proto/test/Jamfile.v2
==============================================================================
--- branches/proto/v3/libs/xpressive/proto/test/Jamfile.v2	(original)
+++ branches/proto/v3/libs/xpressive/proto/test/Jamfile.v2	2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
@@ -26,4 +26,5 @@
         [ run matches.cpp ]
         [ run make_expr.cpp ]
         [ run examples.cpp ]
+        [ run deep_copy.cpp ]
     ;
Added: branches/proto/v3/libs/xpressive/proto/test/deep_copy.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto/test/deep_copy.cpp	2007-12-17 16:20:24 EST (Mon, 17 Dec 2007)
@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////////
+// deep_copy.hpp
+//
+//  Copyright 2006 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 <boost/xpressive/proto/proto.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+
+void test1()
+{
+    using namespace proto;
+
+    int i = 42;
+    terminal<int &>::type t1 = {{i}};
+    terminal<int>::type r1 = deep_copy(t1);
+    BOOST_CHECK_EQUAL(42, arg(r1));
+
+    plus<terminal<int>::type, terminal<int>::type>::type r2 = deep_copy(t1 + 24);
+    BOOST_CHECK_EQUAL(42, arg(left(r2)));
+    BOOST_CHECK_EQUAL(24, arg(right(r2)));
+
+    #ifdef BOOST_HAS_VARIADIC_TMPL
+    function<
+        terminal<int>::type
+      , terminal<int>::type
+      , terminal<int>::type
+      , terminal<int>::type
+      , terminal<int>::type
+      , terminal<int>::type
+      , terminal<int>::type
+      , terminal<int>::type
+    >::type r3 = deep_copy(t1(1,2,3,4,5,6,7));
+    #endif
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+    test_suite *test = BOOST_TEST_SUITE("test deep_copy of proto parse trees");
+
+    test->add(BOOST_TEST_CASE(&test1));
+
+    return test;
+}