| OLD | NEW |
| 1 /* | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 * | 3 // found in the LICENSE file. |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * 1. Redistributions of source code must retain the above copyright | |
| 8 * notice, this list of conditions and the following disclaimer. | |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 * notice, this list of conditions and the following disclaimer in the | |
| 11 * documentation and/or other materials provided with the distribution. | |
| 12 * | |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 24 */ | |
| 25 | 4 |
| 26 #ifndef WTF_MathExtras_h | 5 #include "platform/wtf/MathExtras.h" |
| 27 #define WTF_MathExtras_h | |
| 28 | 6 |
| 29 #include "wtf/Allocator.h" | 7 // The contents of this header was moved to platform/wtf as part of |
| 30 #include "wtf/Assertions.h" | 8 // WTF migration project. See the following post for details: |
| 31 #include "wtf/CPU.h" | 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY
CAAJ |
| 32 #include <cmath> | |
| 33 #include <cstddef> | |
| 34 #include <limits> | |
| 35 | |
| 36 #if COMPILER(MSVC) | |
| 37 // Make math.h behave like other platforms. | |
| 38 #define _USE_MATH_DEFINES | |
| 39 // Even if math.h was already included, including math.h again with | |
| 40 // _USE_MATH_DEFINES adds the extra defines. | |
| 41 #include <math.h> | |
| 42 #include <stdint.h> | |
| 43 #endif | |
| 44 | |
| 45 #if OS(OPENBSD) | |
| 46 #include <machine/ieee.h> | |
| 47 #include <sys/types.h> | |
| 48 #endif | |
| 49 | |
| 50 const double piDouble = M_PI; | |
| 51 const float piFloat = static_cast<float>(M_PI); | |
| 52 | |
| 53 const double piOverTwoDouble = M_PI_2; | |
| 54 const float piOverTwoFloat = static_cast<float>(M_PI_2); | |
| 55 | |
| 56 const double piOverFourDouble = M_PI_4; | |
| 57 const float piOverFourFloat = static_cast<float>(M_PI_4); | |
| 58 | |
| 59 const double twoPiDouble = piDouble * 2.0; | |
| 60 const float twoPiFloat = piFloat * 2.0f; | |
| 61 | |
| 62 #if COMPILER(MSVC) | |
| 63 | |
| 64 // VS2013 has most of the math functions now, but we still need to work | |
| 65 // around various differences in behavior of Inf. | |
| 66 | |
| 67 // Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN | |
| 68 // instead of specific values. | |
| 69 inline double wtf_atan2(double x, double y) { | |
| 70 double posInf = std::numeric_limits<double>::infinity(); | |
| 71 double negInf = -std::numeric_limits<double>::infinity(); | |
| 72 double nan = std::numeric_limits<double>::quiet_NaN(); | |
| 73 | |
| 74 double result = nan; | |
| 75 | |
| 76 if (x == posInf && y == posInf) | |
| 77 result = piOverFourDouble; | |
| 78 else if (x == posInf && y == negInf) | |
| 79 result = 3 * piOverFourDouble; | |
| 80 else if (x == negInf && y == posInf) | |
| 81 result = -piOverFourDouble; | |
| 82 else if (x == negInf && y == negInf) | |
| 83 result = -3 * piOverFourDouble; | |
| 84 else | |
| 85 result = ::atan2(x, y); | |
| 86 | |
| 87 return result; | |
| 88 } | |
| 89 | |
| 90 // Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN | |
| 91 // instead of x. | |
| 92 inline double wtf_fmod(double x, double y) { | |
| 93 return (!std::isinf(x) && std::isinf(y)) ? x : fmod(x, y); | |
| 94 } | |
| 95 | |
| 96 // Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead | |
| 97 // of 1. | |
| 98 inline double wtf_pow(double x, double y) { | |
| 99 return y == 0 ? 1 : pow(x, y); | |
| 100 } | |
| 101 | |
| 102 #define atan2(x, y) wtf_atan2(x, y) | |
| 103 #define fmod(x, y) wtf_fmod(x, y) | |
| 104 #define pow(x, y) wtf_pow(x, y) | |
| 105 | |
| 106 #endif // COMPILER(MSVC) | |
| 107 | |
| 108 inline double deg2rad(double d) { | |
| 109 return d * piDouble / 180.0; | |
| 110 } | |
| 111 inline double rad2deg(double r) { | |
| 112 return r * 180.0 / piDouble; | |
| 113 } | |
| 114 inline double deg2grad(double d) { | |
| 115 return d * 400.0 / 360.0; | |
| 116 } | |
| 117 inline double grad2deg(double g) { | |
| 118 return g * 360.0 / 400.0; | |
| 119 } | |
| 120 inline double turn2deg(double t) { | |
| 121 return t * 360.0; | |
| 122 } | |
| 123 inline double deg2turn(double d) { | |
| 124 return d / 360.0; | |
| 125 } | |
| 126 inline double rad2grad(double r) { | |
| 127 return r * 200.0 / piDouble; | |
| 128 } | |
| 129 inline double grad2rad(double g) { | |
| 130 return g * piDouble / 200.0; | |
| 131 } | |
| 132 inline double turn2grad(double t) { | |
| 133 return t * 400; | |
| 134 } | |
| 135 inline double grad2turn(double g) { | |
| 136 return g / 400; | |
| 137 } | |
| 138 | |
| 139 inline float deg2rad(float d) { | |
| 140 return d * piFloat / 180.0f; | |
| 141 } | |
| 142 inline float rad2deg(float r) { | |
| 143 return r * 180.0f / piFloat; | |
| 144 } | |
| 145 inline float deg2grad(float d) { | |
| 146 return d * 400.0f / 360.0f; | |
| 147 } | |
| 148 inline float grad2deg(float g) { | |
| 149 return g * 360.0f / 400.0f; | |
| 150 } | |
| 151 inline float turn2deg(float t) { | |
| 152 return t * 360.0f; | |
| 153 } | |
| 154 inline float deg2turn(float d) { | |
| 155 return d / 360.0f; | |
| 156 } | |
| 157 inline float rad2grad(float r) { | |
| 158 return r * 200.0f / piFloat; | |
| 159 } | |
| 160 inline float grad2rad(float g) { | |
| 161 return g * piFloat / 200.0f; | |
| 162 } | |
| 163 inline float turn2grad(float t) { | |
| 164 return t * 400; | |
| 165 } | |
| 166 inline float grad2turn(float g) { | |
| 167 return g / 400; | |
| 168 } | |
| 169 | |
| 170 // clampTo() is implemented by templated helper classes (to allow for partial | |
| 171 // template specialization) as well as several helper functions. | |
| 172 | |
| 173 // This helper function can be called when we know that: | |
| 174 // (1) The type signednesses match so the compiler will not produce signed vs. | |
| 175 // unsigned warnings | |
| 176 // (2) The default type promotions/conversions are sufficient to handle things | |
| 177 // correctly | |
| 178 template <typename LimitType, typename ValueType> | |
| 179 inline LimitType clampToDirectComparison(ValueType value, | |
| 180 LimitType min, | |
| 181 LimitType max) { | |
| 182 if (value >= max) | |
| 183 return max; | |
| 184 return (value <= min) ? min : static_cast<LimitType>(value); | |
| 185 } | |
| 186 | |
| 187 // For any floating-point limits, or integral limits smaller than long long, we | |
| 188 // can cast the limits to double without losing precision; then the only cases | |
| 189 // where |value| can't be represented accurately as a double are the ones where | |
| 190 // it's outside the limit range anyway. So doing all comparisons as doubles | |
| 191 // will give correct results. | |
| 192 // | |
| 193 // In some cases, we can get better performance by using | |
| 194 // clampToDirectComparison(). We use a templated class to switch between these | |
| 195 // two cases (instead of simply using a conditional within one function) in | |
| 196 // order to only compile the clampToDirectComparison() code for cases where it | |
| 197 // will actually be used; this prevents the compiler from emitting warnings | |
| 198 // about unsafe code (even though we wouldn't actually be executing that code). | |
| 199 template <bool canUseDirectComparison, typename LimitType, typename ValueType> | |
| 200 class ClampToNonLongLongHelper; | |
| 201 template <typename LimitType, typename ValueType> | |
| 202 class ClampToNonLongLongHelper<true, LimitType, ValueType> { | |
| 203 STATIC_ONLY(ClampToNonLongLongHelper); | |
| 204 | |
| 205 public: | |
| 206 static inline LimitType clampTo(ValueType value, | |
| 207 LimitType min, | |
| 208 LimitType max) { | |
| 209 return clampToDirectComparison(value, min, max); | |
| 210 } | |
| 211 }; | |
| 212 | |
| 213 template <typename LimitType, typename ValueType> | |
| 214 class ClampToNonLongLongHelper<false, LimitType, ValueType> { | |
| 215 STATIC_ONLY(ClampToNonLongLongHelper); | |
| 216 | |
| 217 public: | |
| 218 static inline LimitType clampTo(ValueType value, | |
| 219 LimitType min, | |
| 220 LimitType max) { | |
| 221 const double doubleValue = static_cast<double>(value); | |
| 222 if (doubleValue >= static_cast<double>(max)) | |
| 223 return max; | |
| 224 if (doubleValue <= static_cast<double>(min)) | |
| 225 return min; | |
| 226 // If the limit type is integer, we might get better performance by | |
| 227 // casting |value| (as opposed to |doubleValue|) to the limit type. | |
| 228 return std::numeric_limits<LimitType>::is_integer | |
| 229 ? static_cast<LimitType>(value) | |
| 230 : static_cast<LimitType>(doubleValue); | |
| 231 } | |
| 232 }; | |
| 233 | |
| 234 // The unspecialized version of this templated class handles clamping to | |
| 235 // anything other than [unsigned] long long int limits. It simply uses the | |
| 236 // class above to toggle between the "fast" and "safe" clamp implementations. | |
| 237 template <typename LimitType, typename ValueType> | |
| 238 class ClampToHelper { | |
| 239 public: | |
| 240 static inline LimitType clampTo(ValueType value, | |
| 241 LimitType min, | |
| 242 LimitType max) { | |
| 243 // We only use clampToDirectComparison() when the integerness and | |
| 244 // signedness of the two types matches. | |
| 245 // | |
| 246 // If the integerness of the types doesn't match, then at best | |
| 247 // clampToDirectComparison() won't be much more efficient than the | |
| 248 // cast-everything-to-double method, since we'll need to convert to | |
| 249 // floating point anyway; at worst, we risk incorrect results when | |
| 250 // clamping a float to a 32-bit integral type due to potential precision | |
| 251 // loss. | |
| 252 // | |
| 253 // If the signedness doesn't match, clampToDirectComparison() will | |
| 254 // produce warnings about comparing signed vs. unsigned, which are apt | |
| 255 // since negative signed values will be converted to large unsigned ones | |
| 256 // and we'll get incorrect results. | |
| 257 return ClampToNonLongLongHelper < | |
| 258 std::numeric_limits<LimitType>::is_integer == | |
| 259 std::numeric_limits<ValueType>::is_integer && | |
| 260 std::numeric_limits<LimitType>::is_signed == | |
| 261 std::numeric_limits<ValueType>::is_signed, | |
| 262 LimitType, ValueType > ::clampTo(value, min, max); | |
| 263 } | |
| 264 }; | |
| 265 | |
| 266 // Clamping to [unsigned] long long int limits requires more care. These may | |
| 267 // not be accurately representable as doubles, so instead we cast |value| to the | |
| 268 // limit type. But that cast is undefined if |value| is floating point and | |
| 269 // outside the representable range of the limit type, so we also have to check | |
| 270 // for that case explicitly. | |
| 271 template <typename ValueType> | |
| 272 class ClampToHelper<long long int, ValueType> { | |
| 273 STATIC_ONLY(ClampToHelper); | |
| 274 | |
| 275 public: | |
| 276 static inline long long int clampTo(ValueType value, | |
| 277 long long int min, | |
| 278 long long int max) { | |
| 279 if (!std::numeric_limits<ValueType>::is_integer) { | |
| 280 if (value > 0) { | |
| 281 if (static_cast<double>(value) >= | |
| 282 static_cast<double>(std::numeric_limits<long long int>::max())) | |
| 283 return max; | |
| 284 } else if (static_cast<double>(value) <= | |
| 285 static_cast<double>( | |
| 286 std::numeric_limits<long long int>::min())) { | |
| 287 return min; | |
| 288 } | |
| 289 } | |
| 290 // Note: If |value| were unsigned long long int, it could be larger than | |
| 291 // the largest long long int, and this code would be wrong; we handle | |
| 292 // this case with a separate full specialization below. | |
| 293 return clampToDirectComparison(static_cast<long long int>(value), min, max); | |
| 294 } | |
| 295 }; | |
| 296 | |
| 297 // This specialization handles the case where the above partial specialization | |
| 298 // would be potentially incorrect. | |
| 299 template <> | |
| 300 class ClampToHelper<long long int, unsigned long long int> { | |
| 301 STATIC_ONLY(ClampToHelper); | |
| 302 | |
| 303 public: | |
| 304 static inline long long int clampTo(unsigned long long int value, | |
| 305 long long int min, | |
| 306 long long int max) { | |
| 307 if (max <= 0 || value >= static_cast<unsigned long long int>(max)) | |
| 308 return max; | |
| 309 const long long int longLongValue = static_cast<long long int>(value); | |
| 310 return (longLongValue <= min) ? min : longLongValue; | |
| 311 } | |
| 312 }; | |
| 313 | |
| 314 // This is similar to the partial specialization that clamps to long long int, | |
| 315 // but because the lower-bound check is done for integer value types as well, we | |
| 316 // don't need a <unsigned long long int, long long int> full specialization. | |
| 317 template <typename ValueType> | |
| 318 class ClampToHelper<unsigned long long int, ValueType> { | |
| 319 STATIC_ONLY(ClampToHelper); | |
| 320 | |
| 321 public: | |
| 322 static inline unsigned long long int clampTo(ValueType value, | |
| 323 unsigned long long int min, | |
| 324 unsigned long long int max) { | |
| 325 if (value <= 0) | |
| 326 return min; | |
| 327 if (!std::numeric_limits<ValueType>::is_integer) { | |
| 328 if (static_cast<double>(value) >= | |
| 329 static_cast<double>( | |
| 330 std::numeric_limits<unsigned long long int>::max())) | |
| 331 return max; | |
| 332 } | |
| 333 return clampToDirectComparison(static_cast<unsigned long long int>(value), | |
| 334 min, max); | |
| 335 } | |
| 336 }; | |
| 337 | |
| 338 template <typename T> | |
| 339 inline T defaultMaximumForClamp() { | |
| 340 return std::numeric_limits<T>::max(); | |
| 341 } | |
| 342 // This basically reimplements C++11's std::numeric_limits<T>::lowest(). | |
| 343 template <typename T> | |
| 344 inline T defaultMinimumForClamp() { | |
| 345 return std::numeric_limits<T>::min(); | |
| 346 } | |
| 347 template <> | |
| 348 inline float defaultMinimumForClamp<float>() { | |
| 349 return -std::numeric_limits<float>::max(); | |
| 350 } | |
| 351 template <> | |
| 352 inline double defaultMinimumForClamp<double>() { | |
| 353 return -std::numeric_limits<double>::max(); | |
| 354 } | |
| 355 | |
| 356 // And, finally, the actual function for people to call. | |
| 357 template <typename LimitType, typename ValueType> | |
| 358 inline LimitType clampTo(ValueType value, | |
| 359 LimitType min = defaultMinimumForClamp<LimitType>(), | |
| 360 LimitType max = defaultMaximumForClamp<LimitType>()) { | |
| 361 DCHECK(!std::isnan(static_cast<double>(value))); | |
| 362 DCHECK_LE(min, max); // This also ensures |min| and |max| aren't NaN. | |
| 363 return ClampToHelper<LimitType, ValueType>::clampTo(value, min, max); | |
| 364 } | |
| 365 | |
| 366 inline bool isWithinIntRange(float x) { | |
| 367 return x > static_cast<float>(std::numeric_limits<int>::min()) && | |
| 368 x < static_cast<float>(std::numeric_limits<int>::max()); | |
| 369 } | |
| 370 | |
| 371 static size_t greatestCommonDivisor(size_t a, size_t b) { | |
| 372 return b ? greatestCommonDivisor(b, a % b) : a; | |
| 373 } | |
| 374 | |
| 375 inline size_t lowestCommonMultiple(size_t a, size_t b) { | |
| 376 return a && b ? a / greatestCommonDivisor(a, b) * b : 0; | |
| 377 } | |
| 378 | |
| 379 #ifndef UINT64_C | |
| 380 #if COMPILER(MSVC) | |
| 381 #define UINT64_C(c) c##ui64 | |
| 382 #else | |
| 383 #define UINT64_C(c) c##ull | |
| 384 #endif | |
| 385 #endif | |
| 386 | |
| 387 // Calculate d % 2^{64}. | |
| 388 inline void doubleToInteger(double d, unsigned long long& value) { | |
| 389 if (std::isnan(d) || std::isinf(d)) { | |
| 390 value = 0; | |
| 391 } else { | |
| 392 // -2^{64} < fmodValue < 2^{64}. | |
| 393 double fmodValue = | |
| 394 fmod(trunc(d), std::numeric_limits<unsigned long long>::max() + 1.0); | |
| 395 if (fmodValue >= 0) { | |
| 396 // 0 <= fmodValue < 2^{64}. | |
| 397 // 0 <= value < 2^{64}. This cast causes no loss. | |
| 398 value = static_cast<unsigned long long>(fmodValue); | |
| 399 } else { | |
| 400 // -2^{64} < fmodValue < 0. | |
| 401 // 0 < fmodValueInUnsignedLongLong < 2^{64}. This cast causes no loss. | |
| 402 unsigned long long fmodValueInUnsignedLongLong = | |
| 403 static_cast<unsigned long long>(-fmodValue); | |
| 404 // -1 < (std::numeric_limits<unsigned long long>::max() - | |
| 405 // fmodValueInUnsignedLongLong) | |
| 406 // < 2^{64} - 1. | |
| 407 // 0 < value < 2^{64}. | |
| 408 value = std::numeric_limits<unsigned long long>::max() - | |
| 409 fmodValueInUnsignedLongLong + 1; | |
| 410 } | |
| 411 } | |
| 412 } | |
| 413 | |
| 414 namespace WTF { | |
| 415 | |
| 416 inline unsigned fastLog2(unsigned i) { | |
| 417 unsigned log2 = 0; | |
| 418 if (i & (i - 1)) | |
| 419 log2 += 1; | |
| 420 if (i >> 16) | |
| 421 log2 += 16, i >>= 16; | |
| 422 if (i >> 8) | |
| 423 log2 += 8, i >>= 8; | |
| 424 if (i >> 4) | |
| 425 log2 += 4, i >>= 4; | |
| 426 if (i >> 2) | |
| 427 log2 += 2, i >>= 2; | |
| 428 if (i >> 1) | |
| 429 log2 += 1; | |
| 430 return log2; | |
| 431 } | |
| 432 | |
| 433 } // namespace WTF | |
| 434 | |
| 435 #endif // #ifndef WTF_MathExtras_h | |
| OLD | NEW |