// Portable "typeof" operator and test program.
//
// Written by Bill Gibbons 2/18/2000
//
// This example uses function overloading and template specialization
// to implement a restricted form of the "typeof" operator.
//
// Each type for which "typeof" must work must be registered with
// the REGISTER_TYPEOF macro, which generates the required template
// specialization and overloaded function declaration.
//
// An ordinal 1..n is assigned to each type and used to pass type
// information by encoding the type as a number (in an array size)
// and using "sizeof" to extract the value as a constant.
//==================== The "typeof" machinery ====================
template<int N> struct typeof_class; // no def’n, only
specializations
template<class T> struct WrapType { typedef T U; };
#define REGISTER_TYPEOF(N,T) \
template<> struct typeof_class<N> { typedef
WrapType<T>::U V; }; \
char (*typeof_fct(const WrapType<T>::U &))[N];
#define typeof(x) typeof_class<sizeof(*typeof_fct(x))>::V
//======== Registration of types to be used with "typeof" ========
REGISTER_TYPEOF( 1, char )
REGISTER_TYPEOF( 2, signed char )
REGISTER_TYPEOF( 3, unsigned char )
REGISTER_TYPEOF( 4, short )
REGISTER_TYPEOF( 5, unsigned short )
REGISTER_TYPEOF( 6, int )
REGISTER_TYPEOF( 7, unsigned int )
REGISTER_TYPEOF( 8, long )
REGISTER_TYPEOF( 9, unsigned long )
/* REGISTER_TYPEOF( 10, long long ) - may be unknown type */
/* REGISTER_TYPEOF( 11, unsigned long long ) - may be unknown type */
REGISTER_TYPEOF( 12, float )
REGISTER_TYPEOF( 13, double )
/* REGISTER_TYPEOF( 14, wchar_t ) - may be unknown type */
REGISTER_TYPEOF( 15, int (*)() )
//========================= Test program =========================
#include <iostream.h>
#include <typeinfo.h>
int main()
{
short a;
long b;
typeof(a) c;
typeof(b) d;
typeof(1.0) e;
typeof(main) f;
cout << "c is " << typeid(c).name()
<< '\n';
cout << "d is " << typeid(d).name()
<< '\n';
cout << "e is " << typeid(e).name()
<< '\n';
cout << "f is " << typeid(f).name()
<< '\n';
return 0;
}