3

In the boost::proto manual, there is an example of a grammar that matches terminals of type std::transform<...>:

struct StdComplex
  : proto::terminal< std::complex< proto::_ > >  
{};

I would like to write a transform that does something with the type of the proto::_. For example, when matching a proto::terminal< std::complex< T > >, it returns a boost::shared_ptr < T > .

Is this possible?

Another way to state my question is, how do I make the following snippet work?

template<typename T>
struct Show : proto::callable  
{
    typedef T result_type;

    result_type operator()(T& v)
    {
        std::cout << "value = " << v << std::endl;
        return v;
    }
};


struct my_grammar
: proto::when<proto::terminal<proto::_ >, Show<??? what comes here ???>(proto::_value) >  
{};  
ildjarn
  • 62,044
  • 9
  • 127
  • 211
Irit Katriel
  • 3,534
  • 1
  • 16
  • 18

1 Answers1

3

Your Show transform will be easier to handle as a Polymorphic Function Object :

struct Show : proto::callable  
{
  template<class Sig> struct result;

  template<class This, class T>
  struct result<This(T)>
  {
    typedef T type;
  };

  template<class T> T operator()(T const& v) const
  {
      std::cout << "value = " << v << std::endl;
      return v;
  }
};   

struct my_grammar
: proto::when<proto::terminal<proto::_ >, Show(proto::_value) >  
{};  

Your answer on the other problem is :

struct to_shared : proto::callable  
{
  template<class Sig> struct result;

  template<class This, class T>
  struct result<This(T)>
  {
    typedef typename T::value_type base;
    typedef shared_ptr<base> type;
  };

  template<class T> 
  typename result<to_share(T)>::type operator()(T const& v) const
  {
    // stuff
  }
};


struct my_grammar
: proto::when<proto::terminal<complex<proto::_> >, to_shared(proto::_value) >  
{};  
Joel Falcou
  • 6,247
  • 1
  • 17
  • 34
  • This seems to work for proto::terminal::type term1 = {{21}}; but not proto::terminal::type term1 = {{21}}; Am I right? In my application I want the terminal to hold a shared_ptr, which points to something that the transform can modify. Is this a problem? Thanks. – Irit Katriel Feb 25 '12 at 11:49
  • The error I get from the compiler with non-const int is: Non-const lvalue reference to type 'int' cannot bind to temporary of type 'int'. – Irit Katriel Feb 25 '12 at 11:52
  • I suppose I just need to use a const-pointer-to-non-const-object. – Irit Katriel Feb 25 '12 at 12:00