Boost logo

Boost Users :

Subject: [Boost-users] [Proto] callable_context
From: Hossein Haeri (powerprogman_at_[hidden])
Date: 2010-12-10 11:57:00


Dear all,

I am trying to use callable_contexts to evaluate expressions like:

x >> f >> g >> h;

where this would be equivalent to h(g(f(x))). I have derived my context from callable_context, and thought I have overloaded for relevant tags (terminal and shift_right). GCC 4.5.1 (MinGW32, WinXP, SP3) stops with an error message which is cryptic to my current level of knowledge about Proto. I guess that's because I haven't done the job correctely. For your reference, I have included a copy of my program as well as the error GCC gives me in the P.S. section of this posting. Any ideas please?

TIA,
--Hossein

P.S.

<code>

#include <iostream>
#include <boost/proto/proto.hpp>

namespace mpl = boost::mpl;
namespace proto = boost::proto;
using proto::_;

using namespace std;

struct EWGrandDad
{
        int evaluate() const;
};
typedef proto::terminal<double (*) (double)> FunctionType;

template<typename> struct EmtExpr;

struct EmtGrammar:
        proto::or_
        <
                proto::terminal<EWGrandDad>,
                proto::shift_right<EmtGrammar, FunctionType>
>
{};

struct EmtDomain: proto::domain<proto::generator<EmtExpr>, EmtGrammar> {};

template<typename Expr>
struct EmtExpr
  : proto::extends<Expr, EmtExpr<Expr>, EmtDomain>
{
        typedef proto::extends<Expr, EmtExpr<Expr>, EmtDomain> base_type;

        EmtExpr(const Expr& e = Expr()): base_type(e) {}
};

struct EWBase
  : EmtExpr<typename proto::terminal<EWGrandDad>::type>
{
        typedef typename proto::terminal<EWGrandDad>::type expr_type;

        EWBase(): EmtExpr<expr_type>(expr_type::make(EWGrandDad())) {}
};

struct EW1: EWBase
{
        EW1(int n1, int n2): n1_(n1), n2_(n2) {}

        int evaluate() const {return n1_ * n2_;}

        int n1_, n2_;
};

double times2(double d) {return d * 2;}
double minus1(double d) {return d - 1;}

struct EmtContext: proto::callable_context<const EmtContext>
{
        typedef double result_type;

        result_type operator() (proto::tag::terminal, const EWGrandDad& ew) const
        {
                return ew.evaluate();
        }

        template<typename Expr>
        result_type operator() (proto::tag::shift_right, const Expr& e, FunctionType f) const
        {
                return f(proto::eval(e, *this));
        }
};

int main()
{
        EmtContext emtCtx;
        cout << "result = " << emtCtx(EW1(4, 5) >> &times2 >> &minus1);
        return 0;
}

</code>
<error message>
main.cpp: In function 'int main()':
main.cpp:82:63: error: no match for call to '(EmtContext) (const boost::lazy_enable_if_c<true, boost::proto::generatorns_::generator<EmtExpr>::result<EmtDomain(boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<const EmtExpr<boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<const EW1&, EmtExpr<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<double (* const&)(double)>, 0l> > >, 2l> >&, EmtExpr<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<double (* const&)(double)>, 0l> > >, 2l>)> >::type)'
main.cpp:67:14: note: candidate is: EmtContext::result_type EmtContext::operator()(boost::proto::tag::terminal, const EWGrandDad&) const
</error message>


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