
On Mon, 26 Jun 2006 11:26:57 -0400, David Abrahams <dave@boost-consulting.com> wrote:
Gennaro Prota <gennaro_prota@yahoo.com> writes:
[...]
template <std::size_t n> struct counter { enum { n = n }; // yep :)
template <typename t> static char(&count(t(*)[n]))[n];
};
#define COUNT_OF(x) \ (sizeof counter<(sizeof x / sizeof x[0])>::count(&x))
PS: note the enum!
Wow, great! That trick is a new one to me.
I'd say the more you can invent non-standard code the more chances you have to make VC6 "work" :) Of course the "n=n" above was just a whim on my part: if one uses two different names, such as "n" and "nn", the code is standard compliant. And you can also use directly a reference: t(&)[n]. So, not as bad as I was expecting. The real somersaults begin when you want the multidimensional case :) Here's what came out: template <std::size_t n> struct array_counter { enum { nn = n }; template <std::size_t d> struct dim { template <typename t, std::size_t sz> struct wrap { static t & expr; enum { n_ = sizeof(expr)/sizeof(expr[0]) }; enum { s = sizeof(array_counter<n_> ::dim<d-1>::count(expr).sizer ) }; char sizer [s]; }; template<typename t> static wrap<t, nn> count( t(&)[nn] ); }; template <> struct dim<0> { template <typename t, std::size_t sz> struct wrap { char sizer[sz]; }; template<typename t> static wrap<t, nn> count( t(&)[nn] ); }; }; #define COUNT_OF_N(d, x) \ sizeof(array_counter<sizeof(x)/sizeof(x[0])>::dim<d>::count(x).sizer) #include <ostream> #include <iostream> int main() { char a[1][2][3][4][5][6][7][8][9]; char a1[COUNT_OF_N(0, a)]; char a2[COUNT_OF_N(1, a)]; char a3[COUNT_OF_N(2, a)]; char a4[COUNT_OF_N(3, a)]; char a5[COUNT_OF_N(4, a)]; char a6[COUNT_OF_N(5, a)]; char a7[COUNT_OF_N(6, a)]; char a8[COUNT_OF_N(7, a)]; std::cout << sizeof(a1) << ", " << sizeof(a2) << ", " << sizeof(a3) << ", " << sizeof(a4) << ", " << sizeof(a5) << ", " << sizeof(a6) << ", " << sizeof(a7) << ", " << sizeof(a8) << '\n'; return 0; } ___ ___ PS: May Bjarne forgive us... ___ ___ --Gennaro.