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

Side by Side Diff: base/strings/string_number_conversions.h

Issue 1212653005: [ADANDONED] Helper code for finding problematic uses of IntToString variants. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@int_to_string_cleanup_net
Patch Set: Disable warnings on IntToString's own tests. Created 5 years, 3 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 | « no previous file | base/strings/string_number_conversions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_
OLDNEW
« no previous file with comments | « no previous file | base/strings/string_number_conversions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698