Computing the number of dimensions of an array, vector, or deque
The following program demonstrates two different ways of computing the number of dimensions
of a variable or data type. The first method, implemented using a template function signature called
"dims(x)", is used to determine the number of dimensions of (a possibly multi-dimensional) array.
You basically call it like this:
int array[4][5][6];
int dimensions = dims(array);
// dimensions now contains 3.
Or like this:
vector< vector<int [4][5][6]> > flarg;
int dimensions = dims(flarg);
// dimensions now contains 5.
In both cases, the dims() function computes the number of dimensions of the variable
passed into it by const &.
Alternatively, if you need the information at compile time, you can use the other
mechanism: template< class T> struct DimCountClass{}. This mechanism uses template
specialization to create data types (classes) which have a member called "count" which
is the number of dimensions of class T passed in.
There are some advantages for both approaches. However, if you need to declare an array
whose size is the number of dimensions of some other type, then you will have to use
the DimCountClass mechanism. For example:
typedef vector< vector<int [4][5][6]> > flargType;
flargType flarg;
static int flargDimInfo[ DimCountClass< flargType >::count ];
// flargDimInfo has 5 elements.
And finally, here is the code that implements the dims() function and the DimCountClass
discussed above:
#include
#include
using namespace std;
inline int dimCount(void const *)
//
// compute the number of dimensions of non-arrays
//
{
return 0;
}
template
inline int dimCount(T (*ptr)[N])
//
// return the number of dimensions of an array for which you have a
// pointer -- note the input parameter must be the address of the array
// not the address of the first element there of:
//
// this: &array
// not: &array[0]
//
// There's probably a way to do this entirely at compile time -- but I'm too
// lazy right now.
{
T* p(0);
return 1 + dimCount(p);
}
template
inline int dimCount( std::vector< T > const *)
{
T* p(0);
return 1 + dimCount(p);
}
template
inline int dims(T const &x)
//
// wrapper for dimCount that makes the interface cleaner
//
{
return dimCount(&x);
}
template
struct DimCountClass
//
// This class' sole purpose is to define a value specific to its
// template parameter -- the value, held in member count, is the
// number of array dimension that the T parameter has. By default
// the answer is 0 -- unless a template specialization is made for
// a given container, it will be assumed that the class T, is not
// an array or container.
//
{
enum constants
{
count=COUNT
};
};
template
struct DimCountClass< vector >
//
// This specialization of DimCountClass, documented above, defines
// the number of dimensions for vector objects -- which is to say,
// one more than the number of dimensions of T
//
{
enum constants
{
count=1+DimCountClass< T >::count
};
};
template
struct DimCountClass< T[N] >
//
// This specialization of DimCountClass, documented above, defines
// the number of dimensions for builtin arrays -- which is 1 more than
// the number of dimensions of class T objects. This also works for
// multi-dimensional arrays.
//
{
enum constants
{
count=1+DimCountClass< T >::count
};
};
int main()
{
int s;
int a1d[4];
int a2d[3][5];
int a3d[2][7][9];
cout << "array dims: " << dims(s)
<< ", " << dims(a1d)
<< ", " << dims(a2d)
<< ", " << dims(a3d)
<< endl;
vector vi0;
vector vi1;
vector vi2;
vector > vi3;
cout << "vector dims: " << dims(vi0)
<< ", " << dims(vi1)
<< ", " << dims(vi2)
<< ", " << dims(vi3)
<< endl;
cout << "comptime dims: " << DimCountClass::count
<< ", " << DimCountClass >::count
<< ", " << DimCountClass< int [3][5] >::count
<< ", " << DimCountClass< vector< int [3][5] > >::count
<< endl;
static int dimInfo[ DimCountClass< vector< int [3][5] > >::count ];
cout << "array[ dims ]: " << sizeof(dimInfo) / sizeof(int) << endl;
}