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 21namespace rtc { 22 23// Convenience function that returns true if the supplied value is in range 24// for the destination type. 25template <typename Dst, typename Src> 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. 33template <typename Dst, typename Src> 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. 42template <typename Dst, typename Src> 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