| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 const float piOverTwoFloat = static_cast<float>(M_PI_2); | 48 const float piOverTwoFloat = static_cast<float>(M_PI_2); |
| 49 | 49 |
| 50 const double piOverFourDouble = M_PI_4; | 50 const double piOverFourDouble = M_PI_4; |
| 51 const float piOverFourFloat = static_cast<float>(M_PI_4); | 51 const float piOverFourFloat = static_cast<float>(M_PI_4); |
| 52 | 52 |
| 53 const double twoPiDouble = piDouble * 2.0; | 53 const double twoPiDouble = piDouble * 2.0; |
| 54 const float twoPiFloat = piFloat * 2.0f; | 54 const float twoPiFloat = piFloat * 2.0f; |
| 55 | 55 |
| 56 #if OS(ANDROID) || COMPILER(MSVC) | 56 #if OS(ANDROID) || COMPILER(MSVC) |
| 57 // ANDROID and MSVC's math.h does not currently supply log2 or log2f. | 57 // ANDROID and MSVC's math.h does not currently supply log2 or log2f. |
| 58 inline double log2(double num) | 58 inline double log2(double num) { |
| 59 { | 59 // This constant is roughly M_LN2, which is not provided by default on Windows
and Android. |
| 60 // This constant is roughly M_LN2, which is not provided by default on Windo
ws and Android. | 60 return log(num) / 0.693147180559945309417232121458176568; |
| 61 return log(num) / 0.693147180559945309417232121458176568; | |
| 62 } | 61 } |
| 63 | 62 |
| 64 inline float log2f(float num) | 63 inline float log2f(float num) { |
| 65 { | 64 // This constant is roughly M_LN2, which is not provided by default on Windows
and Android. |
| 66 // This constant is roughly M_LN2, which is not provided by default on Windo
ws and Android. | 65 return logf(num) / 0.693147180559945309417232121458176568f; |
| 67 return logf(num) / 0.693147180559945309417232121458176568f; | |
| 68 } | 66 } |
| 69 #endif | 67 #endif |
| 70 | 68 |
| 71 #if COMPILER(MSVC) | 69 #if COMPILER(MSVC) |
| 72 | 70 |
| 73 // VS2013 has most of the math functions now, but we still need to work | 71 // VS2013 has most of the math functions now, but we still need to work |
| 74 // around various differences in behavior of Inf. | 72 // around various differences in behavior of Inf. |
| 75 | 73 |
| 76 // Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN inst
ead of specific values. | 74 // Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN inst
ead of specific values. |
| 77 inline double wtf_atan2(double x, double y) | 75 inline double wtf_atan2(double x, double y) { |
| 78 { | 76 double posInf = std::numeric_limits<double>::infinity(); |
| 79 double posInf = std::numeric_limits<double>::infinity(); | 77 double negInf = -std::numeric_limits<double>::infinity(); |
| 80 double negInf = -std::numeric_limits<double>::infinity(); | 78 double nan = std::numeric_limits<double>::quiet_NaN(); |
| 81 double nan = std::numeric_limits<double>::quiet_NaN(); | |
| 82 | 79 |
| 83 double result = nan; | 80 double result = nan; |
| 84 | 81 |
| 85 if (x == posInf && y == posInf) | 82 if (x == posInf && y == posInf) |
| 86 result = piOverFourDouble; | 83 result = piOverFourDouble; |
| 87 else if (x == posInf && y == negInf) | 84 else if (x == posInf && y == negInf) |
| 88 result = 3 * piOverFourDouble; | 85 result = 3 * piOverFourDouble; |
| 89 else if (x == negInf && y == posInf) | 86 else if (x == negInf && y == posInf) |
| 90 result = -piOverFourDouble; | 87 result = -piOverFourDouble; |
| 91 else if (x == negInf && y == negInf) | 88 else if (x == negInf && y == negInf) |
| 92 result = -3 * piOverFourDouble; | 89 result = -3 * piOverFourDouble; |
| 93 else | 90 else |
| 94 result = ::atan2(x, y); | 91 result = ::atan2(x, y); |
| 95 | 92 |
| 96 return result; | 93 return result; |
| 97 } | 94 } |
| 98 | 95 |
| 99 // Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN
instead of x. | 96 // Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN
instead of x. |
| 100 inline double wtf_fmod(double x, double y) { return (!std::isinf(x) && std::isin
f(y)) ? x : fmod(x, y); } | 97 inline double wtf_fmod(double x, double y) { |
| 98 return (!std::isinf(x) && std::isinf(y)) ? x : fmod(x, y); |
| 99 } |
| 101 | 100 |
| 102 // Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead
of 1. | 101 // Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead
of 1. |
| 103 inline double wtf_pow(double x, double y) { return y == 0 ? 1 : pow(x, y); } | 102 inline double wtf_pow(double x, double y) { |
| 103 return y == 0 ? 1 : pow(x, y); |
| 104 } |
| 104 | 105 |
| 105 #define atan2(x, y) wtf_atan2(x, y) | 106 #define atan2(x, y) wtf_atan2(x, y) |
| 106 #define fmod(x, y) wtf_fmod(x, y) | 107 #define fmod(x, y) wtf_fmod(x, y) |
| 107 #define pow(x, y) wtf_pow(x, y) | 108 #define pow(x, y) wtf_pow(x, y) |
| 108 | 109 |
| 109 #endif // COMPILER(MSVC) | 110 #endif // COMPILER(MSVC) |
| 110 | 111 |
| 111 inline double deg2rad(double d) { return d * piDouble / 180.0; } | 112 inline double deg2rad(double d) { |
| 112 inline double rad2deg(double r) { return r * 180.0 / piDouble; } | 113 return d * piDouble / 180.0; |
| 113 inline double deg2grad(double d) { return d * 400.0 / 360.0; } | 114 } |
| 114 inline double grad2deg(double g) { return g * 360.0 / 400.0; } | 115 inline double rad2deg(double r) { |
| 115 inline double turn2deg(double t) { return t * 360.0; } | 116 return r * 180.0 / piDouble; |
| 116 inline double deg2turn(double d) { return d / 360.0; } | 117 } |
| 117 inline double rad2grad(double r) { return r * 200.0 / piDouble; } | 118 inline double deg2grad(double d) { |
| 118 inline double grad2rad(double g) { return g * piDouble / 200.0; } | 119 return d * 400.0 / 360.0; |
| 119 inline double turn2grad(double t) { return t * 400; } | 120 } |
| 120 inline double grad2turn(double g) { return g / 400; } | 121 inline double grad2deg(double g) { |
| 122 return g * 360.0 / 400.0; |
| 123 } |
| 124 inline double turn2deg(double t) { |
| 125 return t * 360.0; |
| 126 } |
| 127 inline double deg2turn(double d) { |
| 128 return d / 360.0; |
| 129 } |
| 130 inline double rad2grad(double r) { |
| 131 return r * 200.0 / piDouble; |
| 132 } |
| 133 inline double grad2rad(double g) { |
| 134 return g * piDouble / 200.0; |
| 135 } |
| 136 inline double turn2grad(double t) { |
| 137 return t * 400; |
| 138 } |
| 139 inline double grad2turn(double g) { |
| 140 return g / 400; |
| 141 } |
| 121 | 142 |
| 122 inline float deg2rad(float d) { return d * piFloat / 180.0f; } | 143 inline float deg2rad(float d) { |
| 123 inline float rad2deg(float r) { return r * 180.0f / piFloat; } | 144 return d * piFloat / 180.0f; |
| 124 inline float deg2grad(float d) { return d * 400.0f / 360.0f; } | 145 } |
| 125 inline float grad2deg(float g) { return g * 360.0f / 400.0f; } | 146 inline float rad2deg(float r) { |
| 126 inline float turn2deg(float t) { return t * 360.0f; } | 147 return r * 180.0f / piFloat; |
| 127 inline float deg2turn(float d) { return d / 360.0f; } | 148 } |
| 128 inline float rad2grad(float r) { return r * 200.0f / piFloat; } | 149 inline float deg2grad(float d) { |
| 129 inline float grad2rad(float g) { return g * piFloat / 200.0f; } | 150 return d * 400.0f / 360.0f; |
| 130 inline float turn2grad(float t) { return t * 400; } | 151 } |
| 131 inline float grad2turn(float g) { return g / 400; } | 152 inline float grad2deg(float g) { |
| 153 return g * 360.0f / 400.0f; |
| 154 } |
| 155 inline float turn2deg(float t) { |
| 156 return t * 360.0f; |
| 157 } |
| 158 inline float deg2turn(float d) { |
| 159 return d / 360.0f; |
| 160 } |
| 161 inline float rad2grad(float r) { |
| 162 return r * 200.0f / piFloat; |
| 163 } |
| 164 inline float grad2rad(float g) { |
| 165 return g * piFloat / 200.0f; |
| 166 } |
| 167 inline float turn2grad(float t) { |
| 168 return t * 400; |
| 169 } |
| 170 inline float grad2turn(float g) { |
| 171 return g / 400; |
| 172 } |
| 132 | 173 |
| 133 // clampTo() is implemented by templated helper classes (to allow for partial | 174 // clampTo() is implemented by templated helper classes (to allow for partial |
| 134 // template specialization) as well as several helper functions. | 175 // template specialization) as well as several helper functions. |
| 135 | 176 |
| 136 // This helper function can be called when we know that: | 177 // This helper function can be called when we know that: |
| 137 // (1) The type signednesses match so the compiler will not produce signed vs. | 178 // (1) The type signednesses match so the compiler will not produce signed vs. |
| 138 // unsigned warnings | 179 // unsigned warnings |
| 139 // (2) The default type promotions/conversions are sufficient to handle things | 180 // (2) The default type promotions/conversions are sufficient to handle things |
| 140 // correctly | 181 // correctly |
| 141 template<typename LimitType, typename ValueType> inline LimitType clampToDirectC
omparison(ValueType value, LimitType min, LimitType max) | 182 template <typename LimitType, typename ValueType> |
| 142 { | 183 inline LimitType clampToDirectComparison(ValueType value, LimitType min, LimitTy
pe max) { |
| 143 if (value >= max) | 184 if (value >= max) |
| 144 return max; | 185 return max; |
| 145 return (value <= min) ? min : static_cast<LimitType>(value); | 186 return (value <= min) ? min : static_cast<LimitType>(value); |
| 146 } | 187 } |
| 147 | 188 |
| 148 // For any floating-point limits, or integral limits smaller than long long, we | 189 // For any floating-point limits, or integral limits smaller than long long, we |
| 149 // can cast the limits to double without losing precision; then the only cases | 190 // can cast the limits to double without losing precision; then the only cases |
| 150 // where |value| can't be represented accurately as a double are the ones where | 191 // where |value| can't be represented accurately as a double are the ones where |
| 151 // it's outside the limit range anyway. So doing all comparisons as doubles | 192 // it's outside the limit range anyway. So doing all comparisons as doubles |
| 152 // will give correct results. | 193 // will give correct results. |
| 153 // | 194 // |
| 154 // In some cases, we can get better performance by using | 195 // In some cases, we can get better performance by using |
| 155 // clampToDirectComparison(). We use a templated class to switch between these | 196 // clampToDirectComparison(). We use a templated class to switch between these |
| 156 // two cases (instead of simply using a conditional within one function) in | 197 // two cases (instead of simply using a conditional within one function) in |
| 157 // order to only compile the clampToDirectComparison() code for cases where it | 198 // order to only compile the clampToDirectComparison() code for cases where it |
| 158 // will actually be used; this prevents the compiler from emitting warnings | 199 // will actually be used; this prevents the compiler from emitting warnings |
| 159 // about unsafe code (even though we wouldn't actually be executing that code). | 200 // about unsafe code (even though we wouldn't actually be executing that code). |
| 160 template<bool canUseDirectComparison, typename LimitType, typename ValueType> cl
ass ClampToNonLongLongHelper; | 201 template <bool canUseDirectComparison, typename LimitType, typename ValueType> |
| 161 template<typename LimitType, typename ValueType> class ClampToNonLongLongHelper<
true, LimitType, ValueType> { | 202 class ClampToNonLongLongHelper; |
| 162 public: | 203 template <typename LimitType, typename ValueType> |
| 163 static inline LimitType clampTo(ValueType value, LimitType min, LimitType ma
x) | 204 class ClampToNonLongLongHelper<true, LimitType, ValueType> { |
| 164 { | 205 public: |
| 165 return clampToDirectComparison(value, min, max); | 206 static inline LimitType clampTo(ValueType value, LimitType min, LimitType max)
{ |
| 166 } | 207 return clampToDirectComparison(value, min, max); |
| 208 } |
| 167 }; | 209 }; |
| 168 | 210 |
| 169 template<typename LimitType, typename ValueType> class ClampToNonLongLongHelper<
false, LimitType, ValueType> { | 211 template <typename LimitType, typename ValueType> |
| 170 public: | 212 class ClampToNonLongLongHelper<false, LimitType, ValueType> { |
| 171 static inline LimitType clampTo(ValueType value, LimitType min, LimitType ma
x) | 213 public: |
| 172 { | 214 static inline LimitType clampTo(ValueType value, LimitType min, LimitType max)
{ |
| 173 const double doubleValue = static_cast<double>(value); | 215 const double doubleValue = static_cast<double>(value); |
| 174 if (doubleValue >= static_cast<double>(max)) | 216 if (doubleValue >= static_cast<double>(max)) |
| 175 return max; | 217 return max; |
| 176 if (doubleValue <= static_cast<double>(min)) | 218 if (doubleValue <= static_cast<double>(min)) |
| 177 return min; | 219 return min; |
| 178 // If the limit type is integer, we might get better performance by | 220 // If the limit type is integer, we might get better performance by |
| 179 // casting |value| (as opposed to |doubleValue|) to the limit type. | 221 // casting |value| (as opposed to |doubleValue|) to the limit type. |
| 180 return std::numeric_limits<LimitType>::is_integer ? static_cast<LimitTyp
e>(value) : static_cast<LimitType>(doubleValue); | 222 return std::numeric_limits<LimitType>::is_integer ? static_cast<LimitType>(v
alue) : static_cast<LimitType>(doubleValue); |
| 181 } | 223 } |
| 182 }; | 224 }; |
| 183 | 225 |
| 184 // The unspecialized version of this templated class handles clamping to | 226 // The unspecialized version of this templated class handles clamping to |
| 185 // anything other than [unsigned] long long int limits. It simply uses the | 227 // anything other than [unsigned] long long int limits. It simply uses the |
| 186 // class above to toggle between the "fast" and "safe" clamp implementations. | 228 // class above to toggle between the "fast" and "safe" clamp implementations. |
| 187 template<typename LimitType, typename ValueType> class ClampToHelper { | 229 template <typename LimitType, typename ValueType> |
| 188 public: | 230 class ClampToHelper { |
| 189 static inline LimitType clampTo(ValueType value, LimitType min, LimitType ma
x) | 231 public: |
| 190 { | 232 static inline LimitType clampTo(ValueType value, LimitType min, LimitType max)
{ |
| 191 // We only use clampToDirectComparison() when the integerness and | 233 // We only use clampToDirectComparison() when the integerness and |
| 192 // signedness of the two types matches. | 234 // signedness of the two types matches. |
| 193 // | 235 // |
| 194 // If the integerness of the types doesn't match, then at best | 236 // If the integerness of the types doesn't match, then at best |
| 195 // clampToDirectComparison() won't be much more efficient than the | 237 // clampToDirectComparison() won't be much more efficient than the |
| 196 // cast-everything-to-double method, since we'll need to convert to | 238 // cast-everything-to-double method, since we'll need to convert to |
| 197 // floating point anyway; at worst, we risk incorrect results when | 239 // floating point anyway; at worst, we risk incorrect results when |
| 198 // clamping a float to a 32-bit integral type due to potential precision | 240 // clamping a float to a 32-bit integral type due to potential precision |
| 199 // loss. | 241 // loss. |
| 200 // | 242 // |
| 201 // If the signedness doesn't match, clampToDirectComparison() will | 243 // If the signedness doesn't match, clampToDirectComparison() will |
| 202 // produce warnings about comparing signed vs. unsigned, which are apt | 244 // produce warnings about comparing signed vs. unsigned, which are apt |
| 203 // since negative signed values will be converted to large unsigned ones | 245 // since negative signed values will be converted to large unsigned ones |
| 204 // and we'll get incorrect results. | 246 // and we'll get incorrect results. |
| 205 return ClampToNonLongLongHelper<std::numeric_limits<LimitType>::is_integ
er == std::numeric_limits<ValueType>::is_integer && std::numeric_limits<LimitTyp
e>::is_signed == std::numeric_limits<ValueType>::is_signed, LimitType, ValueType
>::clampTo(value, min, max); | 247 return ClampToNonLongLongHelper < std::numeric_limits<LimitType>::is_integer
== std::numeric_limits<ValueType>::is_integer && std::numeric_limits<LimitType>
::is_signed == std::numeric_limits<ValueType>::is_signed, LimitType, ValueType >
::clampTo(value, min, max); |
| 206 } | 248 } |
| 207 }; | 249 }; |
| 208 | 250 |
| 209 // Clamping to [unsigned] long long int limits requires more care. These may | 251 // Clamping to [unsigned] long long int limits requires more care. These may |
| 210 // not be accurately representable as doubles, so instead we cast |value| to the | 252 // not be accurately representable as doubles, so instead we cast |value| to the |
| 211 // limit type. But that cast is undefined if |value| is floating point and | 253 // limit type. But that cast is undefined if |value| is floating point and |
| 212 // outside the representable range of the limit type, so we also have to check | 254 // outside the representable range of the limit type, so we also have to check |
| 213 // for that case explicitly. | 255 // for that case explicitly. |
| 214 template<typename ValueType> class ClampToHelper<long long int, ValueType> { | 256 template <typename ValueType> |
| 215 public: | 257 class ClampToHelper<long long int, ValueType> { |
| 216 static inline long long int clampTo(ValueType value, long long int min, long
long int max) | 258 public: |
| 217 { | 259 static inline long long int clampTo(ValueType value, long long int min, long l
ong int max) { |
| 218 if (!std::numeric_limits<ValueType>::is_integer) { | 260 if (!std::numeric_limits<ValueType>::is_integer) { |
| 219 if (value > 0) { | 261 if (value > 0) { |
| 220 if (static_cast<double>(value) >= static_cast<double>(std::numer
ic_limits<long long int>::max())) | 262 if (static_cast<double>(value) >= static_cast<double>(std::numeric_limit
s<long long int>::max())) |
| 221 return max; | 263 return max; |
| 222 } else if (static_cast<double>(value) <= static_cast<double>(std::nu
meric_limits<long long int>::min())) { | 264 } else if (static_cast<double>(value) <= static_cast<double>(std::numeric_
limits<long long int>::min())) { |
| 223 return min; | 265 return min; |
| 224 } | 266 } |
| 225 } | |
| 226 // Note: If |value| were unsigned long long int, it could be larger than | |
| 227 // the largest long long int, and this code would be wrong; we handle | |
| 228 // this case with a separate full specialization below. | |
| 229 return clampToDirectComparison(static_cast<long long int>(value), min, m
ax); | |
| 230 } | 267 } |
| 268 // Note: If |value| were unsigned long long int, it could be larger than |
| 269 // the largest long long int, and this code would be wrong; we handle |
| 270 // this case with a separate full specialization below. |
| 271 return clampToDirectComparison(static_cast<long long int>(value), min, max); |
| 272 } |
| 231 }; | 273 }; |
| 232 | 274 |
| 233 // This specialization handles the case where the above partial specialization | 275 // This specialization handles the case where the above partial specialization |
| 234 // would be potentially incorrect. | 276 // would be potentially incorrect. |
| 235 template<> class ClampToHelper<long long int, unsigned long long int> { | 277 template <> |
| 236 public: | 278 class ClampToHelper<long long int, unsigned long long int> { |
| 237 static inline long long int clampTo(unsigned long long int value, long long
int min, long long int max) | 279 public: |
| 238 { | 280 static inline long long int clampTo(unsigned long long int value, long long in
t min, long long int max) { |
| 239 if (max <= 0 || value >= static_cast<unsigned long long int>(max)) | 281 if (max <= 0 || value >= static_cast<unsigned long long int>(max)) |
| 240 return max; | 282 return max; |
| 241 const long long int longLongValue = static_cast<long long int>(value); | 283 const long long int longLongValue = static_cast<long long int>(value); |
| 242 return (longLongValue <= min) ? min : longLongValue; | 284 return (longLongValue <= min) ? min : longLongValue; |
| 243 } | 285 } |
| 244 }; | 286 }; |
| 245 | 287 |
| 246 // This is similar to the partial specialization that clamps to long long int, | 288 // This is similar to the partial specialization that clamps to long long int, |
| 247 // but because the lower-bound check is done for integer value types as well, we | 289 // but because the lower-bound check is done for integer value types as well, we |
| 248 // don't need a <unsigned long long int, long long int> full specialization. | 290 // don't need a <unsigned long long int, long long int> full specialization. |
| 249 template<typename ValueType> class ClampToHelper<unsigned long long int, ValueTy
pe> { | 291 template <typename ValueType> |
| 250 public: | 292 class ClampToHelper<unsigned long long int, ValueType> { |
| 251 static inline unsigned long long int clampTo(ValueType value, unsigned long
long int min, unsigned long long int max) | 293 public: |
| 252 { | 294 static inline unsigned long long int clampTo(ValueType value, unsigned long lo
ng int min, unsigned long long int max) { |
| 253 if (value <= 0) | 295 if (value <= 0) |
| 254 return min; | 296 return min; |
| 255 if (!std::numeric_limits<ValueType>::is_integer) { | 297 if (!std::numeric_limits<ValueType>::is_integer) { |
| 256 if (static_cast<double>(value) >= static_cast<double>(std::numeric_l
imits<unsigned long long int>::max())) | 298 if (static_cast<double>(value) >= static_cast<double>(std::numeric_limits<
unsigned long long int>::max())) |
| 257 return max; | 299 return max; |
| 258 } | |
| 259 return clampToDirectComparison(static_cast<unsigned long long int>(value
), min, max); | |
| 260 } | 300 } |
| 301 return clampToDirectComparison(static_cast<unsigned long long int>(value), m
in, max); |
| 302 } |
| 261 }; | 303 }; |
| 262 | 304 |
| 263 template<typename T> inline T defaultMaximumForClamp() { return std::numeric_lim
its<T>::max(); } | 305 template <typename T> |
| 306 inline T defaultMaximumForClamp() { |
| 307 return std::numeric_limits<T>::max(); |
| 308 } |
| 264 // This basically reimplements C++11's std::numeric_limits<T>::lowest(). | 309 // This basically reimplements C++11's std::numeric_limits<T>::lowest(). |
| 265 template<typename T> inline T defaultMinimumForClamp() { return std::numeric_lim
its<T>::min(); } | 310 template <typename T> |
| 266 template<> inline float defaultMinimumForClamp<float>() { return -std::numeric_l
imits<float>::max(); } | 311 inline T defaultMinimumForClamp() { |
| 267 template<> inline double defaultMinimumForClamp<double>() { return -std::numeric
_limits<double>::max(); } | 312 return std::numeric_limits<T>::min(); |
| 313 } |
| 314 template <> |
| 315 inline float defaultMinimumForClamp<float>() { |
| 316 return -std::numeric_limits<float>::max(); |
| 317 } |
| 318 template <> |
| 319 inline double defaultMinimumForClamp<double>() { |
| 320 return -std::numeric_limits<double>::max(); |
| 321 } |
| 268 | 322 |
| 269 // And, finally, the actual function for people to call. | 323 // And, finally, the actual function for people to call. |
| 270 template<typename LimitType, typename ValueType> inline LimitType clampTo(ValueT
ype value, LimitType min = defaultMinimumForClamp<LimitType>(), LimitType max =
defaultMaximumForClamp<LimitType>()) | 324 template <typename LimitType, typename ValueType> |
| 271 { | 325 inline LimitType clampTo(ValueType value, LimitType min = defaultMinimumForClamp
<LimitType>(), LimitType max = defaultMaximumForClamp<LimitType>()) { |
| 272 ASSERT(!std::isnan(static_cast<double>(value))); | 326 ASSERT(!std::isnan(static_cast<double>(value))); |
| 273 ASSERT(min <= max); // This also ensures |min| and |max| aren't NaN. | 327 ASSERT(min <= max); // This also ensures |min| and |max| aren't NaN. |
| 274 return ClampToHelper<LimitType, ValueType>::clampTo(value, min, max); | 328 return ClampToHelper<LimitType, ValueType>::clampTo(value, min, max); |
| 275 } | 329 } |
| 276 | 330 |
| 277 inline bool isWithinIntRange(float x) | 331 inline bool isWithinIntRange(float x) { |
| 278 { | 332 return x > static_cast<float>(std::numeric_limits<int>::min()) && x < static_c
ast<float>(std::numeric_limits<int>::max()); |
| 279 return x > static_cast<float>(std::numeric_limits<int>::min()) && x < static
_cast<float>(std::numeric_limits<int>::max()); | |
| 280 } | 333 } |
| 281 | 334 |
| 282 static size_t greatestCommonDivisor(size_t a, size_t b) | 335 static size_t greatestCommonDivisor(size_t a, size_t b) { |
| 283 { | 336 return b ? greatestCommonDivisor(b, a % b) : a; |
| 284 return b ? greatestCommonDivisor(b, a % b) : a; | |
| 285 } | 337 } |
| 286 | 338 |
| 287 inline size_t lowestCommonMultiple(size_t a, size_t b) | 339 inline size_t lowestCommonMultiple(size_t a, size_t b) { |
| 288 { | 340 return a && b ? a / greatestCommonDivisor(a, b) * b : 0; |
| 289 return a && b ? a / greatestCommonDivisor(a, b) * b : 0; | |
| 290 } | 341 } |
| 291 | 342 |
| 292 #ifndef UINT64_C | 343 #ifndef UINT64_C |
| 293 #if COMPILER(MSVC) | 344 #if COMPILER(MSVC) |
| 294 #define UINT64_C(c) c ## ui64 | 345 #define UINT64_C(c) c##ui64 |
| 295 #else | 346 #else |
| 296 #define UINT64_C(c) c ## ull | 347 #define UINT64_C(c) c##ull |
| 297 #endif | 348 #endif |
| 298 #endif | 349 #endif |
| 299 | 350 |
| 300 // Calculate d % 2^{64}. | 351 // Calculate d % 2^{64}. |
| 301 inline void doubleToInteger(double d, unsigned long long& value) | 352 inline void doubleToInteger(double d, unsigned long long& value) { |
| 302 { | 353 if (std::isnan(d) || std::isinf(d)) { |
| 303 if (std::isnan(d) || std::isinf(d)) { | 354 value = 0; |
| 304 value = 0; | 355 } else { |
| 356 // -2^{64} < fmodValue < 2^{64}. |
| 357 double fmodValue = fmod(trunc(d), std::numeric_limits<unsigned long long>::m
ax() + 1.0); |
| 358 if (fmodValue >= 0) { |
| 359 // 0 <= fmodValue < 2^{64}. |
| 360 // 0 <= value < 2^{64}. This cast causes no loss. |
| 361 value = static_cast<unsigned long long>(fmodValue); |
| 305 } else { | 362 } else { |
| 306 // -2^{64} < fmodValue < 2^{64}. | 363 // -2^{64} < fmodValue < 0. |
| 307 double fmodValue = fmod(trunc(d), std::numeric_limits<unsigned long long
>::max() + 1.0); | 364 // 0 < fmodValueInUnsignedLongLong < 2^{64}. This cast causes no loss. |
| 308 if (fmodValue >= 0) { | 365 unsigned long long fmodValueInUnsignedLongLong = static_cast<unsigned long
long>(-fmodValue); |
| 309 // 0 <= fmodValue < 2^{64}. | 366 // -1 < (std::numeric_limits<unsigned long long>::max() - fmodValueInUnsig
nedLongLong) < 2^{64} - 1. |
| 310 // 0 <= value < 2^{64}. This cast causes no loss. | 367 // 0 < value < 2^{64}. |
| 311 value = static_cast<unsigned long long>(fmodValue); | 368 value = std::numeric_limits<unsigned long long>::max() - fmodValueInUnsign
edLongLong + 1; |
| 312 } else { | |
| 313 // -2^{64} < fmodValue < 0. | |
| 314 // 0 < fmodValueInUnsignedLongLong < 2^{64}. This cast causes no los
s. | |
| 315 unsigned long long fmodValueInUnsignedLongLong = static_cast<unsigne
d long long>(-fmodValue); | |
| 316 // -1 < (std::numeric_limits<unsigned long long>::max() - fmodValueI
nUnsignedLongLong) < 2^{64} - 1. | |
| 317 // 0 < value < 2^{64}. | |
| 318 value = std::numeric_limits<unsigned long long>::max() - fmodValueIn
UnsignedLongLong + 1; | |
| 319 } | |
| 320 } | 369 } |
| 370 } |
| 321 } | 371 } |
| 322 | 372 |
| 323 namespace WTF { | 373 namespace WTF { |
| 324 | 374 |
| 325 inline unsigned fastLog2(unsigned i) | 375 inline unsigned fastLog2(unsigned i) { |
| 326 { | 376 unsigned log2 = 0; |
| 327 unsigned log2 = 0; | 377 if (i & (i - 1)) |
| 328 if (i & (i - 1)) | 378 log2 += 1; |
| 329 log2 += 1; | 379 if (i >> 16) |
| 330 if (i >> 16) | 380 log2 += 16, i >>= 16; |
| 331 log2 += 16, i >>= 16; | 381 if (i >> 8) |
| 332 if (i >> 8) | 382 log2 += 8, i >>= 8; |
| 333 log2 += 8, i >>= 8; | 383 if (i >> 4) |
| 334 if (i >> 4) | 384 log2 += 4, i >>= 4; |
| 335 log2 += 4, i >>= 4; | 385 if (i >> 2) |
| 336 if (i >> 2) | 386 log2 += 2, i >>= 2; |
| 337 log2 += 2, i >>= 2; | 387 if (i >> 1) |
| 338 if (i >> 1) | 388 log2 += 1; |
| 339 log2 += 1; | 389 return log2; |
| 340 return log2; | |
| 341 } | 390 } |
| 342 | 391 |
| 343 } // namespace WTF | 392 } // namespace WTF |
| 344 | 393 |
| 345 #endif // #ifndef WTF_MathExtras_h | 394 #endif // #ifndef WTF_MathExtras_h |
| OLD | NEW |