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 template<typename Expr> 9 struct deep_copy_impl<Expr, 1> 10 { 11 typedef 12 typename base_expr< 13 typename Expr::proto_domain 14 , typename Expr::proto_tag 15 , list1< 16 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type 17 > 18 >::type 19 expr_type; 20 typedef typename Expr::proto_generator proto_generator; 21 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 22 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl23 result_type operator()(Expr2 const &e, S const &, D const &) const 24 { 25 expr_type const that = { 26 proto::deep_copy(e.proto_base().child0) 27 }; 28 return proto_generator()(that); 29 } 30 }; 31 template<typename Expr> 32 struct deep_copy_impl<Expr, 2> 33 { 34 typedef 35 typename base_expr< 36 typename Expr::proto_domain 37 , typename Expr::proto_tag 38 , list2< 39 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type 40 > 41 >::type 42 expr_type; 43 typedef typename Expr::proto_generator proto_generator; 44 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 45 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl46 result_type operator()(Expr2 const &e, S const &, D const &) const 47 { 48 expr_type const that = { 49 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) 50 }; 51 return proto_generator()(that); 52 } 53 }; 54 template<typename Expr> 55 struct deep_copy_impl<Expr, 3> 56 { 57 typedef 58 typename base_expr< 59 typename Expr::proto_domain 60 , typename Expr::proto_tag 61 , list3< 62 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child2 >::type::proto_derived_expr >::result_type 63 > 64 >::type 65 expr_type; 66 typedef typename Expr::proto_generator proto_generator; 67 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 68 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl69 result_type operator()(Expr2 const &e, S const &, D const &) const 70 { 71 expr_type const that = { 72 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) , proto::deep_copy(e.proto_base().child2) 73 }; 74 return proto_generator()(that); 75 } 76 }; 77 template<typename Expr> 78 struct deep_copy_impl<Expr, 4> 79 { 80 typedef 81 typename base_expr< 82 typename Expr::proto_domain 83 , typename Expr::proto_tag 84 , list4< 85 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child2 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child3 >::type::proto_derived_expr >::result_type 86 > 87 >::type 88 expr_type; 89 typedef typename Expr::proto_generator proto_generator; 90 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 91 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl92 result_type operator()(Expr2 const &e, S const &, D const &) const 93 { 94 expr_type const that = { 95 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) , proto::deep_copy(e.proto_base().child2) , proto::deep_copy(e.proto_base().child3) 96 }; 97 return proto_generator()(that); 98 } 99 }; 100 template<typename Expr> 101 struct deep_copy_impl<Expr, 5> 102 { 103 typedef 104 typename base_expr< 105 typename Expr::proto_domain 106 , typename Expr::proto_tag 107 , list5< 108 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child2 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child3 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child4 >::type::proto_derived_expr >::result_type 109 > 110 >::type 111 expr_type; 112 typedef typename Expr::proto_generator proto_generator; 113 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 114 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl115 result_type operator()(Expr2 const &e, S const &, D const &) const 116 { 117 expr_type const that = { 118 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) , proto::deep_copy(e.proto_base().child2) , proto::deep_copy(e.proto_base().child3) , proto::deep_copy(e.proto_base().child4) 119 }; 120 return proto_generator()(that); 121 } 122 }; 123 template<typename Expr> 124 struct deep_copy_impl<Expr, 6> 125 { 126 typedef 127 typename base_expr< 128 typename Expr::proto_domain 129 , typename Expr::proto_tag 130 , list6< 131 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child2 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child3 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child4 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child5 >::type::proto_derived_expr >::result_type 132 > 133 >::type 134 expr_type; 135 typedef typename Expr::proto_generator proto_generator; 136 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 137 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl138 result_type operator()(Expr2 const &e, S const &, D const &) const 139 { 140 expr_type const that = { 141 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) , proto::deep_copy(e.proto_base().child2) , proto::deep_copy(e.proto_base().child3) , proto::deep_copy(e.proto_base().child4) , proto::deep_copy(e.proto_base().child5) 142 }; 143 return proto_generator()(that); 144 } 145 }; 146 template<typename Expr> 147 struct deep_copy_impl<Expr, 7> 148 { 149 typedef 150 typename base_expr< 151 typename Expr::proto_domain 152 , typename Expr::proto_tag 153 , list7< 154 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child2 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child3 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child4 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child5 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child6 >::type::proto_derived_expr >::result_type 155 > 156 >::type 157 expr_type; 158 typedef typename Expr::proto_generator proto_generator; 159 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 160 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl161 result_type operator()(Expr2 const &e, S const &, D const &) const 162 { 163 expr_type const that = { 164 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) , proto::deep_copy(e.proto_base().child2) , proto::deep_copy(e.proto_base().child3) , proto::deep_copy(e.proto_base().child4) , proto::deep_copy(e.proto_base().child5) , proto::deep_copy(e.proto_base().child6) 165 }; 166 return proto_generator()(that); 167 } 168 }; 169 template<typename Expr> 170 struct deep_copy_impl<Expr, 8> 171 { 172 typedef 173 typename base_expr< 174 typename Expr::proto_domain 175 , typename Expr::proto_tag 176 , list8< 177 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child2 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child3 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child4 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child5 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child6 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child7 >::type::proto_derived_expr >::result_type 178 > 179 >::type 180 expr_type; 181 typedef typename Expr::proto_generator proto_generator; 182 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 183 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl184 result_type operator()(Expr2 const &e, S const &, D const &) const 185 { 186 expr_type const that = { 187 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) , proto::deep_copy(e.proto_base().child2) , proto::deep_copy(e.proto_base().child3) , proto::deep_copy(e.proto_base().child4) , proto::deep_copy(e.proto_base().child5) , proto::deep_copy(e.proto_base().child6) , proto::deep_copy(e.proto_base().child7) 188 }; 189 return proto_generator()(that); 190 } 191 }; 192 template<typename Expr> 193 struct deep_copy_impl<Expr, 9> 194 { 195 typedef 196 typename base_expr< 197 typename Expr::proto_domain 198 , typename Expr::proto_tag 199 , list9< 200 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child2 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child3 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child4 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child5 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child6 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child7 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child8 >::type::proto_derived_expr >::result_type 201 > 202 >::type 203 expr_type; 204 typedef typename Expr::proto_generator proto_generator; 205 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 206 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl207 result_type operator()(Expr2 const &e, S const &, D const &) const 208 { 209 expr_type const that = { 210 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) , proto::deep_copy(e.proto_base().child2) , proto::deep_copy(e.proto_base().child3) , proto::deep_copy(e.proto_base().child4) , proto::deep_copy(e.proto_base().child5) , proto::deep_copy(e.proto_base().child6) , proto::deep_copy(e.proto_base().child7) , proto::deep_copy(e.proto_base().child8) 211 }; 212 return proto_generator()(that); 213 } 214 }; 215 template<typename Expr> 216 struct deep_copy_impl<Expr, 10> 217 { 218 typedef 219 typename base_expr< 220 typename Expr::proto_domain 221 , typename Expr::proto_tag 222 , list10< 223 typename deep_copy_impl< typename remove_reference< typename Expr::proto_child0 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child1 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child2 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child3 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child4 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child5 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child6 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child7 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child8 >::type::proto_derived_expr >::result_type , typename deep_copy_impl< typename remove_reference< typename Expr::proto_child9 >::type::proto_derived_expr >::result_type 224 > 225 >::type 226 expr_type; 227 typedef typename Expr::proto_generator proto_generator; 228 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; 229 template<typename Expr2, typename S, typename D> operator ()deep_copy_impl230 result_type operator()(Expr2 const &e, S const &, D const &) const 231 { 232 expr_type const that = { 233 proto::deep_copy(e.proto_base().child0) , proto::deep_copy(e.proto_base().child1) , proto::deep_copy(e.proto_base().child2) , proto::deep_copy(e.proto_base().child3) , proto::deep_copy(e.proto_base().child4) , proto::deep_copy(e.proto_base().child5) , proto::deep_copy(e.proto_base().child6) , proto::deep_copy(e.proto_base().child7) , proto::deep_copy(e.proto_base().child8) , proto::deep_copy(e.proto_base().child9) 234 }; 235 return proto_generator()(that); 236 } 237 }; 238