My Project
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 <string>
35#include <stdexcept>
36#include <limits>
37#include <iostream>
38#include <type_traits>
39
40extern "C" {
41#include <quadmath.h>
42}
43
44typedef __float128 quad;
45
46namespace std {
47
48#if !LIMITS_HAS_QUAD
49// provide the numeric limits for the quad precision type
50template <>
51class numeric_limits<quad>
52{
53public:
54 static constexpr bool is_specialized = true;
55
56 static constexpr quad min() throw()
57 { return FLT128_MIN; }
58 static constexpr quad max() throw()
59 { return FLT128_MAX; }
60
61 // number of bits in mantissa
62 static constexpr int digits = FLT128_MANT_DIG;
63 // number of decimal digits
64 static constexpr int digits10 = FLT128_DIG;
65 static constexpr bool is_signed = true;
66 static constexpr bool is_integer = false;
67 static constexpr bool is_exact = false;
68 static constexpr int radix = 0;
69 static constexpr quad epsilon() throw()
70 { return FLT128_EPSILON; }
71 static constexpr quad round_error() throw()
72 { return 0.5; }
73
74 static constexpr int min_exponent = FLT128_MIN_EXP;
75 static constexpr int min_exponent10 = FLT128_MIN_10_EXP;
76 static constexpr int max_exponent = FLT128_MAX_EXP;
77 static constexpr int max_exponent10 = FLT128_MAX_10_EXP;
78
79 static constexpr bool has_infinity = true;
80 static constexpr bool has_quiet_NaN = true;
81 static constexpr bool has_signaling_NaN = true;
82 static constexpr float_denorm_style has_denorm = denorm_present;
83 static constexpr bool has_denorm_loss = false;
84 static constexpr quad infinity() throw()
85 { return __builtin_huge_valq(); }
86 static constexpr quad quiet_NaN() throw()
87 { return __builtin_nan(""); }
88 static constexpr quad signaling_NaN() throw()
89 { return __builtin_nans(""); }
90 static constexpr quad denorm_min() throw()
91 { return FLT128_DENORM_MIN; }
92
93 static constexpr bool is_iec559 = true;
94 static constexpr bool is_bounded = true;
95 static constexpr bool is_modulo = false;
96
97 static constexpr bool traps = std::numeric_limits<double>::traps;
98 static constexpr bool tinyness_before = std::numeric_limits<double>::tinyness_before;
99 static constexpr float_round_style round_style = round_to_nearest;
100};
101#endif // LIMITS_HAS_QUAD
102
103// provide some type traits for the quadruple precision type
104template <>
105struct is_floating_point<quad>
106 : public integral_constant<bool, true>
107{};
108
109template <>
110struct is_arithmetic<quad>
111 : public integral_constant<bool, true>
112{};
113
114template <>
115struct is_fundamental<quad>
116 : public integral_constant<bool, true>
117{};
118
119template <>
120struct is_scalar<quad>
121 : public integral_constant<bool, true>
122{};
123
124#if __cplusplus < 202002L
125template <>
126struct is_pod<quad>
127 : public integral_constant<bool, true>
128{};
129#endif
130
131template <>
132struct is_signed<quad>
133 : public integral_constant<bool, true>
134{};
135
136
137template <>
138struct is_standard_layout<quad>
139 : public integral_constant<bool, true>
140{};
141
142template <>
143struct is_trivial<quad>
144 : public integral_constant<bool, true>
145{};
146
147/*
148template <>
149struct is_trivially_copyable<quad>
150 : public integral_constant<bool, true>
151{};
152*/
153
154template <class OtherType>
155struct is_assignable<quad, OtherType>
156 : public integral_constant<bool, is_arithmetic<OtherType>::value>
157{};
158
159template <class OtherType>
160struct is_nothrow_assignable<quad, OtherType>
161 : public is_assignable<quad, OtherType>
162{};
163
164/*
165template <class OtherType>
166struct is_trivially_assignable<quad, OtherType>
167 : public integral_constant<bool, is_arithmetic<OtherType>::value>
168{};
169*/
170
171template <>
172struct is_copy_assignable<quad>
173 : public integral_constant<bool, true>
174{};
175
176template <>
177struct is_nothrow_copy_assignable<quad>
178 : public integral_constant<bool, true>
179{};
180
181template <>
182struct is_move_assignable<quad>
183 : public integral_constant<bool, true>
184{};
185
186template <>
187struct is_nothrow_move_assignable<quad>
188 : public integral_constant<bool, true>
189{};
190
191template <>
192struct is_constructible<quad>
193 : public integral_constant<bool, true>
194{};
195
196template <>
197struct is_nothrow_constructible<quad>
198 : public integral_constant<bool, true>
199{};
200
201template <>
202struct is_default_constructible<quad>
203 : public integral_constant<bool, true>
204{};
205
206template <>
207struct is_nothrow_default_constructible<quad>
208 : public integral_constant<bool, true>
209{};
210
211/*
212template <>
213struct is_trivially_default_constructible<quad>
214 : public integral_constant<bool, true>
215{};
216*/
217
218template <>
219struct is_copy_constructible<quad>
220 : public integral_constant<bool, true>
221{};
222
223template <>
224struct is_move_constructible<quad>
225 : public integral_constant<bool, true>
226{};
227
228template <>
229struct is_nothrow_move_constructible<quad>
230 : public integral_constant<bool, true>
231{};
232
233
234template <>
235struct is_destructible<quad>
236 : public integral_constant<bool, true>
237{};
238
239template <>
240struct is_nothrow_destructible<quad>
241 : public integral_constant<bool, true>
242{};
243
244template <class OtherType>
245struct is_convertible<quad, OtherType>
246 : public is_arithmetic<OtherType>
247{ };
248
249inline std::ostream& operator<<(std::ostream& os, const quad& val)
250{
251 if (os.precision() > std::numeric_limits<double>::digits10)
252 throw std::runtime_error("The precision requested for output cannot "
253 "be represented by a double precision floating "
254 "point object");
255
256 return os << static_cast<double>(val);
257}
258
259inline std::istream& operator>>(std::istream& is, quad& val)
260{
261 double tmp = 0.0;
262 std::istream& ret = (is >> tmp);
263 val = tmp;
264 return ret;
265}
266
267inline quad real(quad val)
268{ return val; }
269
270inline quad real(const std::complex<quad>& val)
271{ return val.real(); }
272
273inline quad imag(quad)
274{ return 0.0; }
275
276inline quad imag(const std::complex<quad>& val)
277{ return val.imag(); }
278
279inline quad abs(quad val)
280{ return (val < 0) ? -val : val; }
281
282inline quad floor(quad val)
283{ return floorq(val); }
284
285inline quad ceil(quad val)
286{ return ceilq(val); }
287
288inline quad max(quad a, quad b)
289{ return (a > b) ? a : b; }
290
291inline quad min(quad a, quad b)
292{ return (a < b) ? a : b; }
293
294inline quad sqrt(quad val)
295{ return sqrtq(val); }
296
297template <class ExpType>
298inline quad pow(quad base, ExpType exp)
299{ return powq(base, static_cast<quad>(exp)); }
300
301template <class BaseType>
302inline quad pow(BaseType base, quad exp)
303{ return powq(static_cast<quad>(base), exp); }
304
305inline quad pow(quad base, quad exp)
306{ return powq(base, exp); }
307
308inline quad exp(quad val)
309{ return expq(val); }
310
311inline quad log(quad val)
312{ return logq(val); }
313
314inline quad sin(quad val)
315{ return sinq(val); }
316
317inline quad cos(quad val)
318{ return cosq(val); }
319
320inline quad tan(quad val)
321{ return tanq(val); }
322
323inline quad atan(quad val)
324{ return atanq(val); }
325
326inline quad atan2(quad a, quad b)
327{ return atan2q(a, b); }
328
329inline quad round(quad val)
330{ return roundq(val); }
331
332inline bool isfinite(quad val)
333{ return finiteq(val); }
334
335inline bool isnan(quad val)
336{ return isnanq(val); }
337
338inline bool isinf(quad val)
339{ return isinfq(val); }
340
341} // namespace std
342
343#if HAVE_DUNE_COMMON
344
345// specialize Dune::className for __float128 since it former does not work properly with
346// __float128 (this is mainly the fault of GCC/libstdc++)
347#include <dune/common/classname.hh>
348
349namespace Dune {
350template <>
351inline std::string className<__float128>()
352{ return "quad"; }
353} // namespace Dune
354
355#endif // HAVE_DUNE_COMMON
356
357#if HAVE_DUNE_FEM
358#include <dune/fem/io/streams/streams_inline.hh>
359
360namespace Dune {
361namespace Fem {
362template <class Traits>
363inline OutStreamInterface<Traits>&
364operator<<(OutStreamInterface<Traits>& out, quad value)
365{
366 out.writeDouble(static_cast<double>(value));
367 return out;
368}
369
370template <class Traits>
371inline InStreamInterface<Traits>&
372operator>>(InStreamInterface<Traits>& in, quad& value)
373{
374 double tmp;
375 in.readDouble(tmp);
376 value = tmp;
377 return in;
378}
379
380}} // namespace Dune, Fem
381#endif // HAVE_DUNE_FEM
382
383#endif // OPM_COMMON_QUAD_HPP