Boost logo

Boost Users :

Subject: Re: [Boost-users] [Proto?][Phoenix?] : Advice on creating lazy data structures
From: Manjunath Kudlur (keveman_at_[hidden])
Date: 2010-03-30 15:48:40


> Thanks, Eric. That was an Ah-ha moment for me. I tried a different
> variation of your program. I changed point to a templated
> tuple<typename X, typename Y> and declared the terminals x and y with
> proto::_ template arguments. Here is the complete program :

I re-worked the program as below to achieve what I need. But now,
using the DSEL with a new data-type becomes much more invasive,
because I need some rules to the grammar. May be there is a less
invasive and more elegant way? Also, I don't understand why I need
both This(tuple<>&) and This(const tuple<>&) versions in the
get_tuple_* classes. Removing either one of them causes a compiler
error.

#include <cassert>
#include <boost/proto/proto.hpp>
#include <iostream>
namespace proto = boost::proto;

template<typename X, typename Y>
struct tuple {
  X x;
  Y y;
};

struct arg_ {};
proto::terminal<arg_>::type arg = {{}};

struct x_ {};
proto::terminal<x_>::type x = {{}};
struct y_ {};
proto::terminal<y_>::type y = {{}};

struct get_tuple_x
  : proto::callable {

  template<typename Sig>
  struct result;

  template<typename This, typename X, typename Y>
  struct result<This(tuple<X, Y> &)> {
    typedef X type;
  };

  template<typename This, typename X, typename Y>
  struct result<This(const tuple<X, Y> &)> {
    typedef X type;
  };

  template<typename X, typename Y>
  X operator()(tuple<X, Y> &t) const {
    return t.x;
  }

  template<typename X, typename Y>
  X operator()(const tuple<X, Y> &t) const {
    return t.x;
  }
};

struct get_tuple_y
  : proto::callable {

  template<typename Sig>
  struct result;

  template<typename This, typename X, typename Y>
  struct result<This(tuple<X, Y> &)> {
    typedef Y type;
  };

  template<typename This, typename X, typename Y>
  struct result<This(const tuple<X, Y> &)> {
    typedef Y type;
  };

  template<typename X, typename Y>
  Y operator()(tuple<X, Y> &t) const {
    return t.y;
  }

  template<typename X, typename Y>
  Y operator()(const tuple<X, Y> &t) const {
    return t.y;
  }
};

struct micro_lambda
  : proto::or_<
proto::when<
  proto::mem_ptr<proto::terminal<arg_>, proto::terminal<x_> >
  , get_tuple_x(proto::_state)>
, proto::when<
  proto::mem_ptr<proto::terminal<arg_>, proto::terminal<y_> >
  , get_tuple_y(proto::_state)>
, proto::otherwise<
  proto::_default<micro_lambda>
>
>
{} eval;

using namespace std;

int main()
{
  tuple<int, float> t;
  t.x = 1;
  t.y = 41.f;

  cout << eval(arg->*x + arg->*y, t) << endl;
}

Manjunath


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