
Maurizio Vitale wrote:
You need proto::deep_copy():
It doesn't quite work because it seems deep_copy doesn't (seem to) use generate for wrapping up expression, with the result that the type of the object returned by deep_copy is deeply different from the type sent in.
Oh, you're right. I'll have to fix that.
Question: once deep_copy is fixed (or you show me how to use it in my context), would it be usable for initializing a static member variable?
Well, it's not ideal for that because it requires a runtime function call. But then again, so do proto's operator overloads. This is the sort of thing where you would want to leverage the POD-ness of proto's expr<> type. Consider: // 1 + "hello" proto::plus< proto::terminal<int>::type , proto::terminal<char const *>::type
::type const int_plus_string = {{1}, {"hello"}};
This thing requires no runtime initialization. And if you peek at libs/xpressive/proto/test/lambda.cpp, check out the lambda<> expression wrapper. It shows a way to extend a proto expression type without losing POD-ness, so you can make the above still work. If you'd rather go the deep copy route, you don't need to wait for me to fix proto::deep_copy(). You can accomplish the same thing with a proto transform. Here is some code to get you started. It deep-copies a proto expression, and wraps everything in a myexpr<> wrapper. #include <iostream> #include <boost/xpressive/proto/proto.hpp> using namespace boost; using proto::_; template<typename Expr> struct myexpr : proto::extends< Expr, myexpr<Expr> > { myexpr(Expr const &expr = Expr()) : proto::extends< Expr, myexpr<Expr> >(expr) {} }; template<typename Grammar> struct make_myexpr : Grammar { template<typename Expr, typename State, typename Visitor> struct apply { typedef myexpr< typename Grammar::template apply<Expr, State, Visitor>::type > type; }; template<typename Expr, typename State, typename Visitor> static typename apply<Expr, State, Visitor>::type call(Expr const &expr, State const &state, Visitor &visitor) { return typename apply<Expr, State, Visitor>::type( Grammar::call(expr, state, visitor) ); } }; template<typename Grammar> struct by_val : Grammar { template<typename Expr, typename State, typename Visitor> struct apply : proto::terminal< typename proto::result_of::arg<Expr>::type > {}; template<typename Expr, typename State, typename Visitor> static typename apply<Expr, State, Visitor>::type call(Expr const &expr, State const &state, Visitor &visitor) { return typename apply<Expr, State, Visitor>::type::make( proto::arg(expr) ); } }; struct my_deep_copy : make_myexpr< proto::or_< by_val<proto::terminal<_> > , proto::nary_expr<_, proto::vararg<my_deep_copy> > > > {}; int main() { int i = 0; // before std::cout << typeid( proto::as_expr(1) >> 2 >> 3 ).name() << std::endl; // after std::cout << typeid( my_deep_copy::call( proto::as_expr(1) >> 2 >> 3, i, i ) ).name() << std::endl; return 0; } HTH, -- Eric Niebler Boost Consulting www.boost-consulting.com