OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_STRINGS_STRING_NUMBER_CONVERSIONS_H_ | 5 #ifndef BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ |
6 #define BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ | 6 #define BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
| 11 #if defined(STRING_NUMBER_CONVERSIONS_DETECT_RISKY_CONVERSIONS) |
| 12 #include <limits> |
| 13 #include <type_traits> |
| 14 #endif |
| 15 |
11 #include "base/base_export.h" | 16 #include "base/base_export.h" |
12 #include "base/basictypes.h" | 17 #include "base/basictypes.h" |
13 #include "base/strings/string16.h" | 18 #include "base/strings/string16.h" |
14 #include "base/strings/string_piece.h" | 19 #include "base/strings/string_piece.h" |
15 | 20 |
16 // ---------------------------------------------------------------------------- | 21 // ---------------------------------------------------------------------------- |
17 // IMPORTANT MESSAGE FROM YOUR SPONSOR | 22 // IMPORTANT MESSAGE FROM YOUR SPONSOR |
18 // | 23 // |
19 // This file contains no "wstring" variants. New code should use string16. If | 24 // This file contains no "wstring" variants. New code should use string16. If |
20 // you need to make old code work, use the UTF8 version and convert. Please do | 25 // you need to make old code work, use the UTF8 version and convert. Please do |
21 // not add wstring variants. | 26 // not add wstring variants. |
22 // | 27 // |
23 // Please do not add "convenience" functions for converting strings to integers | 28 // Please do not add "convenience" functions for converting strings to integers |
24 // that return the value and ignore success/failure. That encourages people to | 29 // that return the value and ignore success/failure. That encourages people to |
25 // write code that doesn't properly handle the error conditions. | 30 // write code that doesn't properly handle the error conditions. |
26 // ---------------------------------------------------------------------------- | 31 // ---------------------------------------------------------------------------- |
27 | 32 |
28 namespace base { | 33 namespace base { |
29 | 34 |
30 // Number -> string conversions ------------------------------------------------ | 35 // Number -> string conversions ------------------------------------------------ |
31 | 36 |
| 37 #if defined(STRING_NUMBER_CONVERSIONS_DETECT_RISKY_CONVERSIONS) |
| 38 namespace internal { |
| 39 #endif |
| 40 |
32 BASE_EXPORT std::string IntToString(int value); | 41 BASE_EXPORT std::string IntToString(int value); |
33 BASE_EXPORT string16 IntToString16(int value); | 42 BASE_EXPORT string16 IntToString16(int value); |
34 | 43 |
35 BASE_EXPORT std::string UintToString(unsigned value); | 44 BASE_EXPORT std::string UintToString(unsigned value); |
36 BASE_EXPORT string16 UintToString16(unsigned value); | 45 BASE_EXPORT string16 UintToString16(unsigned value); |
37 | 46 |
38 BASE_EXPORT std::string Int64ToString(int64 value); | 47 BASE_EXPORT std::string Int64ToString(int64 value); |
39 BASE_EXPORT string16 Int64ToString16(int64 value); | 48 BASE_EXPORT string16 Int64ToString16(int64 value); |
40 | 49 |
41 BASE_EXPORT std::string Uint64ToString(uint64 value); | 50 BASE_EXPORT std::string Uint64ToString(uint64 value); |
42 BASE_EXPORT string16 Uint64ToString16(uint64 value); | 51 BASE_EXPORT string16 Uint64ToString16(uint64 value); |
43 | 52 |
44 BASE_EXPORT std::string SizeTToString(size_t value); | 53 BASE_EXPORT std::string SizeTToString(size_t value); |
45 BASE_EXPORT string16 SizeTToString16(size_t value); | 54 BASE_EXPORT string16 SizeTToString16(size_t value); |
46 | 55 |
47 // DoubleToString converts the double to a string format that ignores the | 56 // DoubleToString converts the double to a string format that ignores the |
48 // locale. If you want to use locale specific formatting, use ICU. | 57 // locale. If you want to use locale specific formatting, use ICU. |
49 BASE_EXPORT std::string DoubleToString(double value); | 58 BASE_EXPORT std::string DoubleToString(double value); |
50 | 59 |
| 60 #if defined(STRING_NUMBER_CONVERSIONS_DETECT_RISKY_CONVERSIONS) |
| 61 } // namespace internal |
| 62 #endif |
| 63 |
51 // String -> number conversions ------------------------------------------------ | 64 // String -> number conversions ------------------------------------------------ |
52 | 65 |
53 // Perform a best-effort conversion of the input string to a numeric type, | 66 // Perform a best-effort conversion of the input string to a numeric type, |
54 // setting |*output| to the result of the conversion. Returns true for | 67 // setting |*output| to the result of the conversion. Returns true for |
55 // "perfect" conversions; returns false in the following cases: | 68 // "perfect" conversions; returns false in the following cases: |
56 // - Overflow. |*output| will be set to the maximum value supported | 69 // - Overflow. |*output| will be set to the maximum value supported |
57 // by the data type. | 70 // by the data type. |
58 // - Underflow. |*output| will be set to the minimum value supported | 71 // - Underflow. |*output| will be set to the minimum value supported |
59 // by the data type. | 72 // by the data type. |
60 // - Trailing characters in the string after parsing the number. |*output| | 73 // - Trailing characters in the string after parsing the number. |*output| |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 // The string is not required to start with 0x. | 136 // The string is not required to start with 0x. |
124 BASE_EXPORT bool HexStringToUInt64(const StringPiece& input, uint64* output); | 137 BASE_EXPORT bool HexStringToUInt64(const StringPiece& input, uint64* output); |
125 | 138 |
126 // Similar to the previous functions, except that output is a vector of bytes. | 139 // Similar to the previous functions, except that output is a vector of bytes. |
127 // |*output| will contain as many bytes as were successfully parsed prior to the | 140 // |*output| will contain as many bytes as were successfully parsed prior to the |
128 // error. There is no overflow, but input.size() must be evenly divisible by 2. | 141 // error. There is no overflow, but input.size() must be evenly divisible by 2. |
129 // Leading 0x or +/- are not allowed. | 142 // Leading 0x or +/- are not allowed. |
130 BASE_EXPORT bool HexStringToBytes(const std::string& input, | 143 BASE_EXPORT bool HexStringToBytes(const std::string& input, |
131 std::vector<uint8>* output); | 144 std::vector<uint8>* output); |
132 | 145 |
| 146 // Detection of potentially risky conversions. This is not enabled by default |
| 147 // because it has too many false positives. |
| 148 // |
| 149 // How to use: |
| 150 // 1. Define STRING_NUMBER_CONVERSIONS_DETECT_RISKY_CONVERSIONS (probably the |
| 151 // easiest way is to make a local modification to this file, but make sure |
| 152 // you don't check it in). |
| 153 // 2. Compile the code you want to check. |
| 154 // 3. You will see errors like "error: temporary of type |
| 155 // 'SignedUnsignedMismatch' (aka 'base::ErrorOnUse') has private destructor" |
| 156 // 4. Check the actual type of the variable being passed in. |
| 157 // 5. Attempt to determine whether the "wrong" conversion function is being used |
| 158 // intentionally. Pay particular attention to 32-bit/64-bit issues and |
| 159 // cross-platform compatibility. |
| 160 // 6. Decide if it would be better to use a different conversion function. |
| 161 // 7. If so, make the change, compile it, and test it. |
| 162 // |
| 163 #if defined(STRING_NUMBER_CONVERSIONS_DETECT_RISKY_CONVERSIONS) |
| 164 |
| 165 // Enums are weird. They have an "underlying type", but that is |
| 166 // implementation-specific (unless explicitly specified). However, the overload |
| 167 // resolution order for enums *is* specified in the standard, specifically: |
| 168 // |
| 169 // """ A prvalue of an unscoped enumeration type whose underlying type is not |
| 170 // fixed (7.2) can be converted to a prvalue of the first of the following types |
| 171 // that can represent all the values of the enumeration (i.e., the values in the |
| 172 // range b min to b max as described in 7.2): int, unsigned int, long int, |
| 173 // unsigned long int, long long int, or unsigned long long int. """ |
| 174 // |
| 175 // Since that is portable, decide the correct function to pass an enum to based |
| 176 // on overload resolution. |
| 177 template <typename T> |
| 178 class EnumOverloadOrOriginalType { |
| 179 private: |
| 180 template <typename T2, bool is_enum> |
| 181 struct Impl; |
| 182 |
| 183 template <typename T2> |
| 184 struct Impl<T2, false> { |
| 185 typedef T2 type; |
| 186 }; |
| 187 |
| 188 template <typename T2> |
| 189 struct Impl<T2, true> { |
| 190 static int deduce(int); |
| 191 static uint32 deduce(uint32); |
| 192 static int64 deduce(int64); |
| 193 static uint64 deduce(uint64); |
| 194 |
| 195 typedef decltype(deduce(T2())) type; |
| 196 }; |
| 197 |
| 198 public: |
| 199 typedef typename Impl<T, std::is_enum<T>::value>::type type; |
| 200 }; |
| 201 |
| 202 template <typename ReturnType, |
| 203 typename ExpectedType, |
| 204 ReturnType(Function)(ExpectedType)> |
| 205 struct LooseMatchFunctor { |
| 206 constexpr LooseMatchFunctor() {} |
| 207 |
| 208 template <typename T> |
| 209 ReturnType operator()(T value) const { |
| 210 static_assert( |
| 211 std::is_arithmetic<T>::value || std::is_enum<T>::value, |
| 212 "Type passed to numeric conversions must be arithmetic or enum"); |
| 213 // If T is an enum, then it is the underlying type we are interested in. |
| 214 typedef typename EnumOverloadOrOriginalType<T>::type ActualType; |
| 215 static_assert(std::is_arithmetic<ActualType>::value, |
| 216 "ActualType must be arithmetic"); |
| 217 static_assert(sizeof(ActualType) <= sizeof(ExpectedType), |
| 218 "Silent truncation of larger integer type"); |
| 219 static_assert(std::is_enum<ActualType>::value || |
| 220 std::numeric_limits<ActualType>::is_signed == |
| 221 std::numeric_limits<ExpectedType>::is_signed, |
| 222 "Signed/unsigned mismatch"); |
| 223 static_assert(std::is_enum<ActualType>::value || |
| 224 std::numeric_limits<ActualType>::is_integer == |
| 225 std::numeric_limits<ExpectedType>::is_integer, |
| 226 "Integer/floating point mismatch"); |
| 227 return Function(value); |
| 228 } |
| 229 }; |
| 230 |
| 231 template <typename ReturnType, |
| 232 typename ExpectedType, |
| 233 ReturnType(Function)(ExpectedType)> |
| 234 struct ExactMatchFunctor { |
| 235 constexpr ExactMatchFunctor() {} |
| 236 |
| 237 template <typename ActualType> |
| 238 ReturnType operator()(ActualType value) const { |
| 239 static_assert(std::is_same<ActualType, ExpectedType>::value, |
| 240 "Types do not match"); |
| 241 return Function(value); |
| 242 } |
| 243 }; |
| 244 |
| 245 #define DEFINE_INT_TO_STRING_FUNCTION(RETURN_TYPE, EXPECTED_TYPE, FUNCTION) \ |
| 246 constexpr LooseMatchFunctor<RETURN_TYPE, EXPECTED_TYPE, internal::FUNCTION> \ |
| 247 FUNCTION |
| 248 |
| 249 #define DEFINE_EXACT_MATCH_INT_TO_STRING_FUNCTION(RETURN_TYPE, EXPECTED_TYPE, \ |
| 250 FUNCTION) \ |
| 251 constexpr ExactMatchFunctor<RETURN_TYPE, EXPECTED_TYPE, internal::FUNCTION> \ |
| 252 FUNCTION |
| 253 |
| 254 DEFINE_INT_TO_STRING_FUNCTION(std::string, int, IntToString); |
| 255 DEFINE_INT_TO_STRING_FUNCTION(string16, int, IntToString16); |
| 256 DEFINE_INT_TO_STRING_FUNCTION(std::string, uint32, UintToString); |
| 257 DEFINE_INT_TO_STRING_FUNCTION(string16, uint32, UintToString16); |
| 258 DEFINE_INT_TO_STRING_FUNCTION(std::string, int64, Int64ToString); |
| 259 DEFINE_INT_TO_STRING_FUNCTION(string16, int64, Int64ToString16); |
| 260 DEFINE_INT_TO_STRING_FUNCTION(std::string, uint64, Uint64ToString); |
| 261 DEFINE_INT_TO_STRING_FUNCTION(string16, uint64, Uint64ToString16); |
| 262 DEFINE_EXACT_MATCH_INT_TO_STRING_FUNCTION(std::string, size_t, SizeTToString); |
| 263 DEFINE_EXACT_MATCH_INT_TO_STRING_FUNCTION(string16, size_t, SizeTToString16); |
| 264 DEFINE_INT_TO_STRING_FUNCTION(std::string, double, DoubleToString); |
| 265 |
| 266 #endif |
| 267 |
133 } // namespace base | 268 } // namespace base |
134 | 269 |
135 #endif // BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ | 270 #endif // BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ |
OLD | NEW |