compare_types.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 #ifndef LIBMESH_COMPARE_TYPES_H
20 #define LIBMESH_COMPARE_TYPES_H
21 
22 // System includes
23 #include <complex>
24 
25 namespace libMesh
26 {
27 
28 // Copy of boost's enable_if_c
29 
30 namespace boostcopy {
31  template <bool B, class T = void>
32  struct enable_if_c {
33  typedef T type;
34  };
35 
36  template <class T>
37  struct enable_if_c<false, T> {};
38 }
39 
40 
41 
42 // Complete list of scalar classes, needed for disambiguation
43 template <typename T>
44 struct ScalarTraits {
45  static const bool value = false;
46 };
47 
48 #define ScalarTraits_true(type) \
49 template<> \
50 struct ScalarTraits<type> { static const bool value = true; }
51 
52 ScalarTraits_true(char);
53 ScalarTraits_true(short);
55 ScalarTraits_true(long);
56 ScalarTraits_true(unsigned char);
57 ScalarTraits_true(unsigned short);
58 ScalarTraits_true(unsigned int);
59 ScalarTraits_true(unsigned long);
60 ScalarTraits_true(float);
61 ScalarTraits_true(double);
62 ScalarTraits_true(long double);
63 
64 template<typename T>
65 struct ScalarTraits<std::complex<T> > { static const bool value = ScalarTraits<T>::value; };
66 
67 
68 
69 // Operators using different but compatible types need a return value
70 // based on whichever type the other can be upconverted into. For
71 // instance, the proper return type for
72 // TypeVector<float>::operator*(double) is TypeVector<double>. In
73 // general, an operation using types S and T should return a value
74 // based on CompareTypes<S,T>::supertype
75 
76 template<typename S, typename T>
77 struct CompareTypes {
78  typedef void supertype;
79 };
80 
81 template<typename T>
82 struct CompareTypes<T, T> {
83  typedef T supertype;
84 };
85 
86 template<typename T>
87 struct CompareTypes<T, std::complex<T> > {
88  typedef std::complex<T> supertype;
89 };
90 
91 template<typename T>
92 struct CompareTypes<std::complex<T>, T> {
93  typedef std::complex<T> supertype;
94 };
95 
96 // There's got to be some magic template way to do these better - but the best
97 // thing on the net requires a bunch of Alexandrescu's code and doesn't work
98 // with older compilers
99 
100 #define CompareTypes_super(a,b,super) \
101  template<> \
102  struct CompareTypes<a, b> { \
103  typedef super supertype; \
104  }
105 
106 #define SUPERTYPE(mysub,mysuper) \
107  CompareTypes_super(mysub, mysuper, mysuper); \
108  CompareTypes_super(mysuper, mysub, mysuper); \
109  CompareTypes_super(std::complex<mysub>, mysuper, std::complex<mysuper>); \
110  CompareTypes_super(mysuper, std::complex<mysub>, std::complex<mysuper>); \
111  CompareTypes_super(mysub, std::complex<mysuper>, std::complex<mysuper>); \
112  CompareTypes_super(std::complex<mysuper>, mysub, std::complex<mysuper>); \
113  CompareTypes_super(std::complex<mysub>, std::complex<mysuper>, std::complex<mysuper>); \
114  CompareTypes_super(std::complex<mysuper>, std::complex<mysub>, std::complex<mysuper>)
115 
116 SUPERTYPE(unsigned char, short);
117 SUPERTYPE(unsigned char, int);
118 SUPERTYPE(unsigned char, float);
119 SUPERTYPE(unsigned char, double);
120 SUPERTYPE(unsigned char, long double);
121 SUPERTYPE(unsigned short, int);
122 SUPERTYPE(unsigned short, float);
123 SUPERTYPE(unsigned short, double);
124 SUPERTYPE(unsigned short, long double);
125 SUPERTYPE(unsigned int, float);
126 SUPERTYPE(unsigned int, double);
127 SUPERTYPE(unsigned int, long double);
128 SUPERTYPE(char, short);
129 SUPERTYPE(char, int);
130 SUPERTYPE(char, float);
131 SUPERTYPE(char, double);
132 SUPERTYPE(char, long double);
133 SUPERTYPE(short, int);
134 SUPERTYPE(short, float);
135 SUPERTYPE(short, double);
136 SUPERTYPE(short, long double);
137 SUPERTYPE(int, float);
138 SUPERTYPE(int, double);
139 SUPERTYPE(int, long double);
140 SUPERTYPE(float, double);
141 SUPERTYPE(float, long double);
142 SUPERTYPE(double, long double);
143 
144 #undef CompareTypes_super
145 #undef SUPERTYPE
146 
147 // gcc can't tell which of the following is the most specialized? Weak.
148 /*
149 template<typename S, typename T>
150 struct CompareTypes<std::complex<S>, std::complex<T> > {
151  typedef std::complex<typename CompareTypes<S, T>::supertype> supertype;
152 };
153 
154 template<typename S, typename T>
155 struct CompareTypes<std::complex<S>, T> {
156  typedef std::complex<typename CompareTypes<S, T>::supertype> supertype;
157 };
158 
159 template<typename S, typename T>
160 struct CompareTypes<S, std::complex<T> > {
161  typedef std::complex<typename CompareTypes<S, T>::supertype> supertype;
162 };
163 */
164 
165 } // namespace libMesh
166 
167 #endif // LIBMESH_COMPARE_TYPES_H

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:04 UTC

Hosted By:
SourceForge.net Logo