00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_meta_programming_hh
00025 #define PPL_meta_programming_hh 1
00026
00027 #include <gmpxx.h>
00028
00029 namespace Parma_Polyhedra_Library {
00030
00031 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00032
00041 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00042 #define const_bool_nodef(name, value) \
00043 enum anonymous_enum_ ## name { name = (value) }
00044
00045 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00046
00055 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00056 #define const_int_nodef(name, value) \
00057 enum anonymous_enum_ ## name { name = (value) }
00058
00059 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00060
00070 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00071 #define const_value_nodef(type, name, value) \
00072 static type name() { \
00073 return value; \
00074 }
00075
00076 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00077
00087 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00088 #define const_ref_nodef(type, name, value) \
00089 static const type& name() { \
00090 static type name(value); \
00091 return name; \
00092 }
00093
00094 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00095
00101 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00102 template <bool b>
00103 struct Compile_Time_Check;
00104
00105 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00106
00113 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00114 template <>
00115 struct Compile_Time_Check<true> {
00116 };
00117
00118 #define PPL_COMPILE_TIME_CHECK_NAME(suffix) compile_time_check_ ## suffix
00119 #define PPL_COMPILE_TIME_CHECK_AUX(e, suffix) \
00120 enum anonymous_enum_compile_time_check_ ## suffix { \
00121 \
00122 PPL_COMPILE_TIME_CHECK_NAME(suffix) \
00123 = sizeof(Parma_Polyhedra_Library:: \
00124 Compile_Time_Check<static_cast<bool>(e)>) \
00125 }
00126
00127 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00128
00133 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00134 #define PPL_COMPILE_TIME_CHECK(e, msg) PPL_COMPILE_TIME_CHECK_AUX(e, __LINE__)
00135
00136 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00137
00142 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00143 template <bool b>
00144 struct Bool {
00145 enum anonymous_enum {
00146 value = b
00147 };
00148 };
00149
00150 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00151
00156 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00157 struct True : public Bool<true> {
00158 };
00159
00160 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00161
00166 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00167 struct False : public Bool<false> {
00168 };
00169
00170 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00171
00178 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00179 template <typename T1, typename T2>
00180 struct Is_Same : public False {
00181 };
00182
00183 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00184
00191 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00192 template <typename T>
00193 struct Is_Same<T, T> : public True {
00194 };
00195
00196 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00197
00222 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00223 template <typename Base, typename Derived>
00224 struct Is_Same_Or_Derived {
00225
00226 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00227
00228 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00229 struct Any {
00231 template <typename T>
00232 Any(const T&);
00233 };
00234
00236 static char func(const Base&);
00237
00239 static double func(Any);
00240
00242 static const Derived& derived_object();
00243
00244 PPL_COMPILE_TIME_CHECK(sizeof(char) != sizeof(double),
00245 "architecture with sizeof(char) == sizeof(double)"
00246 " (!?)");
00247
00248 enum anonymous_enum {
00256 value = (sizeof(func(derived_object())) == sizeof(char))
00257 };
00258 };
00259
00260 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00261
00269 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00270 template <bool b, typename T = void>
00271 struct Enable_If {
00272 };
00273
00274 template <typename Type, Type, typename T = void>
00275 struct Enable_If_Is {
00276 typedef T type;
00277 };
00278
00279 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00280
00304 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00305 template <typename T>
00306 struct Enable_If<true, T> {
00307 typedef T type;
00308 };
00309
00310 template <typename T>
00311 struct Is_Native : public False {
00312 };
00313
00314 template <> struct Is_Native<char> : public True { };
00315 template <> struct Is_Native<signed char> : public True { };
00316 template <> struct Is_Native<signed short> : public True { };
00317 template <> struct Is_Native<signed int> : public True { };
00318 template <> struct Is_Native<signed long> : public True { };
00319 template <> struct Is_Native<signed long long> : public True { };
00320 template <> struct Is_Native<unsigned char> : public True { };
00321 template <> struct Is_Native<unsigned short> : public True { };
00322 template <> struct Is_Native<unsigned int> : public True { };
00323 template <> struct Is_Native<unsigned long> : public True { };
00324 template <> struct Is_Native<unsigned long long> : public True { };
00325
00326 #if PPL_SUPPORTED_FLOAT
00327 template <> struct Is_Native<float> : public True { };
00328 #endif
00329 #if PPL_SUPPORTED_DOUBLE
00330 template <> struct Is_Native<double> : public True { };
00331 #endif
00332 #if PPL_SUPPORTED_LONG_DOUBLE
00333 template <> struct Is_Native<long double> : public True { };
00334 #endif
00335
00336 template <> struct Is_Native<mpz_class> : public True { };
00337
00338 template <> struct Is_Native<mpq_class> : public True { };
00339
00340 }
00341
00342 #endif // !defined(PPL_meta_programming_hh)