Boost logo

Proto :

Subject: Re: [proto] Transform result_of nightmare and preserving terminal identity
From: Bart Janssens (bart.janssens_at_[hidden])
Date: 2012-10-16 06:24:29


On Sun, Oct 14, 2012 at 1:20 AM, Agustín K-ballo Bergé
<kaballo86_at_[hidden]> wrote:
> When deep copying an expression the 'identity' of the terminals is lost, as
> each reference to a terminal results in a new hold by value terminal.
> Consequently, expressions with side effects (like assignment) no longer
> evaluate correctly. Is it possible to customize the expression 'semantics'
> so that when a deep copy is made terminals are copied only the first time
> they are seen, and subsequent uses refer to that first copy?

Hi Agustín,

Re-reading your question after Eric's nudge, I think this is similar
to a question I asked a while ago. Eric proposed replacing the
standard deep copy with a transform like this:

struct DeepCopy :
  boost::proto::or_
  <
    boost::proto::when // exceptions for terminals that need to be
stored by value
    <
      boost::proto::or_
      <
        boost::proto::terminal<const double&>,
        boost::proto::terminal<const int&>
>,
      boost::proto::_make_terminal(boost::proto::_byval(boost::proto::_value))
>,
    boost::proto::terminal<boost::proto::_>,
    boost::proto::nary_expr<boost::proto::_, boost::proto::vararg<
boost::proto::when<DeepCopy, boost::proto::_byval(DeepCopy)> > >
>
{
};

This can then be called like DeepCopy()(your_expr). The when<>
template in here has some exceptions for terminals that I did want to
keep by value, so if you remove that all terminals should be stored by
reference in the copy. Concretely in the above example, const doubles
and ints are stored by value in the copy, all other types including
non-const doubles and ints are kept by reference. Hope this helps!

Cheers,

-- 
Bart

Proto list run by eric at boostpro.com