1 /////////////////////////////////////////////////////////////////////////////// 2 /// \file deep_copy.hpp 3 /// Replace all nodes stored by reference by nodes stored by value. 4 // 5 // Copyright 2008 Eric Niebler. Distributed under the Boost 6 // Software License, Version 1.0. (See accompanying file 7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 9 #ifndef BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006 10 #define BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006 11 12 #include <boost/preprocessor/cat.hpp> 13 #include <boost/preprocessor/repetition/enum.hpp> 14 #include <boost/preprocessor/iteration/iterate.hpp> 15 #include <boost/mpl/if.hpp> 16 #include <boost/type_traits/remove_reference.hpp> 17 #include <boost/proto/proto_fwd.hpp> 18 #include <boost/proto/args.hpp> 19 #include <boost/proto/expr.hpp> 20 21 namespace boost { namespace proto 22 { 23 namespace detail 24 { 25 template<typename Expr, long Arity = Expr::proto_arity_c> 26 struct deep_copy_impl; 27 28 template<typename Expr> 29 struct deep_copy_impl<Expr, 0> 30 { 31 typedef 32 typename base_expr< 33 typename Expr::proto_domain 34 , tag::terminal 35 , term<typename term_traits<typename Expr::proto_child0>::value_type> 36 >::type 37 expr_type; 38 39 typedef typename Expr::proto_generator proto_generator; 40 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 41 42 template<typename Expr2, typename S, typename D> operator ()boost::proto::detail::deep_copy_impl43 result_type operator()(Expr2 const &e, S const &, D const &) const 44 { 45 return proto_generator()(expr_type::make(e.proto_base().child0)); 46 } 47 }; 48 } 49 50 namespace result_of 51 { 52 /// \brief A metafunction for calculating the return type 53 /// of \c proto::deep_copy(). 54 /// 55 /// A metafunction for calculating the return type 56 /// of \c proto::deep_copy(). The type parameter \c Expr 57 /// should be the type of a Proto expression tree. 58 /// It should not be a reference type, nor should it 59 /// be cv-qualified. 60 template<typename Expr> 61 struct deep_copy 62 { 63 typedef 64 typename detail::deep_copy_impl< 65 BOOST_PROTO_UNCVREF(Expr) 66 >::result_type 67 type; 68 }; 69 } 70 71 namespace functional 72 { 73 /// \brief A PolymorphicFunctionObject type for deep-copying 74 /// Proto expression trees. 75 /// 76 /// A PolymorphicFunctionObject type for deep-copying 77 /// Proto expression trees. When a tree is deep-copied, 78 /// all internal nodes and most terminals held by reference 79 /// are instead held by value. 80 /// 81 /// \attention Terminals of reference-to-function type are 82 /// left unchanged. Terminals of reference-to-array type are 83 /// stored by value, which can cause a large amount of data 84 /// to be passed by value and stored on the stack. 85 struct deep_copy 86 { 87 BOOST_PROTO_CALLABLE() 88 89 template<typename Sig> 90 struct result; 91 92 template<typename This, typename Expr> 93 struct result<This(Expr)> 94 { 95 typedef 96 typename detail::deep_copy_impl< 97 BOOST_PROTO_UNCVREF(Expr) 98 >::result_type 99 type; 100 }; 101 102 /// \brief Deep-copies a Proto expression tree, turning all 103 /// nodes and terminals held by reference into ones held by 104 /// value. 105 template<typename Expr> 106 typename result_of::deep_copy<Expr>::type operator ()boost::proto::functional::deep_copy107 operator()(Expr const &e) const 108 { 109 return proto::detail::deep_copy_impl<Expr>()(e, 0, 0); 110 } 111 }; 112 } 113 114 /// \brief A function for deep-copying 115 /// Proto expression trees. 116 /// 117 /// A function for deep-copying 118 /// Proto expression trees. When a tree is deep-copied, 119 /// all internal nodes and most terminals held by reference 120 /// are instead held by value. 121 /// 122 /// \attention Terminals of reference-to-function type are 123 /// left unchanged. 124 /// 125 /// \sa proto::functional::deep_copy. 126 template<typename Expr> 127 typename proto::result_of::deep_copy<Expr>::type deep_copy(Expr const & e)128 deep_copy(Expr const &e) 129 { 130 return proto::detail::deep_copy_impl<Expr>()(e, 0, 0); 131 } 132 133 /// \brief A PrimitiveTransform for deep-copying 134 /// Proto expression trees. 135 /// 136 /// A PrimitiveTransform for deep-copying 137 /// Proto expression trees. When a tree is deep-copied, 138 /// all internal nodes and most terminals held by reference 139 /// are instead held by value. 140 /// 141 /// \attention Terminals of reference-to-function type are 142 /// left unchanged. 143 /// 144 /// \sa proto::functional::deep_copy. 145 struct _deep_copy 146 : proto::transform<_deep_copy> 147 { 148 template<typename E, typename S, typename D> 149 struct impl 150 : detail::deep_copy_impl<BOOST_PROTO_UNCVREF(E)> 151 {}; 152 }; 153 154 namespace detail 155 { 156 // include the definition of deep_copy_impl 157 #include <boost/proto/detail/deep_copy.hpp> 158 } 159 160 }} 161 162 #endif // BOOST_PROTO_COMPILER_DEEP_COPY_HPP_EAN_11_21_2006 163 164