| 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 |