You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
163 lines
5.3 KiB
163 lines
5.3 KiB
/////////////////////////////////////////////////////////////////////////////// |
|
/// \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 <boost/preprocessor/cat.hpp> |
|
#include <boost/preprocessor/repetition/enum.hpp> |
|
#include <boost/preprocessor/iteration/iterate.hpp> |
|
#include <boost/mpl/if.hpp> |
|
#include <boost/type_traits/remove_reference.hpp> |
|
#include <boost/proto/proto_fwd.hpp> |
|
#include <boost/proto/args.hpp> |
|
#include <boost/proto/expr.hpp> |
|
|
|
namespace boost { namespace proto |
|
{ |
|
namespace detail |
|
{ |
|
template<typename Expr, long Arity = Expr::proto_arity_c> |
|
struct deep_copy_impl; |
|
|
|
template<typename Expr> |
|
struct deep_copy_impl<Expr, 0> |
|
{ |
|
typedef |
|
typename base_expr< |
|
typename Expr::proto_domain |
|
, tag::terminal |
|
, term<typename term_traits<typename Expr::proto_child0>::value_type> |
|
>::type |
|
expr_type; |
|
|
|
typedef typename Expr::proto_generator proto_generator; |
|
typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type; |
|
|
|
template<typename Expr2, typename S, typename D> |
|
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<typename Expr> |
|
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<typename Sig> |
|
struct result; |
|
|
|
template<typename This, typename Expr> |
|
struct result<This(Expr)> |
|
{ |
|
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 Expr> |
|
typename result_of::deep_copy<Expr>::type |
|
operator()(Expr const &e) const |
|
{ |
|
return proto::detail::deep_copy_impl<Expr>()(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 Expr> |
|
typename proto::result_of::deep_copy<Expr>::type |
|
deep_copy(Expr const &e) |
|
{ |
|
return proto::detail::deep_copy_impl<Expr>()(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<typename E, typename S, typename D> |
|
struct impl |
|
: detail::deep_copy_impl<BOOST_PROTO_UNCVREF(E)> |
|
{}; |
|
}; |
|
|
|
namespace detail |
|
{ |
|
// include the definition of deep_copy_impl |
|
#include <boost/proto/detail/deep_copy.hpp> |
|
} |
|
|
|
}} |
|
|
|
#endif // BOOST_PROTO_COMPILER_DEEP_COPY_HPP_EAN_11_21_2006 |
|
|
|
|