• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/typeof.h

00001 #ifndef _typeof_h
00002 #define _typeof_h
00003 
00004 // Already included from spl/types.h, but just to be safe
00005 #include <spl/types.h>
00006 
00007 //#ifndef HAVE_TYPEOF
00008 
00009 // http://www.accu-usa.org/2000-05-Main.html
00010 //
00011 // Portable "typeof" operator and test program.
00012 //
00013 // Written by Bill Gibbons 2/18/2000
00014 //
00015 // This example uses function overloading and template specialization
00016 // to implement a restricted form of the "typeof" operator.
00017 //
00018 // Each type for which "typeof" must work must be registered with
00019 // the REGISTER_TYPEOF macro, which generates the required template
00020 // specialization and overloaded function declaration.
00021 //
00022 // An ordinal 1..n is assigned to each type and used to pass type
00023 // information by encoding the type as a number (in an array size)
00024 // and using "sizeof" to extract the value as a constant.
00025 //==================== The "typeof" machinery ====================
00026 
00038 template<int N> struct typeof_class; // no def’n, only specializations
00039 template<class T> struct WrapType { typedef T U; };
00040 
00041 #define REGISTER_TYPEOF(N,T) \
00042     template<> struct typeof_class<N > { typedef WrapType<T >::U V; }; \
00043     char (*typeof_fct(const WrapType<T >::U &))[N];
00044 
00045 #if defined(_MSC_VER)
00046 #define REGISTER_TYPEOF2(N,T,T2) \
00047     template<> struct typeof_class<N > { typedef WrapType<T,##T2 >::U V; }; \
00048     char (*typeof_fct(const WrapType<T,##T2 >::U &))[N];
00049 #else
00050 #define REGISTER_TYPEOF2(N,T,T2) \
00051     template<> struct typeof_class<N > { typedef WrapType<T,T2 >::U V; }; \
00052     char (*typeof_fct(const WrapType<T,T2 >::U &))[N];
00053 #endif
00054 
00055 #define type_of(x) typeof_class<sizeof(*typeof_fct(x))>::V
00056 
00057 //======== Registration of types to be used with "typeof" ========
00058 
00059 REGISTER_TYPEOF( 1, char );
00060 REGISTER_TYPEOF( 2, byte );
00061 REGISTER_TYPEOF( 6, int16 );
00062 REGISTER_TYPEOF( 7, uint16 );
00063 REGISTER_TYPEOF( 8, long );
00064 REGISTER_TYPEOF( 9, unsigned long );
00065 REGISTER_TYPEOF( 10, int32 );
00066 REGISTER_TYPEOF( 11, uint32 );
00067 REGISTER_TYPEOF( 12, int64 );
00068 REGISTER_TYPEOF( 13, uint64 );
00069 REGISTER_TYPEOF( 14, float32 );
00070 REGISTER_TYPEOF( 15, float64 );
00071 REGISTER_TYPEOF( 17, IHashable );
00072 REGISTER_TYPEOF( 18, IComparable );
00073 
00074 //#else
00075 //
00076 //#define REGISTER_TYPEOF(a, b)
00077 //#define REGISTER_TYPEOF2(a,b,c)
00078 //
00079 //#endif
00080 
00081 #define USER_REGISTER_TYPEOF_START 1024
00082 
00118 #define foreach(_it_,_collection_) \
00119         for(type_of(_collection_)::Iterator _it_ = _collection_.Begin();_it_.Next(); )
00120 
00124 #endif