1 /* 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 // Borrowed from Chromium's src/base/numerics/safe_conversions.h. 12 13 #ifndef WEBRTC_BASE_SAFE_CONVERSIONS_H_ 14 #define WEBRTC_BASE_SAFE_CONVERSIONS_H_ 15 16 #include <limits> 17 18 #include "webrtc/base/checks.h" 19 #include "webrtc/base/safe_conversions_impl.h" 20 21 namespace rtc { 22 23 // Convenience function that returns true if the supplied value is in range 24 // for the destination type. 25 template <typename Dst, typename Src> IsValueInRangeForNumericType(Src value)26inline bool IsValueInRangeForNumericType(Src value) { 27 return internal::RangeCheck<Dst>(value) == internal::TYPE_VALID; 28 } 29 30 // checked_cast<> is analogous to static_cast<> for numeric types, 31 // except that it CHECKs that the specified numeric conversion will not 32 // overflow or underflow. NaN source will always trigger a CHECK. 33 template <typename Dst, typename Src> checked_cast(Src value)34inline Dst checked_cast(Src value) { 35 RTC_CHECK(IsValueInRangeForNumericType<Dst>(value)); 36 return static_cast<Dst>(value); 37 } 38 39 // saturated_cast<> is analogous to static_cast<> for numeric types, except 40 // that the specified numeric conversion will saturate rather than overflow or 41 // underflow. NaN assignment to an integral will trigger a RTC_CHECK condition. 42 template <typename Dst, typename Src> saturated_cast(Src value)43inline Dst saturated_cast(Src value) { 44 // Optimization for floating point values, which already saturate. 45 if (std::numeric_limits<Dst>::is_iec559) 46 return static_cast<Dst>(value); 47 48 switch (internal::RangeCheck<Dst>(value)) { 49 case internal::TYPE_VALID: 50 return static_cast<Dst>(value); 51 52 case internal::TYPE_UNDERFLOW: 53 return std::numeric_limits<Dst>::min(); 54 55 case internal::TYPE_OVERFLOW: 56 return std::numeric_limits<Dst>::max(); 57 58 // Should fail only on attempting to assign NaN to a saturated integer. 59 case internal::TYPE_INVALID: 60 FATAL(); 61 return std::numeric_limits<Dst>::max(); 62 } 63 64 FATAL(); 65 return static_cast<Dst>(value); 66 } 67 68 } // namespace rtc 69 70 #endif // WEBRTC_BASE_SAFE_CONVERSIONS_H_ 71