|
PPL
0.12.1
|
00001 /* Metaprogramming utilities. 00002 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 00003 Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com) 00004 00005 This file is part of the Parma Polyhedra Library (PPL). 00006 00007 The PPL is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 The PPL is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software Foundation, 00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 00020 00021 For the most up-to-date information see the Parma Polyhedra Library 00022 site: http://bugseng.com/products/ppl/ . */ 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 const_bool_value_ ## name { PPL_U(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 { PPL_U(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 PPL_U(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& PPL_U(name)() { \ 00090 static type PPL_U(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 /* If e evaluates to false, then the sizeof cannot be compiled. */ \ 00122 PPL_COMPILE_TIME_CHECK_NAME(suffix) \ 00123 = sizeof(Parma_Polyhedra_Library::Compile_Time_Check<(e)>) \ 00124 } 00125 00126 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00127 00132 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00133 #define PPL_COMPILE_TIME_CHECK(e, msg) PPL_COMPILE_TIME_CHECK_AUX(e, __LINE__) 00134 00135 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00136 00141 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00142 template <bool b> 00143 struct Bool { 00144 enum const_bool_value { 00145 value = b 00146 }; 00147 }; 00148 00149 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00150 00155 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00156 struct True : public Bool<true> { 00157 }; 00158 00159 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00160 00165 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00166 struct False : public Bool<false> { 00167 }; 00168 00169 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00170 00177 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00178 template <typename T1, typename T2> 00179 struct Is_Same : public False { 00180 }; 00181 00182 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00183 00190 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00191 template <typename T> 00192 struct Is_Same<T, T> : public True { 00193 }; 00194 00195 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00196 00221 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00222 template <typename Base, typename Derived> 00223 struct Is_Same_Or_Derived { 00224 00225 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00226 00227 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00228 struct Any { 00230 template <typename T> 00231 Any(const T&); 00232 }; 00233 00235 static char func(const Base&); 00236 00238 static double func(Any); 00239 00241 static const Derived& derived_object(); 00242 00243 PPL_COMPILE_TIME_CHECK(sizeof(char) != sizeof(double), 00244 "architecture with sizeof(char) == sizeof(double)" 00245 " (!?)"); 00246 00247 enum const_bool_value { 00255 value = (sizeof(func(derived_object())) == sizeof(char)) 00256 }; 00257 }; 00258 00259 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00260 00268 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00269 template <bool b, typename T = void> 00270 struct Enable_If { 00271 }; 00272 00273 template <typename Type, Type, typename T = void> 00274 struct Enable_If_Is { 00275 typedef T type; 00276 }; 00277 00278 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00279 00303 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 00304 template <typename T> 00305 struct Enable_If<true, T> { 00306 typedef T type; 00307 }; 00308 00309 template <typename T> 00310 struct Is_Native : public False { 00311 }; 00312 00313 template <> struct Is_Native<char> : public True { }; 00314 template <> struct Is_Native<signed char> : public True { }; 00315 template <> struct Is_Native<signed short> : public True { }; 00316 template <> struct Is_Native<signed int> : public True { }; 00317 template <> struct Is_Native<signed long> : public True { }; 00318 template <> struct Is_Native<signed long long> : public True { }; 00319 template <> struct Is_Native<unsigned char> : public True { }; 00320 template <> struct Is_Native<unsigned short> : public True { }; 00321 template <> struct Is_Native<unsigned int> : public True { }; 00322 template <> struct Is_Native<unsigned long> : public True { }; 00323 template <> struct Is_Native<unsigned long long> : public True { }; 00324 00325 #if PPL_SUPPORTED_FLOAT 00326 template <> struct Is_Native<float> : public True { }; 00327 #endif 00328 #if PPL_SUPPORTED_DOUBLE 00329 template <> struct Is_Native<double> : public True { }; 00330 #endif 00331 #if PPL_SUPPORTED_LONG_DOUBLE 00332 template <> struct Is_Native<long double> : public True { }; 00333 #endif 00334 00335 template <> struct Is_Native<mpz_class> : public True { }; 00336 00337 template <> struct Is_Native<mpq_class> : public True { }; 00338 00339 } // namespace Parma_Polyhedra_Library 00340 00341 #endif // !defined(PPL_meta_programming_hh)