|
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