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