opm-common
Loading...
Searching...
No Matches
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
41extern "C" {
42#include <quadmath.h>
43}
44
45typedef __float128 quad;
46
47namespace std {
48
49#if !LIMITS_HAS_QUAD
50// provide the numeric limits for the quad precision type
51template <>
52class numeric_limits<quad>
53{
54public:
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
105template <>
106struct is_floating_point<quad>
107 : public integral_constant<bool, true>
108{};
109
110template <>
111struct is_arithmetic<quad>
112 : public integral_constant<bool, true>
113{};
114
115template <>
116struct is_fundamental<quad>
117 : public integral_constant<bool, true>
118{};
119
120template <>
121struct is_scalar<quad>
122 : public integral_constant<bool, true>
123{};
124
125#if __cplusplus < 202002L
126template <>
127struct is_pod<quad>
128 : public integral_constant<bool, true>
129{};
130#endif
131
132template <>
133struct is_signed<quad>
134 : public integral_constant<bool, true>
135{};
136
137
138template <>
139struct is_standard_layout<quad>
140 : public integral_constant<bool, true>
141{};
142
143template <>
144struct is_trivial<quad>
145 : public integral_constant<bool, true>
146{};
147
148/*
149template <>
150struct is_trivially_copyable<quad>
151 : public integral_constant<bool, true>
152{};
153*/
154
155template <class OtherType>
156struct is_assignable<quad, OtherType>
157 : public integral_constant<bool, is_arithmetic<OtherType>::value>
158{};
159
160template <class OtherType>
161struct is_nothrow_assignable<quad, OtherType>
162 : public is_assignable<quad, OtherType>
163{};
164
165/*
166template <class OtherType>
167struct is_trivially_assignable<quad, OtherType>
168 : public integral_constant<bool, is_arithmetic<OtherType>::value>
169{};
170*/
171
172template <>
173struct is_copy_assignable<quad>
174 : public integral_constant<bool, true>
175{};
176
177template <>
178struct is_nothrow_copy_assignable<quad>
179 : public integral_constant<bool, true>
180{};
181
182template <>
183struct is_move_assignable<quad>
184 : public integral_constant<bool, true>
185{};
186
187template <>
188struct is_nothrow_move_assignable<quad>
189 : public integral_constant<bool, true>
190{};
191
192template <>
193struct is_constructible<quad>
194 : public integral_constant<bool, true>
195{};
196
197template <>
198struct is_nothrow_constructible<quad>
199 : public integral_constant<bool, true>
200{};
201
202template <>
203struct is_default_constructible<quad>
204 : public integral_constant<bool, true>
205{};
206
207template <>
208struct is_nothrow_default_constructible<quad>
209 : public integral_constant<bool, true>
210{};
211
212/*
213template <>
214struct is_trivially_default_constructible<quad>
215 : public integral_constant<bool, true>
216{};
217*/
218
219template <>
220struct is_copy_constructible<quad>
221 : public integral_constant<bool, true>
222{};
223
224template <>
225struct is_move_constructible<quad>
226 : public integral_constant<bool, true>
227{};
228
229template <>
230struct is_nothrow_move_constructible<quad>
231 : public integral_constant<bool, true>
232{};
233
234
235template <>
236struct is_destructible<quad>
237 : public integral_constant<bool, true>
238{};
239
240template <>
241struct is_nothrow_destructible<quad>
242 : public integral_constant<bool, true>
243{};
244
245template <class OtherType>
246struct is_convertible<quad, OtherType>
247 : public is_arithmetic<OtherType>
248{ };
249
250#if !QUADMATH_HAS_IO_OPERATOR
251inline 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
261inline 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
271inline quad real(quad val)
272{ return val; }
273
274inline quad real(const std::complex<quad>& val)
275{ return val.real(); }
276
277inline quad imag(quad)
278{ return 0.0; }
279
280inline quad imag(const std::complex<quad>& val)
281{ return val.imag(); }
282
283inline quad abs(quad val)
284{ return (val < 0) ? -val : val; }
285
286inline quad floor(quad val)
287{ return floorq(val); }
288
289inline quad ceil(quad val)
290{ return ceilq(val); }
291
292
293inline quad max(quad a, quad b)
294{ return (a > b) ? a : b; }
295
296inline quad min(quad a, quad b)
297{ return (a < b) ? a : b; }
298
299
300inline quad sqrt(quad val)
301{ return sqrtq(val); }
302#endif // !QUADMATH_HAS_MATH_OPERATORS
303
304template <class ExpType>
305inline quad pow(quad base, ExpType exp)
306{ return powq(base, static_cast<quad>(exp)); }
307
308template <class BaseType>
309inline quad pow(BaseType base, quad exp)
310{ return powq(static_cast<quad>(base), exp); }
311
312#if !QUADMATH_HAS_MATH_OPERATORS
313inline quad pow(quad base, quad exp)
314{ return powq(base, exp); }
315
316inline quad exp(quad val)
317{ return expq(val); }
318
319inline quad log(quad val)
320{ return logq(val); }
321
322inline quad sin(quad val)
323{ return sinq(val); }
324
325inline quad cos(quad val)
326{ return cosq(val); }
327
328inline quad tan(quad val)
329{ return tanq(val); }
330
331inline quad atan(quad val)
332{ return atanq(val); }
333
334inline quad atan2(quad a, quad b)
335{ return atan2q(a, b); }
336
337inline quad round(quad val)
338{ return roundq(val); }
339
340inline bool isfinite(quad val)
341{ return finiteq(val); }
342
343inline bool isnan(quad val)
344{ return isnanq(val); }
345
346inline bool isinf(quad val)
347{ return isinfq(val); }
348#endif // QUADMATH_HAS_MATH_OPERATORS
349
350} // namespace std
351
352namespace 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
363namespace Dune {
364template <>
365inline 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
374namespace Dune {
375namespace Fem {
376template <class Traits>
377inline OutStreamInterface<Traits>&
378operator<<(OutStreamInterface<Traits>& out, quad value)
379{
380 out.writeDouble(static_cast<double>(value));
381 return out;
382}
383
384template <class Traits>
385inline InStreamInterface<Traits>&
386operator>>(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