Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2006-06-27 20:05:35


On Mon, 26 Jun 2006 11:26:57 -0400, David Abrahams
<dave_at_[hidden]> wrote:

>Gennaro Prota <gennaro_prota_at_[hidden]> 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.


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