OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 5 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
6 #define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 6 #define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
7 | 7 |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/template_util.h" | 10 #include "base/template_util.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 // Signed to signed narrowing: Both the upper and lower boundaries may be | 141 // Signed to signed narrowing: Both the upper and lower boundaries may be |
142 // exceeded. | 142 // exceeded. |
143 template <typename Dst, typename Src> | 143 template <typename Dst, typename Src> |
144 struct DstRangeRelationToSrcRangeImpl<Dst, | 144 struct DstRangeRelationToSrcRangeImpl<Dst, |
145 Src, | 145 Src, |
146 INTEGER_REPRESENTATION_SIGNED, | 146 INTEGER_REPRESENTATION_SIGNED, |
147 INTEGER_REPRESENTATION_SIGNED, | 147 INTEGER_REPRESENTATION_SIGNED, |
148 NUMERIC_RANGE_NOT_CONTAINED> { | 148 NUMERIC_RANGE_NOT_CONTAINED> { |
149 static RangeConstraint Check(Src value) { | 149 static RangeConstraint Check(Src value) { |
150 return std::numeric_limits<Dst>::is_iec559 | 150 return std::numeric_limits<Dst>::is_iec559 |
151 ? GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), | 151 ? GetRangeConstraint((value < std::numeric_limits<Dst>::max()), |
152 value >= -std::numeric_limits<Dst>::max()) | 152 (value > -std::numeric_limits<Dst>::max())) |
153 : GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), | 153 : GetRangeConstraint((value < std::numeric_limits<Dst>::max()), |
154 value >= std::numeric_limits<Dst>::min()); | 154 (value > std::numeric_limits<Dst>::min())); |
155 } | 155 } |
156 }; | 156 }; |
157 | 157 |
158 // Unsigned to unsigned narrowing: Only the upper boundary can be exceeded. | 158 // Unsigned to unsigned narrowing: Only the upper boundary can be exceeded. |
159 template <typename Dst, typename Src> | 159 template <typename Dst, typename Src> |
160 struct DstRangeRelationToSrcRangeImpl<Dst, | 160 struct DstRangeRelationToSrcRangeImpl<Dst, |
161 Src, | 161 Src, |
162 INTEGER_REPRESENTATION_UNSIGNED, | 162 INTEGER_REPRESENTATION_UNSIGNED, |
163 INTEGER_REPRESENTATION_UNSIGNED, | 163 INTEGER_REPRESENTATION_UNSIGNED, |
164 NUMERIC_RANGE_NOT_CONTAINED> { | 164 NUMERIC_RANGE_NOT_CONTAINED> { |
165 static RangeConstraint Check(Src value) { | 165 static RangeConstraint Check(Src value) { |
166 return GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), true); | 166 return GetRangeConstraint(value < std::numeric_limits<Dst>::max(), true); |
167 } | 167 } |
168 }; | 168 }; |
169 | 169 |
170 // Unsigned to signed: The upper boundary may be exceeded. | 170 // Unsigned to signed: The upper boundary may be exceeded. |
171 template <typename Dst, typename Src> | 171 template <typename Dst, typename Src> |
172 struct DstRangeRelationToSrcRangeImpl<Dst, | 172 struct DstRangeRelationToSrcRangeImpl<Dst, |
173 Src, | 173 Src, |
174 INTEGER_REPRESENTATION_SIGNED, | 174 INTEGER_REPRESENTATION_SIGNED, |
175 INTEGER_REPRESENTATION_UNSIGNED, | 175 INTEGER_REPRESENTATION_UNSIGNED, |
176 NUMERIC_RANGE_NOT_CONTAINED> { | 176 NUMERIC_RANGE_NOT_CONTAINED> { |
177 static RangeConstraint Check(Src value) { | 177 static RangeConstraint Check(Src value) { |
178 return sizeof(Dst) > sizeof(Src) | 178 return sizeof(Dst) > sizeof(Src) |
179 ? RANGE_VALID | 179 ? RANGE_VALID |
180 : GetRangeConstraint( | 180 : GetRangeConstraint( |
181 value <= static_cast<Src>(std::numeric_limits<Dst>::max()), | 181 value < static_cast<Src>(std::numeric_limits<Dst>::max()), |
182 true); | 182 true); |
183 } | 183 } |
184 }; | 184 }; |
185 | 185 |
186 // Signed to unsigned: The upper boundary may be exceeded for a narrower Dst, | 186 // Signed to unsigned: The upper boundary may be exceeded for a narrower Dst, |
187 // and any negative value exceeds the lower boundary. | 187 // and any negative value exceeds the lower boundary. |
188 template <typename Dst, typename Src> | 188 template <typename Dst, typename Src> |
189 struct DstRangeRelationToSrcRangeImpl<Dst, | 189 struct DstRangeRelationToSrcRangeImpl<Dst, |
190 Src, | 190 Src, |
191 INTEGER_REPRESENTATION_UNSIGNED, | 191 INTEGER_REPRESENTATION_UNSIGNED, |
192 INTEGER_REPRESENTATION_SIGNED, | 192 INTEGER_REPRESENTATION_SIGNED, |
193 NUMERIC_RANGE_NOT_CONTAINED> { | 193 NUMERIC_RANGE_NOT_CONTAINED> { |
194 static RangeConstraint Check(Src value) { | 194 static RangeConstraint Check(Src value) { |
195 return (MaxExponent<Dst>::value >= MaxExponent<Src>::value) | 195 return (MaxExponent<Dst>::value >= MaxExponent<Src>::value) |
196 ? GetRangeConstraint(true, value >= static_cast<Src>(0)) | 196 ? GetRangeConstraint(true, value >= static_cast<Src>(0)) |
197 : GetRangeConstraint( | 197 : GetRangeConstraint( |
198 value <= static_cast<Src>(std::numeric_limits<Dst>::max()), | 198 value < static_cast<Src>(std::numeric_limits<Dst>::max()), |
199 value >= static_cast<Src>(0)); | 199 value >= static_cast<Src>(0)); |
200 } | 200 } |
201 }; | 201 }; |
202 | 202 |
203 template <typename Dst, typename Src> | 203 template <typename Dst, typename Src> |
204 inline RangeConstraint DstRangeRelationToSrcRange(Src value) { | 204 inline RangeConstraint DstRangeRelationToSrcRange(Src value) { |
205 static_assert(std::numeric_limits<Src>::is_specialized, | 205 static_assert(std::numeric_limits<Src>::is_specialized, |
206 "Argument must be numeric."); | 206 "Argument must be numeric."); |
207 static_assert(std::numeric_limits<Dst>::is_specialized, | 207 static_assert(std::numeric_limits<Dst>::is_specialized, |
208 "Result must be numeric."); | 208 "Result must be numeric."); |
209 return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value); | 209 return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value); |
210 } | 210 } |
211 | 211 |
212 } // namespace internal | 212 } // namespace internal |
213 } // namespace base | 213 } // namespace base |
214 | 214 |
215 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 215 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
OLD | NEW |