Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2006-06-28 10:08:00


On Wed, 28 Jun 2006 08:55:11 -0400, David Abrahams
<dave_at_[hidden]> wrote:

>Gennaro Prota <gennaro_prota_at_[hidden]> writes:
>
>> When you write something
>> like, for instance,
>>
>> COUNT_OF_N(3, x)
>>
>> though, it's not enough to check that x is an array. It shall be an
>> array, x[0] shall be an array, x[1] and x[2] shall be arrays. I can
>> imagine implementing it with some pp-lib iteration which automatically
>> generates
>>
>> sizeof(x[0])/sizeof(x[0][0])
>> sizeof(x[0][0])/sizeof(x[0][0][0])
>> sizeof(x[0][0][0])/sizeof(x[0][0][0][0])
>>
>> up to a given limit,
>
>So what's wrong with that?

Nothing. I didn't say it is wrong, just that I can't (still) see an
easier template-only approach for the multidimentional case. It would
help if you could post your simpler solution. With preprocessing
manipulation I agree that you can have one function to detect arrays
and do the actual computation with sizeof/sizeof.

>> but I'm not sure it can *reliably* be done with
>> templates only.
>
>You need a macro anyway, don't you?

You mean for the user? No. My idea was that the macro was provided as
a shorthand (or maybe it wasn't provided at all --to be decided) but
it was not "needed"; the user could anyway do:

  sizeof array_count<n>(arr)

and that would give the count of the (n+1)-th dimension of arr. That
should still be doable with my approach, even with VC6. Just to give
the idea, it's enough to add something like this to my previous code:

 template <std::size_t d, typename t>
 struct vc6_wrap
 {
   static t & expr;
   enum { n_1 = sizeof(expr)/sizeof(expr[0]) };
   enum { s = sizeof(array_counter<n_1>
     ::on_dim<d>::count(expr).result
     )
   };

   static char (&result) [s];

 };

 // "syntax adapter"
 template <std::size_t d, typename t>
 char(&array_count(t& a))[vc6_wrap<d, t>::s];

In my tests so far, this works:

 int main()
 {
   X a[1][2][3][4][5] = { 0 };

   char a1[sizeof array_count<0>(a)] = { 0 }; // <--
   char a2[sizeof array_count<1>(a)] = { 0 };
   char a3[sizeof array_count<2>(a)] = { 0 };
   char a4[sizeof array_count<3>(a)] = { 0 };
   char a5[sizeof array_count<4>(a)] = { 0 };

   std::cout << sizeof(a1) << ", " << sizeof(a2)
     << ", " << sizeof(a3) << ", " << sizeof(a4)
     << ", " << sizeof(a5) << '\n';

   return 0;
 }

but this doesn't:

 struct X {
   operator void*() const;
   double operator[](std::size_t) const;
 };

  X x;
  sizeof array_count<0>(x); // no failure :-(

--Gennaro.


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