|  | /* | 
|  | *  Copyright 2014 The WebRTC Project Authors. All rights reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | // Borrowed from Chromium's src/base/numerics/safe_conversions.h. | 
|  |  | 
|  | #ifndef RTC_BASE_NUMERICS_SAFE_CONVERSIONS_H_ | 
|  | #define RTC_BASE_NUMERICS_SAFE_CONVERSIONS_H_ | 
|  |  | 
|  | #include <limits> | 
|  |  | 
|  | #include "rtc_base/checks.h" | 
|  | #include "rtc_base/numerics/safe_conversions_impl.h" | 
|  |  | 
|  | namespace rtc { | 
|  |  | 
|  | // Convenience function that returns true if the supplied value is in range | 
|  | // for the destination type. | 
|  | template <typename Dst, typename Src> | 
|  | inline bool IsValueInRangeForNumericType(Src value) { | 
|  | return internal::RangeCheck<Dst>(value) == internal::TYPE_VALID; | 
|  | } | 
|  |  | 
|  | // checked_cast<> and dchecked_cast<> are analogous to static_cast<> for | 
|  | // numeric types, except that they [D]CHECK that the specified numeric | 
|  | // conversion will not overflow or underflow. NaN source will always trigger | 
|  | // the [D]CHECK. | 
|  | template <typename Dst, typename Src> | 
|  | inline Dst checked_cast(Src value) { | 
|  | RTC_CHECK(IsValueInRangeForNumericType<Dst>(value)); | 
|  | return static_cast<Dst>(value); | 
|  | } | 
|  | template <typename Dst, typename Src> | 
|  | inline Dst dchecked_cast(Src value) { | 
|  | RTC_DCHECK(IsValueInRangeForNumericType<Dst>(value)); | 
|  | return static_cast<Dst>(value); | 
|  | } | 
|  |  | 
|  | // saturated_cast<> is analogous to static_cast<> for numeric types, except | 
|  | // that the specified numeric conversion will saturate rather than overflow or | 
|  | // underflow. NaN assignment to an integral will trigger a RTC_CHECK condition. | 
|  | template <typename Dst, typename Src> | 
|  | inline Dst saturated_cast(Src value) { | 
|  | // Optimization for floating point values, which already saturate. | 
|  | if (std::numeric_limits<Dst>::is_iec559) | 
|  | return static_cast<Dst>(value); | 
|  |  | 
|  | switch (internal::RangeCheck<Dst>(value)) { | 
|  | case internal::TYPE_VALID: | 
|  | return static_cast<Dst>(value); | 
|  |  | 
|  | case internal::TYPE_UNDERFLOW: | 
|  | return std::numeric_limits<Dst>::min(); | 
|  |  | 
|  | case internal::TYPE_OVERFLOW: | 
|  | return std::numeric_limits<Dst>::max(); | 
|  |  | 
|  | // Should fail only on attempting to assign NaN to a saturated integer. | 
|  | case internal::TYPE_INVALID: | 
|  | FATAL(); | 
|  | return std::numeric_limits<Dst>::max(); | 
|  | } | 
|  |  | 
|  | FATAL(); | 
|  | return static_cast<Dst>(value); | 
|  | } | 
|  |  | 
|  | }  // namespace rtc | 
|  |  | 
|  | #endif  // RTC_BASE_NUMERICS_SAFE_CONVERSIONS_H_ |