#include #include #include #include #include #include using namespace boost; struct empty {}; template struct dimension0 { static A a; enum {e = sizeof(a[0])}; typedef char (&type)[sizeof(A)/e]; }; template struct eval0 { typedef typename T not_array; }; template <> struct eval0 {}; template < std::size_t d , class A > struct legal_array_counter; template < std::size_t d , class A > struct array_counter { enum { legal = is_array::value }; BOOST_MPL_ASSERT((is_array)); typedef typename mpl::eval_if_c< !legal , mpl::identity , legal_array_counter >::type type; }; template < std::size_t d , class A > struct subarray_counter { enum { s = sizeof legal_array_counter::type }; typedef char (&type)[s+is_array::value]; static type x; }; template struct strip { enum { n_ = n }; template static subarray_counter f( E(&)[n_] ); }; template typename eval0< typename array_counter::type >::not_array dimension(A& a); template struct charray1 { enum {n = n_}; typedef char (&type)[n]; }; template <> struct charray1<-1> { typedef void type; }; template < std::size_t d_ , class A > struct next_array_counter { enum {d = d_}; static A a; enum {n = sizeof(A)/sizeof(a[0])}; enum {s = sizeof( strip::f(a).x ) -1}; typedef typename charray1::type type; }; template < std::size_t d_ , class A > struct legal_array_counter { enum { d = d_ }; typedef typename mpl::eval_if_c< d , next_array_counter , dimension0 >::type type; static type x; }; struct X { operator void*() const; double operator[](std::size_t) const; }; template struct whatis {}; int main() { typedef X xt[1][2][3][4][5]; xt a; (void)a; char a1[sizeof dimension<0>(a)] = { 0 }; // <-- char a2[sizeof dimension<1>(a)] = { 0 }; char a3[sizeof dimension<2>(a)] = { 0 }; char a4[sizeof dimension<3>(a)] = { 0 }; char a5[sizeof dimension<4>(a)] = { 0 }; #ifdef FAIL char a6[sizeof dimension<5>(a)] = { 0 }; #endif std::cout << sizeof(a1) << ", " << sizeof(a2) << ", " << sizeof(a3) << ", " << sizeof(a4) << ", " << sizeof(a5) << '\n'; return 0; }