Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: webrtc/base/safe_conversions_impl.h

Issue 2877023002: Move webrtc/{base => rtc_base} (Closed)
Patch Set: update presubmit.py and DEPS include rules Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/safe_conversions.h ('k') | webrtc/base/safe_minmax.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 // Borrowed from Chromium's src/base/numerics/safe_conversions_impl.h. 11 // Borrowed from Chromium's src/base/numerics/safe_conversions_impl.h.
12 12
13 #ifndef WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_ 13 #ifndef WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_
14 #define WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_ 14 #define WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_
15 15
16 #include <limits>
17 16
18 namespace rtc { 17 // This header is deprecated and is just left here temporarily during
19 namespace internal { 18 // refactoring. See https://bugs.webrtc.org/7634 for more details.
20 19 #include "webrtc/rtc_base/safe_conversions_impl.h"
21 enum DstSign {
22 DST_UNSIGNED,
23 DST_SIGNED
24 };
25
26 enum SrcSign {
27 SRC_UNSIGNED,
28 SRC_SIGNED
29 };
30
31 enum DstRange {
32 OVERLAPS_RANGE,
33 CONTAINS_RANGE
34 };
35
36 // Helper templates to statically determine if our destination type can contain
37 // all values represented by the source type.
38
39 template <typename Dst, typename Src,
40 DstSign IsDstSigned = std::numeric_limits<Dst>::is_signed ?
41 DST_SIGNED : DST_UNSIGNED,
42 SrcSign IsSrcSigned = std::numeric_limits<Src>::is_signed ?
43 SRC_SIGNED : SRC_UNSIGNED>
44 struct StaticRangeCheck {};
45
46 template <typename Dst, typename Src>
47 struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_SIGNED> {
48 typedef std::numeric_limits<Dst> DstLimits;
49 typedef std::numeric_limits<Src> SrcLimits;
50 // Compare based on max_exponent, which we must compute for integrals.
51 static const size_t kDstMaxExponent = DstLimits::is_iec559 ?
52 DstLimits::max_exponent :
53 (sizeof(Dst) * 8 - 1);
54 static const size_t kSrcMaxExponent = SrcLimits::is_iec559 ?
55 SrcLimits::max_exponent :
56 (sizeof(Src) * 8 - 1);
57 static const DstRange value = kDstMaxExponent >= kSrcMaxExponent ?
58 CONTAINS_RANGE : OVERLAPS_RANGE;
59 };
60
61 template <typename Dst, typename Src>
62 struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED> {
63 static const DstRange value = sizeof(Dst) >= sizeof(Src) ?
64 CONTAINS_RANGE : OVERLAPS_RANGE;
65 };
66
67 template <typename Dst, typename Src>
68 struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_UNSIGNED> {
69 typedef std::numeric_limits<Dst> DstLimits;
70 typedef std::numeric_limits<Src> SrcLimits;
71 // Compare based on max_exponent, which we must compute for integrals.
72 static const size_t kDstMaxExponent = DstLimits::is_iec559 ?
73 DstLimits::max_exponent :
74 (sizeof(Dst) * 8 - 1);
75 static const size_t kSrcMaxExponent = sizeof(Src) * 8;
76 static const DstRange value = kDstMaxExponent >= kSrcMaxExponent ?
77 CONTAINS_RANGE : OVERLAPS_RANGE;
78 };
79
80 template <typename Dst, typename Src>
81 struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_SIGNED> {
82 static const DstRange value = OVERLAPS_RANGE;
83 };
84
85
86 enum RangeCheckResult {
87 TYPE_VALID = 0, // Value can be represented by the destination type.
88 TYPE_UNDERFLOW = 1, // Value would overflow.
89 TYPE_OVERFLOW = 2, // Value would underflow.
90 TYPE_INVALID = 3 // Source value is invalid (i.e. NaN).
91 };
92
93 // This macro creates a RangeCheckResult from an upper and lower bound
94 // check by taking advantage of the fact that only NaN can be out of range in
95 // both directions at once.
96 #define BASE_NUMERIC_RANGE_CHECK_RESULT(is_in_upper_bound, is_in_lower_bound) \
97 RangeCheckResult(((is_in_upper_bound) ? 0 : TYPE_OVERFLOW) | \
98 ((is_in_lower_bound) ? 0 : TYPE_UNDERFLOW))
99
100 template <typename Dst,
101 typename Src,
102 DstSign IsDstSigned = std::numeric_limits<Dst>::is_signed ?
103 DST_SIGNED : DST_UNSIGNED,
104 SrcSign IsSrcSigned = std::numeric_limits<Src>::is_signed ?
105 SRC_SIGNED : SRC_UNSIGNED,
106 DstRange IsSrcRangeContained = StaticRangeCheck<Dst, Src>::value>
107 struct RangeCheckImpl {};
108
109 // The following templates are for ranges that must be verified at runtime. We
110 // split it into checks based on signedness to avoid confusing casts and
111 // compiler warnings on signed an unsigned comparisons.
112
113 // Dst range always contains the result: nothing to check.
114 template <typename Dst, typename Src, DstSign IsDstSigned, SrcSign IsSrcSigned>
115 struct RangeCheckImpl<Dst, Src, IsDstSigned, IsSrcSigned, CONTAINS_RANGE> {
116 static RangeCheckResult Check(Src value) {
117 return TYPE_VALID;
118 }
119 };
120
121 // Signed to signed narrowing.
122 template <typename Dst, typename Src>
123 struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
124 static RangeCheckResult Check(Src value) {
125 typedef std::numeric_limits<Dst> DstLimits;
126 return DstLimits::is_iec559 ?
127 BASE_NUMERIC_RANGE_CHECK_RESULT(
128 value <= static_cast<Src>(DstLimits::max()),
129 value >= static_cast<Src>(DstLimits::max() * -1)) :
130 BASE_NUMERIC_RANGE_CHECK_RESULT(
131 value <= static_cast<Src>(DstLimits::max()),
132 value >= static_cast<Src>(DstLimits::min()));
133 }
134 };
135
136 // Unsigned to unsigned narrowing.
137 template <typename Dst, typename Src>
138 struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
139 static RangeCheckResult Check(Src value) {
140 typedef std::numeric_limits<Dst> DstLimits;
141 return BASE_NUMERIC_RANGE_CHECK_RESULT(
142 value <= static_cast<Src>(DstLimits::max()), true);
143 }
144 };
145
146 // Unsigned to signed.
147 template <typename Dst, typename Src>
148 struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
149 static RangeCheckResult Check(Src value) {
150 typedef std::numeric_limits<Dst> DstLimits;
151 return sizeof(Dst) > sizeof(Src) ? TYPE_VALID :
152 BASE_NUMERIC_RANGE_CHECK_RESULT(
153 value <= static_cast<Src>(DstLimits::max()), true);
154 }
155 };
156
157 // Signed to unsigned.
158 template <typename Dst, typename Src>
159 struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
160 static RangeCheckResult Check(Src value) {
161 typedef std::numeric_limits<Dst> DstLimits;
162 typedef std::numeric_limits<Src> SrcLimits;
163 // Compare based on max_exponent, which we must compute for integrals.
164 static const size_t kDstMaxExponent = sizeof(Dst) * 8;
165 static const size_t kSrcMaxExponent = SrcLimits::is_iec559 ?
166 SrcLimits::max_exponent :
167 (sizeof(Src) * 8 - 1);
168 return (kDstMaxExponent >= kSrcMaxExponent) ?
169 BASE_NUMERIC_RANGE_CHECK_RESULT(true, value >= static_cast<Src>(0)) :
170 BASE_NUMERIC_RANGE_CHECK_RESULT(
171 value <= static_cast<Src>(DstLimits::max()),
172 value >= static_cast<Src>(0));
173 }
174 };
175
176 template <typename Dst, typename Src>
177 inline RangeCheckResult RangeCheck(Src value) {
178 static_assert(std::numeric_limits<Src>::is_specialized,
179 "argument must be numeric");
180 static_assert(std::numeric_limits<Dst>::is_specialized,
181 "result must be numeric");
182 return RangeCheckImpl<Dst, Src>::Check(value);
183 }
184
185 } // namespace internal
186 } // namespace rtc
187 20
188 #endif // WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_ 21 #endif // WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_
OLDNEW
« no previous file with comments | « webrtc/base/safe_conversions.h ('k') | webrtc/base/safe_minmax.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698