stlab.adobe.com Adobe Systems Incorporated

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 /*************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google