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