OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011 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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 if (signsMatch(lhs, rhs)) { | 244 if (signsMatch(lhs, rhs)) { |
245 if (lhs >= 0) { | 245 if (lhs >= 0) { |
246 if ((std::numeric_limits<ResultType>::max() - rhs) < lhs) | 246 if ((std::numeric_limits<ResultType>::max() - rhs) < lhs) |
247 return false; | 247 return false; |
248 } else { | 248 } else { |
249 ResultType temp = lhs - std::numeric_limits<ResultType>::min(); | 249 ResultType temp = lhs - std::numeric_limits<ResultType>::min(); |
250 if (rhs < -temp) | 250 if (rhs < -temp) |
251 return false; | 251 return false; |
252 } | 252 } |
253 } // if the signs do not match this operation can't overflow | 253 } // if the signs do not match this operation can't overflow |
254 result = lhs + rhs; | 254 result = static_cast<ResultType>(lhs + rhs); |
255 return true; | 255 return true; |
256 } | 256 } |
257 | 257 |
258 static inline bool sub(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RET
URN | 258 static inline bool sub(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RET
URN |
259 { | 259 { |
260 if (!signsMatch(lhs, rhs)) { | 260 if (!signsMatch(lhs, rhs)) { |
261 if (lhs >= 0) { | 261 if (lhs >= 0) { |
262 if (lhs > std::numeric_limits<ResultType>::max() + rhs) | 262 if (lhs > std::numeric_limits<ResultType>::max() + rhs) |
263 return false; | 263 return false; |
264 } else { | 264 } else { |
265 if (rhs > std::numeric_limits<ResultType>::max() + lhs) | 265 if (rhs > std::numeric_limits<ResultType>::max() + lhs) |
266 return false; | 266 return false; |
267 } | 267 } |
268 } // if the signs match this operation can't overflow | 268 } // if the signs match this operation can't overflow |
269 result = lhs - rhs; | 269 result = static_cast<ResultType>(lhs - rhs); |
270 return true; | 270 return true; |
271 } | 271 } |
272 | 272 |
273 static inline bool multiply(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSE
D_RETURN | 273 static inline bool multiply(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSE
D_RETURN |
274 { | 274 { |
275 if (signsMatch(lhs, rhs)) { | 275 if (signsMatch(lhs, rhs)) { |
276 if (lhs >= 0) { | 276 if (lhs >= 0) { |
277 if (lhs && (std::numeric_limits<ResultType>::max() / lhs) < rhs) | 277 if (lhs && (std::numeric_limits<ResultType>::max() / lhs) < rhs) |
278 return false; | 278 return false; |
279 } else { | 279 } else { |
280 if (static_cast<ResultType>(lhs) == std::numeric_limits<ResultTy
pe>::min() || static_cast<ResultType>(rhs) == std::numeric_limits<ResultType>::m
in()) | 280 if (static_cast<ResultType>(lhs) == std::numeric_limits<ResultTy
pe>::min() || static_cast<ResultType>(rhs) == std::numeric_limits<ResultType>::m
in()) |
281 return false; | 281 return false; |
282 if ((std::numeric_limits<ResultType>::max() / -lhs) < -rhs) | 282 if ((std::numeric_limits<ResultType>::max() / -lhs) < -rhs) |
283 return false; | 283 return false; |
284 } | 284 } |
285 } else { | 285 } else { |
286 if (lhs < 0) { | 286 if (lhs < 0) { |
287 if (rhs && lhs < (std::numeric_limits<ResultType>::min() / rhs)) | 287 if (rhs && lhs < (std::numeric_limits<ResultType>::min() / rhs)) |
288 return false; | 288 return false; |
289 } else { | 289 } else { |
290 if (lhs && rhs < (std::numeric_limits<ResultType>::min() / lhs)) | 290 if (lhs && rhs < (std::numeric_limits<ResultType>::min() / lhs)) |
291 return false; | 291 return false; |
292 } | 292 } |
293 } | 293 } |
294 result = lhs * rhs; | 294 result = static_cast<ResultType>(lhs * rhs); |
295 return true; | 295 return true; |
296 } | 296 } |
297 | 297 |
298 static inline bool equals(LHS lhs, RHS rhs) { return lhs == rhs; } | 298 static inline bool equals(LHS lhs, RHS rhs) { return lhs == rhs; } |
299 | 299 |
300 }; | 300 }; |
301 | 301 |
302 template <typename LHS, typename RHS, typename ResultType> struct ArithmeticOper
ations<LHS, RHS, ResultType, false, false> { | 302 template <typename LHS, typename RHS, typename ResultType> struct ArithmeticOper
ations<LHS, RHS, ResultType, false, false> { |
303 // LHS and RHS are unsigned types so bounds checks are nice and easy | 303 // LHS and RHS are unsigned types so bounds checks are nice and easy |
304 static inline bool add(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RET
URN | 304 static inline bool add(LHS lhs, RHS rhs, ResultType& result) WARN_UNUSED_RET
URN |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 return Checked<U, OverflowHandler>(lhs) * rhs; | 707 return Checked<U, OverflowHandler>(lhs) * rhs; |
708 } | 708 } |
709 | 709 |
710 } | 710 } |
711 | 711 |
712 using WTF::Checked; | 712 using WTF::Checked; |
713 using WTF::CheckedState; | 713 using WTF::CheckedState; |
714 using WTF::RecordOverflow; | 714 using WTF::RecordOverflow; |
715 | 715 |
716 #endif | 716 #endif |
OLD | NEW |