Boost logo

Boost :

Subject: [boost] [phoenix] how do i achieve this type of extension of phoenix
From: Hui Li (hui.li_at_[hidden])
Date: 2013-12-25 16:21:45


I want to extend the phoenix library with my own expressions in a specific way. Would appreciate any help!! Thanks!

The code below is what i want to achieve, with the intended behavior specified in the comments. The goal is to first build an expression (the expr0), and later bind some value to certain nodes and turn them into different types of nodes with internal states (expr1) but preserve the structure of the expression tree, and also be able to modify the internal states of those nodes.

My question is, how to define myplus, mymult, myinit, and myreset to make it work?

    using boost::phoenix::arg_names::arg1;
    using boost::phoenix::arg_names::arg2;
    using boost::phoenix::arg_names::arg3;

    // how should i define myplus, mymult and myinit, so that
    // expr1 is arg1 + myplus_f<double>(3.0)(1,arg2) + mymult_f<double>(3.0)(2,arg3)
    auto expr0 = arg1 + myplus(1,arg2) + mymult(2,arg3);
    auto expr1 = myinit( expr0, 3.0 );

    // evaluate expr1 with actual arguments
    double r = expr1(1,2,3);

    // modify the internally held values of myplus_f<double>(3.0) and mymult_f<double>(3.0)
    // so that expr1 becomes equivalent to arg1 + myplus_f<double>(5.0)(1,arg2) + mymult_f<double>(5.0)(2,arg3)
    myreset(expr1, 5.0);

    // evaluate with new value members of myplus_f and mymult_f
    double r2 = expr1(1,2,3);

    
myplus_f and mymult_f are defined as follows:

template < typename T >
struct myplus_f
{
    T value;
    explicit myplus_f(const T& v):value(v){}
    
    void reset(const T& new_value) { value = new_value; }
    
    template < typename Lhs, typename Rhs >
    auto operator()(const Lhs& lhs, const Rhs& rhs) const -> decltype(value+lhs+rhs)
    {
        return value + lhs + rhs;
    }
};

template < typename T >
struct mymult_f
{
    T value;
    explicit mymult_f(const T& v):value(v){}
    
    void reset(const T& new_value) { value = new_value; }
    
    template < typename Lhs, typename Rhs >
    auto operator()(const Lhs& lhs, const Rhs& rhs) const -> decltype(value*lhs*rhs)
    {
        return value * lhs * rhs;
    }
};


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk