#ifndef BOOST_PP_IS_ITERATING /////////////////////////////////////////////////////////////////////////////// /// \file deep_copy.hpp /// Replace all nodes stored by reference by nodes stored by value. // // 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) #ifndef BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006 #define BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006 #include #include #include #include #include #include #include #include namespace boost { namespace proto { namespace detail { template struct deep_copy_impl; template struct deep_copy_impl { typedef typename base_expr< typename Expr::proto_domain , tag::terminal , term::value_type> >::type expr_type; typedef typename Expr::proto_generator proto_generator; typedef typename proto_generator::template result::type result_type; template result_type operator()(Expr2 const &e, S const &, D const &) const { return proto_generator()(expr_type::make(e.proto_base().child0)); } }; } namespace result_of { /// \brief A metafunction for calculating the return type /// of \c proto::deep_copy(). /// /// A metafunction for calculating the return type /// of \c proto::deep_copy(). The type parameter \c Expr /// should be the type of a Proto expression tree. /// It should not be a reference type, nor should it /// be cv-qualified. template struct deep_copy { typedef typename detail::deep_copy_impl< BOOST_PROTO_UNCVREF(Expr) >::result_type type; }; } namespace functional { /// \brief A PolymorphicFunctionObject type for deep-copying /// Proto expression trees. /// /// A PolymorphicFunctionObject type for deep-copying /// Proto expression trees. When a tree is deep-copied, /// all internal nodes and most terminals held by reference /// are instead held by value. /// /// \attention Terminals of reference-to-function type are /// left unchanged. Terminals of reference-to-array type are /// stored by value, which can cause a large amount of data /// to be passed by value and stored on the stack. struct deep_copy { BOOST_PROTO_CALLABLE() template struct result; template struct result { typedef typename detail::deep_copy_impl< BOOST_PROTO_UNCVREF(Expr) >::result_type type; }; /// \brief Deep-copies a Proto expression tree, turning all /// nodes and terminals held by reference into ones held by /// value. template typename result_of::deep_copy::type operator()(Expr const &e) const { return proto::detail::deep_copy_impl()(e, 0, 0); } }; } /// \brief A function for deep-copying /// Proto expression trees. /// /// A function for deep-copying /// Proto expression trees. When a tree is deep-copied, /// all internal nodes and most terminals held by reference /// are instead held by value. /// /// \attention Terminals of reference-to-function type are /// left unchanged. /// /// \sa proto::functional::deep_copy. template typename proto::result_of::deep_copy::type deep_copy(Expr const &e) { return proto::detail::deep_copy_impl()(e, 0, 0); } /// \brief A PrimitiveTransform for deep-copying /// Proto expression trees. /// /// A PrimitiveTransform for deep-copying /// Proto expression trees. When a tree is deep-copied, /// all internal nodes and most terminals held by reference /// are instead held by value. /// /// \attention Terminals of reference-to-function type are /// left unchanged. /// /// \sa proto::functional::deep_copy. struct _deep_copy : proto::transform<_deep_copy> { template struct impl : detail::deep_copy_impl {}; }; namespace detail { #define BOOST_PROTO_DEFINE_DEEP_COPY_TYPE(Z, N, DATA) \ typename deep_copy_impl< \ typename remove_reference< \ typename Expr::BOOST_PP_CAT(proto_child, N) \ >::type::proto_derived_expr \ >::result_type \ /**/ #define BOOST_PROTO_DEFINE_DEEP_COPY_FUN(Z, N, DATA) \ proto::deep_copy(e.proto_base().BOOST_PP_CAT(child, N)) \ /**/ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, )) #include BOOST_PP_ITERATE() #undef BOOST_PROTO_DEFINE_DEEP_COPY_FUN #undef BOOST_PROTO_DEFINE_DEEP_COPY_TYPE } }} #endif // BOOST_PROTO_COMPILER_DEEP_COPY_HPP_EAN_11_21_2006 #else #define N BOOST_PP_ITERATION() template struct deep_copy_impl { typedef typename base_expr< typename Expr::proto_domain , typename Expr::proto_tag , BOOST_PP_CAT(list, N)< BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_TYPE, ~) > >::type expr_type; typedef typename Expr::proto_generator proto_generator; typedef typename proto_generator::template result::type result_type; template result_type operator()(Expr2 const &e, S const &, D const &) const { expr_type const that = { BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_FUN, ~) }; return proto_generator()(that); } }; #undef N #endif