cmath.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /*************************************************************************************************/ 00008 00009 /* 00010 00011 REVISIT (sparent) : Need to replicate the boost configuration tests to figure out when to fall 00012 back to include math.h. This also needs to add any other C99 math.h extensions. 00013 00014 */ 00015 00016 #ifndef ADOBE_CMATH_HPP 00017 #define ADOBE_CMATH_HPP 00018 00019 #include <adobe/config.hpp> 00020 00021 #include <functional> 00022 00023 /*************************************************************************************************/ 00024 00025 #if defined(__MWERKS__) 00026 /* 00027 Any (previously) supported version of metrowerks had the C99/TR1 cmath extensions in the 00028 standard namespace in <cmath>. 00029 */ 00030 #define ADOBE_HAS_C99_STD_MATH_H 00031 #include <cmath> 00032 #elif defined(__GNUC__) 00033 00034 // Guessing at gcc 3 support 00035 #if (__GNUC__ == 3) && (__GNUC_MINOR__ > 2) 00036 00037 #define ADOBE_HAS_CPP_CMATH 00038 00039 #elif __GNUC__ == 4 00040 #if (__GNUC_MINOR__ < 6) || (!(defined(_GLIBCXX_USE_C99_MATH_TR1))) 00041 // at least Ubuntu 9.x, gcc 4.4.1, still falls into this case 00042 /* 00043 The currently supported version of GNUC has C99 extensions in math.h. But no TR1 extensions. 00044 */ 00045 #define ADOBE_HAS_C99_MATH_H 00046 #include <cmath> 00047 #else 00048 #include <tr1/cmath> 00049 s 00050 #define ADOBE_HAS_C99_STD_MATH_H 00051 #endif 00052 #endif 00053 00054 #elif defined(_MSC_VER) 00055 #include <cmath> 00056 /* 00057 The currently supported version of VC++ has no C99 extensions. 00058 */ 00059 00060 #if _MSC_VER > 1600 00061 #error "Unknown MSC compiler configureation for cmath (last knownversion is VC++ 10.0)." 00062 #endif 00063 00064 #define ADOBE_HAS_CPP_CMATH 00065 00066 #else 00067 #error "Unknown compiler configuration for cmath." 00068 #endif 00069 00070 /*************************************************************************************************/ 00071 00072 #if defined(ADOBE_HAS_C99_STD_MATH_H) 00073 00074 namespace adobe { 00075 00076 using std::float_t; 00077 using std::double_t; 00078 00079 using std::round; 00080 using std::lround; 00081 using std::trunc; 00082 00083 } // namespace adobe 00084 00085 /*************************************************************************************************/ 00086 00087 #elif defined(ADOBE_HAS_CPP_CMATH) 00088 00089 namespace adobe { 00090 00091 typedef float float_t; 00092 typedef double double_t; 00093 00094 /*************************************************************************************************/ 00095 00096 inline float trunc(float x) 00097 { return x < 0.0f ? std::ceil(x) : std::floor(x); } 00098 00099 inline double trunc(double x) 00100 { return x < 0.0 ? std::ceil(x) : std::floor(x); } 00101 00102 /*************************************************************************************************/ 00103 00104 inline float round(float x) 00105 { return trunc(x + (x < 0.0f ? -0.5f : 0.5f)); } 00106 00107 inline double round(double x) 00108 { return trunc(x + (x < 0.0 ? -0.5 : 0.5)); } 00109 00110 /*************************************************************************************************/ 00111 00112 inline long lround(float x) 00113 { return static_cast<long>(x + (x < 0.0f ? -0.5f : 0.5f)); } 00114 00115 inline long lround(double x) 00116 { return static_cast<long>(x + (x < 0.0 ? -0.5 : 0.5)); } 00117 00118 /*************************************************************************************************/ 00119 00120 } // namespace adobe 00121 00122 /*************************************************************************************************/ 00123 00124 #elif defined(ADOBE_HAS_C99_MATH_H) 00125 00126 #include <math.h> 00127 00128 namespace adobe { 00129 00130 using ::float_t; 00131 using ::double_t; 00132 00133 /*************************************************************************************************/ 00134 00135 using ::round; 00136 using ::lround; 00137 using ::trunc; 00138 00139 inline float round(float x) { return ::roundf(x); } 00140 inline long lround(float x) { return ::lroundf(x); } 00141 inline float trunc(float x) { return ::truncf(x); } 00142 00143 /*************************************************************************************************/ 00144 00145 } // namespace adobe 00146 00147 #elif defined(ADOBE_NO_DOCUMENTATION) 00148 00149 namespace adobe { 00150 00161 typedef Float double_t; 00162 typedef Float float_t; 00163 00164 double round(double x); 00165 float round(float x); 00166 long lround(double x); 00167 long lround(float x); 00168 double trunc(double x); 00169 float trunc(float x); 00172 } // namespace adobe 00173 00174 #endif 00175 00176 /*************************************************************************************************/ 00177 00178 namespace adobe { 00179 00180 /*************************************************************************************************/ 00181 00182 template <typename A, typename R> struct nearest_cast_fn; 00183 00184 /*************************************************************************************************/ 00185 00186 inline double round_half_up(double x) 00187 { return std::floor(x + 0.5); } 00188 00189 inline float round_half_up(float x) 00190 { return std::floor(x + 0.5f); } 00191 00192 inline long lround_half_up(double x) 00193 { return static_cast<long>(std::floor(x + 0.5)); } 00194 00195 inline long lround_half_up(float x) 00196 { return static_cast<long>(std::floor(x + 0.5f)); } 00197 00198 /* 00199 REVISIT (sparent) : Should complete the rounding modes by providing a round_half_even() 00200 function. 00201 00202 Names are borrowed from the EDA rounding modes: 00203 00204 <http://www.gobosoft.com/eiffel/gobo/math/decimal/> 00205 */ 00206 00207 /*************************************************************************************************/ 00208 00209 template <typename R, typename A> 00210 inline R nearest_cast(const A& x) 00211 { return nearest_cast_fn<A, R>()(x); } 00212 00213 /*************************************************************************************************/ 00214 00215 template <typename A, typename R> 00216 struct nearest_cast_fn : std::unary_function<A, R> 00217 { 00218 R operator()(const A& x) const { return static_cast<R>(round_half_up(x)); } 00219 }; 00220 00221 template <typename A> 00222 struct nearest_cast_fn<A, float> : std::unary_function<A, float> 00223 { 00224 float operator()(const A& x) const { return static_cast<float>(x); } 00225 }; 00226 00227 template <typename A> 00228 struct nearest_cast_fn<A, double> : std::unary_function<A, double> 00229 { 00230 double operator()(const A& x) const { return static_cast<double>(x); } 00231 }; 00232 00233 /*************************************************************************************************/ 00234 00235 } // namespace adobe 00236 00237 /*************************************************************************************************/ 00238 00239 #endif 00240 00241 /*************************************************************************************************/ |