opm-common
quad.hpp
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
29 #if !defined OPM_COMMON_QUAD_HPP && HAVE_QUAD
30 #define OPM_COMMON_QUAD_HPP
31 
32 #include <cmath>
33 #include <complex>
34 #include <iostream>
35 #include <limits>
36 #include <numbers>
37 #include <stdexcept>
38 #include <string>
39 #include <type_traits>
40 
41 extern "C" {
42 #include <quadmath.h>
43 }
44 
45 typedef __float128 quad;
46 
47 namespace std {
48 
49 #if !LIMITS_HAS_QUAD
50 // provide the numeric limits for the quad precision type
51 template <>
52 class numeric_limits<quad>
53 {
54 public:
55  static constexpr bool is_specialized = true;
56 
57  static constexpr quad min() throw()
58  { return FLT128_MIN; }
59  static constexpr quad max() throw()
60  { return FLT128_MAX; }
61 
62  // number of bits in mantissa
63  static constexpr int digits = FLT128_MANT_DIG;
64  // number of decimal digits
65  static constexpr int digits10 = FLT128_DIG;
66  static constexpr bool is_signed = true;
67  static constexpr bool is_integer = false;
68  static constexpr bool is_exact = false;
69  static constexpr int radix = 0;
70  static constexpr quad epsilon() throw()
71  { return FLT128_EPSILON; }
72  static constexpr quad round_error() throw()
73  { return 0.5; }
74 
75  static constexpr int min_exponent = FLT128_MIN_EXP;
76  static constexpr int min_exponent10 = FLT128_MIN_10_EXP;
77  static constexpr int max_exponent = FLT128_MAX_EXP;
78  static constexpr int max_exponent10 = FLT128_MAX_10_EXP;
79 
80  static constexpr bool has_infinity = true;
81  static constexpr bool has_quiet_NaN = true;
82  static constexpr bool has_signaling_NaN = true;
83  static constexpr float_denorm_style has_denorm = denorm_present;
84  static constexpr bool has_denorm_loss = false;
85  static constexpr quad infinity() throw()
86  { return __builtin_huge_valq(); }
87  static constexpr quad quiet_NaN() throw()
88  { return __builtin_nan(""); }
89  static constexpr quad signaling_NaN() throw()
90  { return __builtin_nans(""); }
91  static constexpr quad denorm_min() throw()
92  { return FLT128_DENORM_MIN; }
93 
94  static constexpr bool is_iec559 = true;
95  static constexpr bool is_bounded = true;
96  static constexpr bool is_modulo = false;
97 
98  static constexpr bool traps = std::numeric_limits<double>::traps;
99  static constexpr bool tinyness_before = std::numeric_limits<double>::tinyness_before;
100  static constexpr float_round_style round_style = round_to_nearest;
101 };
102 #endif // LIMITS_HAS_QUAD
103 
104 // provide some type traits for the quadruple precision type
105 template <>
106 struct is_floating_point<quad>
107  : public integral_constant<bool, true>
108 {};
109 
110 template <>
111 struct is_arithmetic<quad>
112  : public integral_constant<bool, true>
113 {};
114 
115 template <>
116 struct is_fundamental<quad>
117  : public integral_constant<bool, true>
118 {};
119 
120 template <>
121 struct is_scalar<quad>
122  : public integral_constant<bool, true>
123 {};
124 
125 #if __cplusplus < 202002L
126 template <>
127 struct is_pod<quad>
128  : public integral_constant<bool, true>
129 {};
130 #endif
131 
132 template <>
133 struct is_signed<quad>
134  : public integral_constant<bool, true>
135 {};
136 
137 
138 template <>
139 struct is_standard_layout<quad>
140  : public integral_constant<bool, true>
141 {};
142 
143 template <>
144 struct is_trivial<quad>
145  : public integral_constant<bool, true>
146 {};
147 
148 /*
149 template <>
150 struct is_trivially_copyable<quad>
151  : public integral_constant<bool, true>
152 {};
153 */
154 
155 template <class OtherType>
156 struct is_assignable<quad, OtherType>
157  : public integral_constant<bool, is_arithmetic<OtherType>::value>
158 {};
159 
160 template <class OtherType>
161 struct is_nothrow_assignable<quad, OtherType>
162  : public is_assignable<quad, OtherType>
163 {};
164 
165 /*
166 template <class OtherType>
167 struct is_trivially_assignable<quad, OtherType>
168  : public integral_constant<bool, is_arithmetic<OtherType>::value>
169 {};
170 */
171 
172 template <>
173 struct is_copy_assignable<quad>
174  : public integral_constant<bool, true>
175 {};
176 
177 template <>
178 struct is_nothrow_copy_assignable<quad>
179  : public integral_constant<bool, true>
180 {};
181 
182 template <>
183 struct is_move_assignable<quad>
184  : public integral_constant<bool, true>
185 {};
186 
187 template <>
188 struct is_nothrow_move_assignable<quad>
189  : public integral_constant<bool, true>
190 {};
191 
192 template <>
193 struct is_constructible<quad>
194  : public integral_constant<bool, true>
195 {};
196 
197 template <>
198 struct is_nothrow_constructible<quad>
199  : public integral_constant<bool, true>
200 {};
201 
202 template <>
203 struct is_default_constructible<quad>
204  : public integral_constant<bool, true>
205 {};
206 
207 template <>
208 struct is_nothrow_default_constructible<quad>
209  : public integral_constant<bool, true>
210 {};
211 
212 /*
213 template <>
214 struct is_trivially_default_constructible<quad>
215  : public integral_constant<bool, true>
216 {};
217 */
218 
219 template <>
220 struct is_copy_constructible<quad>
221  : public integral_constant<bool, true>
222 {};
223 
224 template <>
225 struct is_move_constructible<quad>
226  : public integral_constant<bool, true>
227 {};
228 
229 template <>
230 struct is_nothrow_move_constructible<quad>
231  : public integral_constant<bool, true>
232 {};
233 
234 
235 template <>
236 struct is_destructible<quad>
237  : public integral_constant<bool, true>
238 {};
239 
240 template <>
241 struct is_nothrow_destructible<quad>
242  : public integral_constant<bool, true>
243 {};
244 
245 template <class OtherType>
246 struct is_convertible<quad, OtherType>
247  : public is_arithmetic<OtherType>
248 { };
249 
250 #if !QUADMATH_HAS_IO_OPERATOR
251 inline std::ostream& operator<<(std::ostream& os, const quad& val)
252 {
253  if (os.precision() > std::numeric_limits<double>::digits10)
254  throw std::runtime_error("The precision requested for output cannot "
255  "be represented by a double precision floating "
256  "point object");
257 
258  return os << static_cast<double>(val);
259 }
260 
261 inline typename std::istream& operator>>(std::istream& is, quad& val)
262 {
263  double tmp = 0.0;
264  std::istream& ret = (is >> tmp);
265  val = tmp;
266  return ret;
267 }
268 #endif
269 
270 #if !QUADMATH_HAS_MATH_OPERATORS
271 inline quad real(quad val)
272 { return val; }
273 
274 inline quad real(const std::complex<quad>& val)
275 { return val.real(); }
276 
277 inline quad imag(quad)
278 { return 0.0; }
279 
280 inline quad imag(const std::complex<quad>& val)
281 { return val.imag(); }
282 
283 inline quad abs(quad val)
284 { return (val < 0) ? -val : val; }
285 
286 inline quad floor(quad val)
287 { return floorq(val); }
288 
289 inline quad ceil(quad val)
290 { return ceilq(val); }
291 
292 
293 inline quad max(quad a, quad b)
294 { return (a > b) ? a : b; }
295 
296 inline quad min(quad a, quad b)
297 { return (a < b) ? a : b; }
298 
299 
300 inline quad sqrt(quad val)
301 { return sqrtq(val); }
302 #endif // !QUADMATH_HAS_MATH_OPERATORS
303 
304 template <class ExpType>
305 inline quad pow(quad base, ExpType exp)
306 { return powq(base, static_cast<quad>(exp)); }
307 
308 template <class BaseType>
309 inline quad pow(BaseType base, quad exp)
310 { return powq(static_cast<quad>(base), exp); }
311 
312 #if !QUADMATH_HAS_MATH_OPERATORS
313 inline quad pow(quad base, quad exp)
314 { return powq(base, exp); }
315 
316 inline quad exp(quad val)
317 { return expq(val); }
318 
319 inline quad log(quad val)
320 { return logq(val); }
321 
322 inline quad sin(quad val)
323 { return sinq(val); }
324 
325 inline quad cos(quad val)
326 { return cosq(val); }
327 
328 inline quad tan(quad val)
329 { return tanq(val); }
330 
331 inline quad atan(quad val)
332 { return atanq(val); }
333 
334 inline quad atan2(quad a, quad b)
335 { return atan2q(a, b); }
336 
337 inline quad round(quad val)
338 { return roundq(val); }
339 
340 inline bool isfinite(quad val)
341 { return finiteq(val); }
342 
343 inline bool isnan(quad val)
344 { return isnanq(val); }
345 
346 inline bool isinf(quad val)
347 { return isinfq(val); }
348 #endif // QUADMATH_HAS_MATH_OPERATORS
349 
350 } // namespace std
351 
352 namespace std::numbers {
353  template <>
354  inline constexpr quad pi_v<quad> = M_PIq;
355 } // namespace std::numbers
356 
357 #if HAVE_DUNE_COMMON
358 
359 // specialize Dune::className for __float128 since it former does not work properly with
360 // __float128 (this is mainly the fault of GCC/libstdc++)
361 #include <dune/common/classname.hh>
362 
363 namespace Dune {
364 template <>
365 inline std::string className<__float128>()
366 { return "quad"; }
367 } // namespace Dune
368 
369 #endif // HAVE_DUNE_COMMON
370 
371 #if HAVE_DUNE_FEM
372 #include <dune/fem/io/streams/streams_inline.hh>
373 
374 namespace Dune {
375 namespace Fem {
376 template <class Traits>
377 inline OutStreamInterface<Traits>&
378 operator<<(OutStreamInterface<Traits>& out, quad value)
379 {
380  out.writeDouble(static_cast<double>(value));
381  return out;
382 }
383 
384 template <class Traits>
385 inline InStreamInterface<Traits>&
386 operator>>(InStreamInterface<Traits>& in, quad& value)
387 {
388  double tmp;
389  in.readDouble(tmp);
390  value = tmp;
391  return in;
392 }
393 
394 }} // namespace Dune, Fem
395 #endif // HAVE_DUNE_FEM
396 
397 #endif // OPM_COMMON_QUAD_HPP
Definition: SymmTensor.hpp:23