Line data Source code
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 3509 : 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 3509 : switch (internal::DstRangeRelationToSrcRange<Dst>(value)) {
45 : case internal::RANGE_VALID:
46 5 : 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 3504 : 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 0 : UNREACHABLE();
57 : }
58 :
59 0 : UNREACHABLE();
60 : }
61 :
62 : } // namespace base
63 : } // namespace v8
64 :
65 : #endif // V8_BASE_SAFE_CONVERSIONS_H_
|