Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Deep-copying Expressions

When you build an expression template with Proto, all the intermediate child nodes are held by reference. The avoids needless copies, which is crucial if you want your EDSL to perform well at runtime. Naturally, there is a danger if the temporary objects go out of scope before you try to evaluate your expression template. This is especially a problem in C++0x with the new decltype and auto keywords. Consider:

// OOPS: "ex" is left holding dangling references
auto ex = proto::lit(1) + 2;

The problem can happen in today's C++ also if you use BOOST_TYPEOF() or BOOST_AUTO(), or if you try to pass an expression template outside the scope of its constituents.

In these cases, you want to deep-copy your expression template so that all intermediate nodes and the terminals are held by value. That way, you can safely assign the expression template to a local variable or return it from a function without worrying about dangling references. You can do this with proto::deep_copy() as fo llows:

// OK, "ex" has no dangling references
auto ex = proto::deep_copy( proto::lit(1) + 2 );

If you are using Boost.Typeof, it would look like this:

// OK, use BOOST_AUTO() and proto::deep_copy() to
// store an expression template in a local variable 
BOOST_AUTO( ex, proto::deep_copy( proto::lit(1) + 2 ) );

For the above code to work, you must include the boost/proto/proto_typeof.hpp header, which also defines the BOOST_PROTO_AUTO() macro which automatically deep-copies its argument. With BOOST_PROTO_AUTO(), the above code can be writen as:

// OK, BOOST_PROTO_AUTO() automatically deep-copies
// its argument: 
BOOST_PROTO_AUTO( ex, proto::lit(1) + 2 );

When deep-copying an expression tree, all intermediate nodes and all terminals are stored by value. The only exception is terminals that are function references, which are left alone.

[Note] Note

proto::deep_copy() makes no exception for arrays, which it stores by value. That can potentially cause a large amount of data to be copied.


PrevUpHomeNext