compare_types.h
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 #ifndef LIBMESH_COMPARE_TYPES_H 00020 #define LIBMESH_COMPARE_TYPES_H 00021 00022 // System includes 00023 #include <complex> 00024 00025 namespace libMesh 00026 { 00027 00028 // Copy of boost's enable_if_c 00029 00030 namespace boostcopy { 00031 template <bool B, class T = void> 00032 struct enable_if_c { 00033 typedef T type; 00034 }; 00035 00036 template <class T> 00037 struct enable_if_c<false, T> {}; 00038 } 00039 00040 00041 00042 // Complete list of scalar classes, needed for disambiguation 00043 template <typename T> 00044 struct ScalarTraits { 00045 static const bool value = false; 00046 }; 00047 00048 #define ScalarTraits_true(type) \ 00049 template<> \ 00050 struct ScalarTraits<type> { static const bool value = true; } 00051 00052 ScalarTraits_true(char); 00053 ScalarTraits_true(short); 00054 ScalarTraits_true(int); 00055 ScalarTraits_true(long); 00056 ScalarTraits_true(unsigned char); 00057 ScalarTraits_true(unsigned short); 00058 ScalarTraits_true(unsigned int); 00059 ScalarTraits_true(unsigned long); 00060 ScalarTraits_true(float); 00061 ScalarTraits_true(double); 00062 ScalarTraits_true(long double); 00063 00064 template<typename T> 00065 struct ScalarTraits<std::complex<T> > { static const bool value = ScalarTraits<T>::value; }; 00066 00067 00068 00069 // Operators using different but compatible types need a return value 00070 // based on whichever type the other can be upconverted into. For 00071 // instance, the proper return type for 00072 // TypeVector<float>::operator*(double) is TypeVector<double>. In 00073 // general, an operation using types S and T should return a value 00074 // based on CompareTypes<S,T>::supertype 00075 00076 template<typename S, typename T> 00077 struct CompareTypes { 00078 typedef void supertype; 00079 }; 00080 00081 template<typename T> 00082 struct CompareTypes<T, T> { 00083 typedef T supertype; 00084 }; 00085 00086 template<typename T> 00087 struct CompareTypes<T, std::complex<T> > { 00088 typedef std::complex<T> supertype; 00089 }; 00090 00091 template<typename T> 00092 struct CompareTypes<std::complex<T>, T> { 00093 typedef std::complex<T> supertype; 00094 }; 00095 00096 // There's got to be some magic template way to do these better - but the best 00097 // thing on the net requires a bunch of Alexandrescu's code and doesn't work 00098 // with older compilers 00099 00100 #define CompareTypes_super(a,b,super) \ 00101 template<> \ 00102 struct CompareTypes<a, b> { \ 00103 typedef super supertype; \ 00104 } 00105 00106 #define SUPERTYPE(mysub,mysuper) \ 00107 CompareTypes_super(mysub, mysuper, mysuper); \ 00108 CompareTypes_super(mysuper, mysub, mysuper); \ 00109 CompareTypes_super(std::complex<mysub>, mysuper, std::complex<mysuper>); \ 00110 CompareTypes_super(mysuper, std::complex<mysub>, std::complex<mysuper>); \ 00111 CompareTypes_super(mysub, std::complex<mysuper>, std::complex<mysuper>); \ 00112 CompareTypes_super(std::complex<mysuper>, mysub, std::complex<mysuper>); \ 00113 CompareTypes_super(std::complex<mysub>, std::complex<mysuper>, std::complex<mysuper>); \ 00114 CompareTypes_super(std::complex<mysuper>, std::complex<mysub>, std::complex<mysuper>) 00115 00116 SUPERTYPE(unsigned char, short); 00117 SUPERTYPE(unsigned char, int); 00118 SUPERTYPE(unsigned char, float); 00119 SUPERTYPE(unsigned char, double); 00120 SUPERTYPE(unsigned char, long double); 00121 SUPERTYPE(unsigned short, int); 00122 SUPERTYPE(unsigned short, float); 00123 SUPERTYPE(unsigned short, double); 00124 SUPERTYPE(unsigned short, long double); 00125 SUPERTYPE(unsigned int, float); 00126 SUPERTYPE(unsigned int, double); 00127 SUPERTYPE(unsigned int, long double); 00128 SUPERTYPE(char, short); 00129 SUPERTYPE(char, int); 00130 SUPERTYPE(char, float); 00131 SUPERTYPE(char, double); 00132 SUPERTYPE(char, long double); 00133 SUPERTYPE(short, int); 00134 SUPERTYPE(short, float); 00135 SUPERTYPE(short, double); 00136 SUPERTYPE(short, long double); 00137 SUPERTYPE(int, float); 00138 SUPERTYPE(int, double); 00139 SUPERTYPE(int, long double); 00140 SUPERTYPE(float, double); 00141 SUPERTYPE(float, long double); 00142 SUPERTYPE(double, long double); 00143 00144 // gcc can't tell which of the following is the most specialized? Weak. 00145 /* 00146 template<typename S, typename T> 00147 struct CompareTypes<std::complex<S>, std::complex<T> > { 00148 typedef std::complex<typename CompareTypes<S, T>::supertype> supertype; 00149 }; 00150 00151 template<typename S, typename T> 00152 struct CompareTypes<std::complex<S>, T> { 00153 typedef std::complex<typename CompareTypes<S, T>::supertype> supertype; 00154 }; 00155 00156 template<typename S, typename T> 00157 struct CompareTypes<S, std::complex<T> > { 00158 typedef std::complex<typename CompareTypes<S, T>::supertype> supertype; 00159 }; 00160 */ 00161 00162 } // namespace libMesh 00163 00164 #endif // LIBMESH_COMPARE_TYPES_H
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:45 UTC
Hosted By: