Boost logo

Boost Users :

Subject: [Boost-users] [phoenix] function object that is also lazy
From: alfC (alfredo.correa_at_[hidden])
Date: 2011-04-15 21:55:55


Hi,

 Is this possible at all?

struct A : boost::phoenix::function<A const&>{
        double operator()(double const& d) const{return 5.;}
}

such that an object function it is not only a function but also a lazy
function of itself?
        std::clog << a(4.) << std::endl;
        std::clog << a(arg1 + 1.)(4.) << std::endl;

the code above doesn't work because A is not complete when the type
function<A> is instatiated. However after some experimentation I got
the following. The question is, does it really work in more exotic
context? Is there a possible simplification? Am I reinventing the
wheel?

template<class Self>
struct lazy{
        boost::phoenix::function<Self const&> const* const lazy_;
        lazy(Self const& self) : lazy_(new boost::phoenix::function<Self
const&>(self)){}
        template<class Arg>
        const
boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval,
boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<Self>, 0l>,
                Arg
>, 2l> >
        operator()(Arg const& arg) const{return (*lazy_)(arg);}
        ~lazy(){delete(lazy_);}
};

struct A : lazy<A>{

        using lazy<A>::operator();
        A() : lazy<A>(*this){}
        A(A const& other) : lazy<A>(*this){}

        typedef
        double result_type; result_type
        operator()(double const& d) const{return d;}

};

so, any function object B can be a lazy function of it self provided
that we use the correct CRTP argument (lazy<B>) and manually add the
code:

        using lazy<A>::operator();
        B() : lazy<A>(*this){}
        B(A const& other) : lazy<A>(*this){}

inside the class. This feature seems to make the usage of the function
object b more flexible, since it can we used in many different
contexts. For example, as

  integrate ( b, 1., 2.);

or as

 integrate ( 2.*b(arg1 + 1.) , 1., 2.)

Thanks,
Alfredo


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net