$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-07-17 13:58:22
Eric Niebler <eric_at_[hidden]> writes:
> Maurizio Vitale wrote:
<snip>
>>
>> My mental model was:
>> - proto::deep_copy traverse the expression top-down replacing references with value.
>
> Actually, bottom-up, but yes references are replaced with values.
It is probably terminology, but the following seems top-down to me: you're asked to deep-copy
an expression and you assemble an expression which has the same shape (tag and argcount) of the
original and as children the result of recursive evaluations of deep-copy on the children.
#define N BOOST_PP_ITERATION()
template<typename Expr>
struct deep_copy_impl<Expr, N>
{
typedef expr<typename Expr::proto_tag, BOOST_PP_CAT(args, N)<
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_TYPE, ~)
> > expr_type;
typedef typename Expr::proto_domain::template apply<expr_type>::type type;
template<typename Expr2>
static type call(Expr2 const &expr)
{
expr_type that = {
BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_FUN, ~)
};
return Expr::proto_domain::make(that);
}
};
>
>> - generators are used to wrap expressions as they are built bottom-up
>
> Generators are used whenever you want to customize the result of proto's
> operator overloads.
Yes, and my reading of the behaviour of the specific generator you wrote is that
everytime you construct an expression you evaluate deep_copy on it.
Modulo the number of evaluations of deep_copy, I still don't see any difference
between using deep_copy on the toplevel expression and using the generator for
building an already deep-copied solution (other than, as you point out later in
one case you have to explicitely call deep_copy while in the other expressions
naturally spring to life without references)
>> So, assuming that the expression is properly wrapped in lambda_expr<> why the result
>> of calling proto::expr on the whole expression would be different from using the generator?
>
> Sorry, I don't understand the question.
I guess my question is what is the difference between:
struct lambda_domain : domain<generator<lambda_expression> > {};
auto expr = deep_copy(_1 + 42);
and:
auto expr_1 = _1 + 42; in the case where the generator you provided is used
Aren't expr and expr_1 exactly the same?
> How this helps is that as phoenix expressions are being built, the
> phoenix generator will ensure that all the nodes are held by-value.
> There will never be a need for the user to deep_copy phoenix expressions
> explicitly -- it's done piecemeal by phoenix. So function<> is passed an
> object that does not need to be deep-copied.
I see this difference now and understand the reasons behind your suggestion.
Thanks for the explanation,
Maurizio