I am trying to define operator()(...) for my expressions. I want to be
able to form expression of the form Program_(a,b) and call Program_(a,
b)(10,20). Here, 'a' and 'b' are terminals and I have a mechanism
shown in the code below that somehow gets the type suitable for the
parameter position. Suppose 'a' is terminal, I want the
first parameter position in Program_(a,b) (pos1, pos2) to be of the
type 'int'.
typename boost::result_of::type
gives me that type for the Mth argument in the expression of the form
Program_(a1,a2,...). Now, I am trying to use this to define
operator()(...) in my program_expr class. That doesn't seem to work.
However, if I define a separate function callfunc, that takes the
expression and the arguments, that seems to work. In the following
code, enabling the if 0'ed out code results in compilation errors. How
do I go about defining operator()(...) in my program_expr class with
the above property?
Thanks,
Manjunath
#include
#include
#include
#include
#include <iostream>
#include <sstream>
#include <string>
namespace proto=boost::proto;
namespace mpl=boost::mpl;
unsigned int ids;
template<typename VT>
struct Var {
unsigned int id;
Var() {
id = ++ids;
}
};
typedef proto::terminal::type int32_;
typedef proto::terminal::type float_;
struct program_ {};
template<class E> struct program_expr;
struct program_domain
: proto::domain > {
};
struct _var_type
: proto::callable {
template<typename Sig>
struct result;
template
struct result {
typedef T type;
};
};
struct var_type
: proto::or_<
proto::whenproto::_ >,
_var_type(proto::_value)>
{};
template<int N>
struct call_param_type
: proto::or_<
proto::when<
proto::function<
proto::terminal,
proto::varargproto::_ > > >,
var_type(proto::_child_c)>
{};
template <typename Expr>
struct program_expr {
BOOST_PROTO_BASIC_EXTENDS(Expr, program_expr<Expr>, program_domain);
BOOST_PROTO_EXTENDS_SUBSCRIPT();
typedef void result_type;
#if 0
result_type operator()(typename
boost::result_of(const Expr &)>::type x) {
std::cout << "program with one arg\n";
}
result_type operator()(typename
boost::result_of(const Expr &)>::type x,
typename
boost::result_of(const Expr &)>::type y) {
std::cout << "program with two args\n";
}
#endif
};
template<typename Expr>
void callfunc(const Expr &e,
typename boost::result_of(const Expr
&)>::type x)
{
std::cout << "program with one arg\n";
}
template<typename Expr>
void callfunc(const Expr &e,
typename boost::result_of(const Expr
&)>::type x,
typename boost::result_of(const Expr
&)>::type y)
{
std::cout << "program with two args\n";
}
template<typename A0>
typename proto::result_of::make_expr::type const
Program_(A0 const &a0)
{
return proto::make_expr(
program_(),
boost::ref(a0));
}
template
typename proto::result_of::make_expr::type const
Program_(A0 const &a0, A1 const &a1)
{
return proto::make_expr(
program_(),
boost::ref(a0),
boost::ref(a1));
}
int main()
{
int32_ a,b,c;
callfunc(Program_(a, b), 10, 20);
#if 0
Program_(a, b)(10, 20);
#endif
}