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 <cmath>
00022 #include <functional>
00023 
00024 /*************************************************************************************************/
00025 
00026 #if defined(__MWERKS__)
00027 /*
00028     Any (previously) supported version of metrowerks had the C99/TR1 cmath extensions in the
00029     standard namespace in <cmath>.
00030 */
00031 #define ADOBE_HAS_C99_STD_MATH_H
00032 
00033 #elif defined(__GNUC__)
00034 
00035 // Guessing at gcc 3 support
00036 #if  (__GNUC__ == 3) && (__GNUC_MINOR__ > 2)
00037 
00038 #define ADOBE_HAS_CPP_CMATH 
00039 
00040 #elif ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 3))
00041 /*
00042     The currently supported version of GNUC has C99 extensions in math.h. But no TR1 extensions.
00043 */
00044 #define ADOBE_HAS_C99_MATH_H
00045  
00046 #else
00047 #error "Unknown GCC compiler configuration for cmath (last known version is 4.0.1)."
00048 #endif
00049 
00050 #elif defined(_MSC_VER)
00051 
00052 /*
00053     The currently supported version of VC++ has no C99 extensions.
00054 */
00055 
00056 #if _MSC_VER > 1500
00057 #error "Unknown MSC compiler configureation for cmath (last knownversion is VC++ 9.0)."
00058 #endif
00059 
00060 #define ADOBE_HAS_CPP_CMATH
00061 
00062 #else
00063 #error "Unknown compiler configuration for cmath."
00064 #endif
00065 
00066 /*************************************************************************************************/
00067 
00068 #if defined(ADOBE_HAS_C99_STD_MATH_H)
00069 
00070 namespace adobe {
00071 
00072 using std::float_t;
00073 using std::double_t;
00074 
00075 using std::round;
00076 using std::lround;
00077 using std::trunc;
00078 
00079 } // namespace adobe
00080 
00081 /*************************************************************************************************/
00082 
00083 #elif   defined(ADOBE_HAS_CPP_CMATH)
00084 
00085 namespace adobe {
00086 
00087 typedef float   float_t;
00088 typedef double  double_t;
00089 
00090 /*************************************************************************************************/
00091 
00092 inline float trunc(float x)
00093 { return x < 0.0f ? std::ceil(x) : std::floor(x); }
00094 
00095 inline double trunc(double x)
00096 { return x < 0.0 ? std::ceil(x) : std::floor(x); }
00097 
00098 /*************************************************************************************************/
00099 
00100 inline float round(float x)
00101 { return trunc(x + (x < 0.0f ? -0.5f : 0.5f)); }
00102 
00103 inline double round(double x)
00104 { return trunc(x + (x < 0.0 ? -0.5 : 0.5)); }
00105 
00106 /*************************************************************************************************/
00107 
00108 inline long lround(float x)
00109 { return static_cast<long>(x + (x < 0.0f ? -0.5f : 0.5f)); }
00110 
00111 inline long lround(double x)
00112 { return static_cast<long>(x + (x < 0.0 ? -0.5 : 0.5)); }
00113 
00114 /*************************************************************************************************/
00115 
00116 } // namespace adobe
00117 
00118 /*************************************************************************************************/
00119 
00120 #elif defined(ADOBE_HAS_C99_MATH_H)
00121 
00122 #include <math.h>
00123 
00124 namespace adobe {
00125 
00126 using ::float_t;
00127 using ::double_t;
00128 
00129 /*************************************************************************************************/
00130 
00131 using ::round;
00132 using ::lround;
00133 using ::trunc;
00134 
00135 inline float round(float x) { return ::roundf(x); }
00136 inline long lround(float x) { return ::lroundf(x); }
00137 inline float trunc(float x) { return ::truncf(x); }
00138 
00139 /*************************************************************************************************/
00140 
00141 } // namespace adobe
00142 
00143 #elif defined(ADOBE_NO_DOCUMENTATION)
00144 
00145 namespace adobe {
00146 
00157 typedef Float double_t;
00158 typedef Float float_t;
00159 
00160 double round(double x);
00161 float round(float x);
00162 long lround(double x);
00163 long lround(float x);
00164 double trunc(double x);
00165 float trunc(float x);
00168 } // namespace adobe
00169 
00170 #endif
00171 
00172 /*************************************************************************************************/
00173 
00174 namespace adobe {
00175 
00176 /*************************************************************************************************/
00177 
00178 template <typename A, typename R> struct nearest_cast_fn;
00179 
00180 /*************************************************************************************************/
00181 
00182 inline double round_half_up(double x)
00183 { return std::floor(x + 0.5); }
00184 
00185 inline float round_half_up(float x)
00186 { return std::floor(x + 0.5f); }
00187 
00188 inline long lround_half_up(double x)
00189 { return static_cast<long>(std::floor(x + 0.5)); }
00190 
00191 inline long lround_half_up(float x)
00192 { return static_cast<long>(std::floor(x + 0.5f)); }
00193 
00194 /*
00195     REVISIT (sparent) : Should complete the rounding modes by providing a round_half_even()
00196     function.
00197     
00198     Names are borrowed from the EDA rounding modes:
00199     
00200     <http://www.gobosoft.com/eiffel/gobo/math/decimal/>
00201 */
00202 
00203 /*************************************************************************************************/
00204 
00205 template <typename R, typename A>
00206 inline R nearest_cast(const A& x)
00207 { return nearest_cast_fn<A, R>()(x); }
00208 
00209 /*************************************************************************************************/
00210 
00211 template <typename A, typename R>
00212 struct nearest_cast_fn : std::unary_function<A, R>
00213 {
00214     R operator()(const A& x) const { return static_cast<R>(round_half_up(x)); }
00215 };
00216 
00217 template <typename A>
00218 struct nearest_cast_fn<A, float> : std::unary_function<A, float>
00219 {
00220     float operator()(const A& x) const { return static_cast<float>(x); }
00221 };
00222 
00223 template <typename A>
00224 struct nearest_cast_fn<A, double> : std::unary_function<A, double>
00225 {
00226     double operator()(const A& x) const { return static_cast<double>(x); }
00227 };
00228 
00229 /*************************************************************************************************/
00230 
00231 } // namespace adobe
00232 
00233 /*************************************************************************************************/
00234 
00235 #endif
00236 
00237 /*************************************************************************************************/

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