Boost logo

Boost :

From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-04-12 10:15:35


I'm trying to following your suggestion of putting data inside what used to
be a simple tag and then extend it.
This is a simplified version of what I need, without non-default contexts and domains.

The problem I'm seeng seems to have to do with display_expr (e.g. the naked expressions
alone seems to compile, although I'm not sure how smart the compiler is allowed to
do when values are unused and everything is visible within the same file).

display_expr is very nice to have, and I think will be even more useful when I'll start
with transformations. There're other behaviours of it that looks strange to me, I'll try to
reduce them to small examples asap.

I see that in debug.hpp you handle the case of 1 and 2 arguments explicitely and then
the general case of 3 <= N <= BOOST_PROTO_MAX_ARITY using the boost preprocessor.
It seems to me that all cases could be handled uniformly (I'm not sure about the case
for N=1, where you use display(proto::arg(expr)): is arg equivalent to arg_c<0>)?

This part of debug.hpp seems also the likely cause of the problem I've mentioned in my
other post (ambiguity when BOOST_PROTO_MAX_ARITY==2). It might be that the preprocessor
iterates at least once anyhow, which might give a double definition for the case N==2
(why the generated item would correspond to the end of iteration rather than the beginning
I don't know). It might be a bug in the preprocessor, but I don't know enough about what
it is supposed to do.

I also don't know why the case N==2 and N==3 below fail, as N==2 is handled as special case,
(like N==1, which is ok) while N==3 is handled by preprocessor expansion of different code
(like N==4, which is ok).

#include <iostream>
#include <boost/xpressive/proto/proto.hpp>
#include <boost/xpressive/proto/context.hpp>
#include <boost/xpressive/proto/extends.hpp>
#include <boost/xpressive/proto/debug.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/typeof/std/ostream.hpp>

namespace proto=boost::proto;

struct udt_tag {
  friend std::ostream& operator << (std::ostream& os, const udt_tag o);
  unsigned int m_data;

std::ostream& operator << (std::ostream& os, const udt_tag o) { os << "~" << o.m_data << "~"; return os; }

struct udt_ex : proto::extends<proto::terminal<udt_tag>::type, udt_ex>
  typedef proto::extends<proto::terminal<udt_tag>::type, udt_ex> expr_type;

  udt_ex () {}
  udt_ex (int i) : expr_type (expr_type::type::make (i)) {}

  using proto::extends<proto::terminal<udt_tag>::type, udt_ex>::operator=;

int main (int, char**) {
  udt_ex b(3);

  display_expr (b*b(3,4,5,6)); // OK
  // display_expr (b*b(4,5,6)); // NOK: in proto/ref.hpp:72,73 forming reference to void
  // display_expr (b*b(5,6)); // NOK: in proto/ref.hpp:72,73 forming reference to void
  display_expr (b*b(6)); // OK

  b*b(3,4,5,6); // OK
  b*b(4,5,6); // OK
  b*b(5,6); // OK
  b*b(6); // OK


Boost list run by bdawes at, gregod at, cpdaniel at, john at