Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: Source/wtf/MathExtras.h

Issue 653293003: CL for perf tryjob (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/css/resolver/AnimatedStyleBuilder.cpp ('k') | Source/wtf/MathExtrasTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #ifndef WTF_MathExtras_h 26 #ifndef WTF_MathExtras_h
27 #define WTF_MathExtras_h 27 #define WTF_MathExtras_h
28 28
29 #include "wtf/Assertions.h"
29 #include "wtf/CPU.h" 30 #include "wtf/CPU.h"
31 #include <algorithm>
30 #include <cmath> 32 #include <cmath>
31 #include <limits> 33 #include <limits>
32 34
33 #if COMPILER(MSVC) 35 #if COMPILER(MSVC)
34 #include "wtf/Assertions.h"
35 #include <stdint.h> 36 #include <stdint.h>
36 #endif 37 #endif
37 38
38 #if OS(OPENBSD) 39 #if OS(OPENBSD)
39 #include <sys/types.h> 40 #include <sys/types.h>
40 #include <machine/ieee.h> 41 #include <machine/ieee.h>
41 #endif 42 #endif
42 43
43 const double piDouble = M_PI; 44 const double piDouble = M_PI;
44 const float piFloat = static_cast<float>(M_PI); 45 const float piFloat = static_cast<float>(M_PI);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 inline float rad2deg(float r) { return r * 180.0f / piFloat; } 216 inline float rad2deg(float r) { return r * 180.0f / piFloat; }
216 inline float deg2grad(float d) { return d * 400.0f / 360.0f; } 217 inline float deg2grad(float d) { return d * 400.0f / 360.0f; }
217 inline float grad2deg(float g) { return g * 360.0f / 400.0f; } 218 inline float grad2deg(float g) { return g * 360.0f / 400.0f; }
218 inline float turn2deg(float t) { return t * 360.0f; } 219 inline float turn2deg(float t) { return t * 360.0f; }
219 inline float deg2turn(float d) { return d / 360.0f; } 220 inline float deg2turn(float d) { return d / 360.0f; }
220 inline float rad2grad(float r) { return r * 200.0f / piFloat; } 221 inline float rad2grad(float r) { return r * 200.0f / piFloat; }
221 inline float grad2rad(float g) { return g * piFloat / 200.0f; } 222 inline float grad2rad(float g) { return g * piFloat / 200.0f; }
222 inline float turn2grad(float t) { return t * 400; } 223 inline float turn2grad(float t) { return t * 400; }
223 inline float grad2turn(float g) { return g / 400; } 224 inline float grad2turn(float g) { return g / 400; }
224 225
225 // std::numeric_limits<T>::min() returns the smallest positive value for floatin g point types 226 // clampTo() is implemented by templated helper classes (to allow for partial
226 template<typename T> inline T defaultMinimumForClamp() { return std::numeric_lim its<T>::min(); } 227 // template specialization) as well as several helper functions.
227 template<> inline float defaultMinimumForClamp() { return -std::numeric_limits<f loat>::max(); }
228 template<> inline double defaultMinimumForClamp() { return -std::numeric_limits< double>::max(); }
229 template<typename T> inline T defaultMaximumForClamp() { return std::numeric_lim its<T>::max(); }
230 228
231 template<typename T> inline T clampTo(double value, T min = defaultMinimumForCla mp<T>(), T max = defaultMaximumForClamp<T>()) 229 // This helper function can be called when we know that:
230 // (1) The type signednesses match so the compiler will not produce signed vs.
231 // unsigned warnings
232 // (2) The default type promotions/conversions are sufficient to handle things
233 // correctly
234 template<typename LimitType, typename ValueType> inline LimitType clampToDirectC omparison(ValueType value, LimitType min, LimitType max)
232 { 235 {
233 if (value >= static_cast<double>(max)) 236 if (value >= max)
234 return max; 237 return max;
235 if (value <= static_cast<double>(min)) 238 return (value <= min) ? min : static_cast<LimitType>(value);
236 return min;
237 return static_cast<T>(value);
238 }
239 template<> inline long long int clampTo(double, long long int, long long int); / / clampTo does not support long long ints.
240
241 inline int clampToInteger(double value)
242 {
243 return clampTo<int>(value);
244 } 239 }
245 240
246 inline unsigned clampToUnsigned(double value) 241 // For any floating-point limits, or integral limits smaller than long long, we
242 // can cast the limits to double without losing precision; then the only cases
243 // where |value| can't be represented accurately as a double are the ones where
244 // it's outside the limit range anyway. So doing all comparisons as doubles
245 // will give correct results.
246 //
247 // In some cases, we can get better performance by using
248 // clampToDirectComparison(). We use a templated class to switch between these
249 // two cases (instead of simply using a conditional within one function) in
250 // order to only compile the clampToDirectComparison() code for cases where it
251 // will actually be used; this prevents the compiler from emitting warnings
252 // about unsafe code (even though we wouldn't actually be executing that code).
253 template<bool canUseDirectComparison, typename LimitType, typename ValueType> cl ass ClampToNonLongLongHelper;
254 template<typename LimitType, typename ValueType> class ClampToNonLongLongHelper< true, LimitType, ValueType> {
255 public:
256 static inline LimitType clampTo(ValueType value, LimitType min, LimitType ma x)
257 {
258 return clampToDirectComparison(value, min, max);
259 }
260 };
261
262 template<typename LimitType, typename ValueType> class ClampToNonLongLongHelper< false, LimitType, ValueType> {
263 public:
264 static inline LimitType clampTo(ValueType value, LimitType min, LimitType ma x)
265 {
266 const double doubleValue = static_cast<double>(value);
267 if (doubleValue >= static_cast<double>(max))
268 return max;
269 if (doubleValue <= static_cast<double>(min))
270 return min;
271 // If the limit type is integer, we might get better performance by
272 // casting |value| (as opposed to |doubleValue|) to the limit type.
273 return std::numeric_limits<LimitType>::is_integer ? static_cast<LimitTyp e>(value) : static_cast<LimitType>(doubleValue);
274 }
275 };
276
277 // The unspecialized version of this templated class handles clamping to
278 // anything other than [unsigned] long long int limits. It simply uses the
279 // class above to toggle between the "fast" and "safe" clamp implementations.
280 template<typename LimitType, typename ValueType> class ClampToHelper {
281 public:
282 static inline LimitType clampTo(ValueType value, LimitType min, LimitType ma x)
283 {
284 // We only use clampToDirectComparison() when the integerness and
285 // signedness of the two types matches.
286 //
287 // If the integerness of the types doesn't match, then at best
288 // clampToDirectComparison() won't be much more efficient than the
289 // cast-everything-to-double method, since we'll need to convert to
290 // floating point anyway; at worst, we risk incorrect results when
291 // clamping a float to a 32-bit integral type due to potential precision
292 // loss.
293 //
294 // If the signedness doesn't match, clampToDirectComparison() will
295 // produce warnings about comparing signed vs. unsigned, which are apt
296 // since negative signed values will be converted to large unsigned ones
297 // and we'll get incorrect results.
298 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);
299 }
300 };
301
302 // Clamping to [unsigned] long long int limits requires more care. These may
303 // not be accurately representable as doubles, so instead we cast |value| to the
304 // limit type. But that cast is undefined if |value| is floating point and
305 // outside the representable range of the limit type, so we also have to check
306 // for that case explicitly.
307 template<typename ValueType> class ClampToHelper<long long int, ValueType> {
308 public:
309 static inline long long int clampTo(ValueType value, long long int min, long long int max)
310 {
311 if (!std::numeric_limits<ValueType>::is_integer) {
312 if (value > 0) {
313 if (static_cast<double>(value) >= static_cast<double>(std::numer ic_limits<long long int>::max()))
314 return max;
315 } else if (static_cast<double>(value) <= static_cast<double>(std::nu meric_limits<long long int>::min())) {
316 return min;
317 }
318 }
319 // Note: If |value| were unsigned long long int, it could be larger than
320 // the largest long long int, and this code would be wrong; we handle
321 // this case with a separate full specialization below.
322 return clampToDirectComparison(static_cast<long long int>(value), min, m ax);
323 }
324 };
325
326 // This specialization handles the case where the above partial specialization
327 // would be potentially incorrect.
328 template<> class ClampToHelper<long long int, unsigned long long int> {
329 public:
330 static inline long long int clampTo(unsigned long long int value, long long int min, long long int max)
331 {
332 if (max <= 0 || value >= static_cast<unsigned long long int>(max))
333 return max;
334 const long long int longLongValue = static_cast<long long int>(value);
335 return (longLongValue <= min) ? min : longLongValue;
336 }
337 };
338
339 // This is similar to the partial specialization that clamps to long long int,
340 // but because the lower-bound check is done for integer value types as well, we
341 // don't need a <unsigned long long int, long long int> full specialization.
342 template<typename ValueType> class ClampToHelper<unsigned long long int, ValueTy pe> {
343 public:
344 static inline unsigned long long int clampTo(ValueType value, unsigned long long int min, unsigned long long int max)
345 {
346 if (value <= 0)
347 return min;
348 if (!std::numeric_limits<ValueType>::is_integer) {
349 if (static_cast<double>(value) >= static_cast<double>(std::numeric_l imits<unsigned long long int>::max()))
350 return max;
351 }
352 return clampToDirectComparison(static_cast<unsigned long long int>(value ), min, max);
353 }
354 };
355
356 // This basically reimplements C++11's std::numeric_limits<T>::lowest().
357 template<typename T> inline T defaultMinimumForClamp() { return std::numeric_lim its<T>::min(); }
358 template<> inline float defaultMinimumForClamp<float>() { return -std::numeric_l imits<float>::max(); }
359 template<> inline double defaultMinimumForClamp<double>() { return -std::numeric _limits<double>::max(); }
360
361 // And, finally, the actual function for people to call.
362 template<typename LimitType, typename ValueType> inline LimitType clampTo(ValueT ype value, LimitType min = defaultMinimumForClamp<LimitType>(), LimitType max = std::numeric_limits<LimitType>::max())
247 { 363 {
248 return clampTo<unsigned>(value); 364 ASSERT(!std::isnan(static_cast<double>(value)));
249 } 365 ASSERT(min <= max); // This also ensures |min| and |max| aren't NaN.
250 366 return ClampToHelper<LimitType, ValueType>::clampTo(value, min, max);
251 inline float clampToFloat(double value)
252 {
253 return clampTo<float>(value);
254 }
255
256 inline int clampToPositiveInteger(double value)
257 {
258 return clampTo<int>(value, 0);
259 }
260
261 inline int clampToInteger(float value)
262 {
263 return clampTo<int>(value);
264 }
265
266 inline int clampToInteger(unsigned x)
267 {
268 const unsigned intMax = static_cast<unsigned>(std::numeric_limits<int>::max( ));
269
270 if (x >= intMax)
271 return std::numeric_limits<int>::max();
272 return static_cast<int>(x);
273 } 367 }
274 368
275 inline bool isWithinIntRange(float x) 369 inline bool isWithinIntRange(float x)
276 { 370 {
277 return x > static_cast<float>(std::numeric_limits<int>::min()) && x < static _cast<float>(std::numeric_limits<int>::max()); 371 return x > static_cast<float>(std::numeric_limits<int>::min()) && x < static _cast<float>(std::numeric_limits<int>::max());
278 } 372 }
279 373
280 static size_t greatestCommonDivisor(size_t a, size_t b) 374 static size_t greatestCommonDivisor(size_t a, size_t b)
281 { 375 {
282 return b ? greatestCommonDivisor(b, a % b) : a; 376 return b ? greatestCommonDivisor(b, a % b) : a;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 if (i >> 2) 428 if (i >> 2)
335 log2 += 2, i >>= 2; 429 log2 += 2, i >>= 2;
336 if (i >> 1) 430 if (i >> 1)
337 log2 += 1; 431 log2 += 1;
338 return log2; 432 return log2;
339 } 433 }
340 434
341 } // namespace WTF 435 } // namespace WTF
342 436
343 #endif // #ifndef WTF_MathExtras_h 437 #endif // #ifndef WTF_MathExtras_h
OLDNEW
« no previous file with comments | « Source/core/css/resolver/AnimatedStyleBuilder.cpp ('k') | Source/wtf/MathExtrasTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698