|
ORTS
|
00001 #ifndef Typeof_H 00002 #define Typeof_H 00003 00004 // $Id: Typeof.H 6832 2008-03-04 23:26:18Z furtak $ 00005 00006 // This is an ORTS file (c) Bill Gibbons, licensed under the GPL 00007 00008 // Portable "typeof" operator and test program. 00009 // 00010 // Written by Bill Gibbons 2/18/2000 00011 // 00012 // This example uses function overloading and template specialization 00013 // to implement a restricted form of the "typeof" operator. 00014 // 00015 // Each type for which "typeof" must work must be registered with 00016 // the REGISTER_TYPEOF macro, which generates the required template 00017 // specialization and overloaded function declaration. 00018 // 00019 // An ordinal 1..n is assigned to each type and used to pass type 00020 // information by encoding the type as a number (in an array size) 00021 // and using "sizeof" to extract the value as a constant. 00022 00023 #if !HAS_TYPEOF 00024 00025 #include "Global.H" 00026 00027 //==================== The "typeof" machinery ==================== 00028 00029 template<int N> struct typeof_class; // no def'n, only specializations 00030 template<class T> struct WrapType { typedef T U; }; 00031 00032 #define REGISTER_TYPEOF(N,T) \ 00033 template<> struct typeof_class<N> { typedef WrapType< T >::U V; }; \ 00034 char (*typeof_fct(const WrapType< T >::U &))[N]; 00035 00036 #define REGISTER_TYPEOF2(N,T1,T2) \ 00037 template<> struct typeof_class<N> { typedef WrapType< T1,T2 >::U V; }; \ 00038 char (*typeof_fct(const WrapType< T1,T2 >::U &))[N]; 00039 00040 #define typeof(x) typeof_class<sizeof(*typeof_fct(x))>::V 00041 00042 //======== Registration of types to be used with "typeof" ======== 00043 00044 REGISTER_TYPEOF(1, char ); 00045 REGISTER_TYPEOF(2, signed char ); 00046 REGISTER_TYPEOF(3, unsigned char ); 00047 REGISTER_TYPEOF(4, short ); 00048 REGISTER_TYPEOF(5, unsigned short ); 00049 REGISTER_TYPEOF(6, int ); 00050 REGISTER_TYPEOF(7, unsigned int ); 00051 REGISTER_TYPEOF(8, long ); 00052 REGISTER_TYPEOF(9, unsigned long ); 00053 REGISTER_TYPEOF(10, long long ) // may be unknown type 00054 REGISTER_TYPEOF(11, unsigned long long ) // may be unknown type 00055 REGISTER_TYPEOF(12, float ); 00056 REGISTER_TYPEOF(13, double ); 00057 //REGISTER_TYPEOF(14, wchar_t ) // may be unknown type 00058 REGISTER_TYPEOF(15, std::string); 00059 REGISTER_TYPEOF(16, std::string::iterator); 00060 REGISTER_TYPEOF(17, std::string::const_iterator); 00061 00062 REGISTER_TYPEOF(30, Vector<sint4>::iterator ); 00063 REGISTER_TYPEOF(31, Vector<sint4>::const_iterator ); 00064 REGISTER_TYPEOF(32, Vector<uint4>::iterator ); 00065 REGISTER_TYPEOF(33, Vector<uint4>::const_iterator ); 00066 REGISTER_TYPEOF(34, Vector<uint4*>::iterator ); 00067 REGISTER_TYPEOF(35, Vector<uint4*>::const_iterator ); 00068 REGISTER_TYPEOF(36, Vector<std::string>::iterator ); 00069 REGISTER_TYPEOF(37, Vector<std::string>::const_iterator ); 00070 00071 REGISTER_TYPEOF2(500, std::map<std::string, sint4>::iterator ); 00072 REGISTER_TYPEOF2(501, std::map<std::string, sint4>::const_iterator ); 00073 REGISTER_TYPEOF2(502, std::map<std::string, uint4>::iterator ); 00074 REGISTER_TYPEOF2(503, std::map<std::string, uint4>::const_iterator ); 00075 REGISTER_TYPEOF2(504, std::map<const std::string, sint4>::iterator ); 00076 REGISTER_TYPEOF2(505, std::map<const std::string, sint4>::const_iterator ); 00077 REGISTER_TYPEOF2(506, std::map<const std::string, uint4>::iterator ); 00078 REGISTER_TYPEOF2(507, std::map<const std::string, uint4>::const_iterator ); 00079 REGISTER_TYPEOF2(508, std::map<std::string, std::string>::iterator ); 00080 REGISTER_TYPEOF2(509, std::map<std::string, std::string>::const_iterator ); 00081 00082 00083 REGISTER_TYPEOF(510, Vector< Vector<sint4> >::iterator ); 00084 REGISTER_TYPEOF(511, Vector< Vector<sint4> >::const_iterator ); 00085 REGISTER_TYPEOF(512, Vector< Vector<uint4> >::iterator ); 00086 REGISTER_TYPEOF(513, Vector< Vector<uint4> >::const_iterator ); 00087 00088 REGISTER_TYPEOF(100, std::set<sint4>::iterator ); 00089 REGISTER_TYPEOF(102, std::set<std::string>::iterator ); 00090 REGISTER_TYPEOF(103, std::set<std::string>::const_iterator ); 00091 //REGISTER_TYPEOF(101, std::set<sint4>::const_iterator ); 00092 00093 #else 00094 00095 #define REGISTER_TYPEOF(N,T) 00096 #define REGISTER_TYPEOF2(N,T1,T2) 00097 00098 #endif 00099 00100 #endif 00101