PPL  0.12.1
meta_programming.hh
Go to the documentation of this file.
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)