glucat  0.12.0
promotion.h
Go to the documentation of this file.
1 #ifndef _GLUCAT_PROMOTION_H
2 #define _GLUCAT_PROMOTION_H
3 /***************************************************************************
4  GluCat : Generic library of universal Clifford algebra templates
5  promotion.h : Define promotion and demotion for specific scalar types
6  -------------------
7  begin : 2021-11-13
8  copyright : (C) 2021 by Paul C. Leopardi
9  ***************************************************************************
10 
11  This library is free software: you can redistribute it and/or modify
12  it under the terms of the GNU Lesser General Public License as published
13  by the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public License
22  along with this library. If not, see <http://www.gnu.org/licenses/>.
23 
24  ***************************************************************************
25  This library is based on a prototype written by Arvind Raja and was
26  licensed under the LGPL with permission of the author. See Arvind Raja,
27  "Object-oriented implementations of Clifford algebras in C++: a prototype",
28  in Ablamowicz, Lounesto and Parra (eds.)
29  "Clifford algebras with numeric and symbolic computations, Birkhauser, 1996."
30  ***************************************************************************
31  See also Arvind Raja's original header comments and references in glucat.h
32  ***************************************************************************/
33 
34 #include "glucat/global.h"
35 #include "glucat/scalar.h"
36 #include "glucat/qd.h"
37 
38 #include <cfloat>
39 #include <limits>
40 
41 #if defined(_GLUCAT_USE_QD)
42 # include <qd/qd_real.h>
43 #endif
44 
45 namespace glucat
46 {
48  // Reference: [AA], 2.4, p. 30-31
49 
50 #if !defined(_GLUCAT_USE_QD) || !defined(QD_API)
51 
52 # if DBL_MANT_DIG < LDBL_MANT_DIG
53 
55  template<>
56  struct
57  numeric_traits<double>::
58  promoted {using type = long double;};
59 
61  template<>
62  struct
63  numeric_traits<long double>::
64  demoted {using type = double;};
65 
66 # else
67 
69  template<>
70  struct
72  promoted {using type = double;};
73 
75  template<>
76  struct
78  demoted {using type = float;};
79 
80 # endif // DBL_MANT_DIG < LDBL_MANT_DIG
81 
83  template<>
84  struct
86  promoted {using type = long double;};
87 
88 #else
89 
90 # if (DBL_MANT_DIG < LDBL_MANT_DIG) && (LDBL_MANT_DIG < DBL_MANT_DIG*2)
91 
93  template<>
94  struct
96  promoted {using type = long double;};
97 
99  template<>
100  struct
102  demoted {using type = double;};
103 
105  template<>
106  struct
107  numeric_traits<long double>::
108  promoted {using type = dd_real;};
109 
111  template<>
112  struct
113  numeric_traits<dd_real>::
114  demoted {using type = long double;};
115 
117  template<>
118  struct
119  numeric_traits<dd_real>::
120  promoted {using type = qd_real;};
121 
123  template<>
124  struct
125  numeric_traits<qd_real>::
126  demoted {using type = dd_real;};
127 
128 # elif (LDBL_MANT_DIG < DBL_MANT_DIG*2)
129 
131  template<>
132  struct
133  numeric_traits<double>::
134  promoted {using type = dd_real;};
135 
137  template<>
138  struct
139  numeric_traits<long double>::
140  demoted {using type = float;};
141 
143  template<>
144  struct
145  numeric_traits<long double>::
146  promoted {using type = dd_real;};
147 
149  template<>
150  struct
151  numeric_traits<dd_real>::
152  demoted {using type = double;};
153 
155  template<>
156  struct
157  numeric_traits<dd_real>::
158  promoted {using type = qd_real;};
159 
161  template<>
162  struct
163  numeric_traits<qd_real>::
164  demoted {using type = dd_real;};
165 
166 # else
167 
169  template<>
170  struct
171  numeric_traits<double>::
172  promoted {using type = dd_real;};
173 
175  template<>
176  struct
177  numeric_traits<dd_real>::
178  demoted {using type = double;};
179 
181  template<>
182  struct
183  numeric_traits<dd_real>::
184  promoted {using type = long double;};
185 
187  template<>
188  struct
189  numeric_traits<long double>::
190  demoted {using type = dd_real;};
191 
193  template<>
194  struct
195  numeric_traits<long double>::
196  promoted {using type = qd_real;};
197 
199  template<>
200  struct
201  numeric_traits<qd_real>::
202  demoted {using type = long double;};
203 
204 # endif // (DBL_MANT_DIG < LDBL_MANT_DIG) && (LDBL_MANT_DIG < DBL_MANT_DIG*2)
205 
207  template<>
208  struct
209  numeric_traits<qd_real>::
210  promoted {using type = qd_real;};
211 
212 #endif // !defined(_GLUCAT_USE_QD) || !defined(QD_API)
213 
214 } // namespace glucat
215 
216 #endif // _GLUCAT_PROMOTION_H
Extra traits which extend numeric limits.
Definition: scalar.h:47