Home | History | Annotate | Download | only in base
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Slightly adapted for inclusion in V8.
      6 // Copyright 2014 the V8 project authors. All rights reserved.
      7 
      8 #ifndef V8_BASE_SAFE_CONVERSIONS_H_
      9 #define V8_BASE_SAFE_CONVERSIONS_H_
     10 
     11 #include <limits>
     12 
     13 #include "src/base/safe_conversions_impl.h"
     14 
     15 namespace v8 {
     16 namespace base {
     17 
     18 // Convenience function that returns true if the supplied value is in range
     19 // for the destination type.
     20 template <typename Dst, typename Src>
     21 inline bool IsValueInRangeForNumericType(Src value) {
     22   return internal::DstRangeRelationToSrcRange<Dst>(value) ==
     23          internal::RANGE_VALID;
     24 }
     25 
     26 // checked_cast<> is analogous to static_cast<> for numeric types,
     27 // except that it CHECKs that the specified numeric conversion will not
     28 // overflow or underflow. NaN source will always trigger a CHECK.
     29 template <typename Dst, typename Src>
     30 inline Dst checked_cast(Src value) {
     31   CHECK(IsValueInRangeForNumericType<Dst>(value));
     32   return static_cast<Dst>(value);
     33 }
     34 
     35 // saturated_cast<> is analogous to static_cast<> for numeric types, except
     36 // that the specified numeric conversion will saturate rather than overflow or
     37 // underflow. NaN assignment to an integral will trigger a CHECK condition.
     38 template <typename Dst, typename Src>
     39 inline Dst saturated_cast(Src value) {
     40   // Optimization for floating point values, which already saturate.
     41   if (std::numeric_limits<Dst>::is_iec559)
     42     return static_cast<Dst>(value);
     43 
     44   switch (internal::DstRangeRelationToSrcRange<Dst>(value)) {
     45     case internal::RANGE_VALID:
     46       return static_cast<Dst>(value);
     47 
     48     case internal::RANGE_UNDERFLOW:
     49       return std::numeric_limits<Dst>::min();
     50 
     51     case internal::RANGE_OVERFLOW:
     52       return std::numeric_limits<Dst>::max();
     53 
     54     // Should fail only on attempting to assign NaN to a saturated integer.
     55     case internal::RANGE_INVALID:
     56       CHECK(false);
     57       return std::numeric_limits<Dst>::max();
     58   }
     59 
     60   UNREACHABLE();
     61   return static_cast<Dst>(value);
     62 }
     63 
     64 }  // namespace base
     65 }  // namespace v8
     66 
     67 #endif  // V8_BASE_SAFE_CONVERSIONS_H_
     68