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