1 /* Boost interval/detail/ia64_rounding_control.hpp file 2 * 3 * Copyright 2006-2007 Boris Gubenko 4 * 5 * Distributed under the Boost Software License, Version 1.0. 6 * (See accompanying file LICENSE_1_0.txt or 7 * copy at http://www.boost.org/LICENSE_1_0.txt) 8 */ 9 10 #ifndef BOOST_NUMERIC_INTERVAL_DETAIL_IA64_ROUNDING_CONTROL_HPP 11 #define BOOST_NUMERIC_INTERVAL_DETAIL_IA64_ROUNDING_CONTROL_HPP 12 13 #if !defined(ia64) && !defined(__ia64) && !defined(__ia64__) 14 #error This header only works on ia64 CPUs. 15 #endif 16 17 #if defined(__hpux) 18 19 # include <fenv.h> 20 21 namespace boost { 22 namespace numeric { 23 namespace interval_lib { 24 namespace detail { 25 26 27 struct ia64_rounding_control 28 { 29 typedef unsigned int rounding_mode; 30 set_rounding_modeboost::numeric::interval_lib::detail::ia64_rounding_control31 static void set_rounding_mode(const rounding_mode& mode) { 32 fesetround(mode); } get_rounding_modeboost::numeric::interval_lib::detail::ia64_rounding_control33 static void get_rounding_mode(rounding_mode& mode) { mode = fegetround(); } 34 downwardboost::numeric::interval_lib::detail::ia64_rounding_control35 static void downward() { set_rounding_mode(FE_DOWNWARD); } upwardboost::numeric::interval_lib::detail::ia64_rounding_control36 static void upward() { set_rounding_mode(FE_UPWARD); } to_nearestboost::numeric::interval_lib::detail::ia64_rounding_control37 static void to_nearest() { set_rounding_mode(FE_TONEAREST); } toward_zeroboost::numeric::interval_lib::detail::ia64_rounding_control38 static void toward_zero() { set_rounding_mode(FE_TOWARDZERO); } 39 }; 40 41 } // namespace detail 42 43 extern "C" { 44 float rintf(float); 45 double rint(double); 46 long double rintl(long double); 47 } 48 49 template<> 50 struct rounding_control<float>: 51 detail::ia64_rounding_control 52 { force_roundingboost::numeric::interval_lib::rounding_control53 static float force_rounding(const float r) 54 { volatile float _r = r; return _r; } to_intboost::numeric::interval_lib::rounding_control55 static float to_int(const float& x) { return rintf(x); } 56 }; 57 58 template<> 59 struct rounding_control<double>: 60 detail::ia64_rounding_control 61 { force_roundingboost::numeric::interval_lib::rounding_control62 static const double & force_rounding(const double& r) { return r; } to_intboost::numeric::interval_lib::rounding_control63 static double to_int(const double& r) { return rint(r); } 64 }; 65 66 template<> 67 struct rounding_control<long double>: 68 detail::ia64_rounding_control 69 { force_roundingboost::numeric::interval_lib::rounding_control70 static const long double & force_rounding(const long double& r) { return r; } to_intboost::numeric::interval_lib::rounding_control71 static long double to_int(const long double& r) { return rintl(r); } 72 }; 73 74 } // namespace interval_lib 75 } // namespace numeric 76 } // namespace boost 77 78 #undef BOOST_NUMERIC_INTERVAL_NO_HARDWARE 79 80 #endif /* __hpux */ 81 82 #endif /* BOOST_NUMERIC_INTERVAL_DETAIL_IA64_ROUNDING_CONTROL_HPP */ 83 84