Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2006-06-29 11:25:55


On Wed, 28 Jun 2006 23:38:25 -0400, David Abrahams
<dave_at_[hidden]> wrote:

>I never solved that problem... until today. The enclosed works. It
>could probably be considerably simplified if you untwist the logic a
>bit. In particular, you could probably find a way to get rid of
>remove_bounds. The basic idea here is that the only way to force an
>error in some contexts, with vc6, is at the top level, with
>eval0<...>::not_array being a nonexistent type.

Yes. As you say, "in some contexts". I realize that this is more an
issue of compiler workarounds than template metaprogramming per se. I
mean: you can get rid of remove_bounds<> and/or implement your
is_array with something like this (not thoroughly tested):

 namespace xyz {

   // my usual conversion burning -gps
   struct burn { burn(const volatile void *); };

   template <typename t>
   void is_array (t*, t* const volatile *);

   char is_array (burn ...);

 }

Now,

 sizeof(xyz::is_array(e, &e))

should either produce an error or yield 1 (I may be missing something
and the above might not work at all, but that's not the point). This
is basically what I had used in my pp based solution, as, building
upon, it you can easily generate for instance

 1*1*1* sizeof(a[0][0]) / sizeof(a[0][0][0])

The point is: will xyz::is_array() do its job correctly in complex
metaprogramming invocations? If you prefer "in all contexts"? A look
at the mpl sources shows that they really make somersaults (well, let
me use this word again :)) to hide compiler idiosyncracies (certainly
our is_array<> is nothing as simple as the above).

So, to make a long story short, I'm a bit reluctant to remove
array_bounds<> or mpl::eval_if_c or anything else, because they are a
thoroughly tested ground to build upon for broken compilers. And then
all this *is* for broken compilers, as for conforming ones the whole
utility is a few lines of code (my initial attachment).

I'm refining your solution a bit and writing more tests, then if we
agree on this I'll ask for a fast-track review. In the meantime I'd
like to ask one question:

* Any reason why you used mpl::identity<empty> instead
  of mpl::identity<>? does the latter break on some known
  compiler? I'm asking because it could be the reverse and
  that using the default (i.e. boost::mpl::na) is the
  preferred/most reliable way.

  My guess is that you just wanted to have a clearer
  diagnostic message, but I wanted to ask.

--Gennaro.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk