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

Side by Side Diff: third_party/WebKit/Source/wtf/dtoa/utils.h

Issue 1611343002: wtf reformat test Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pydent Created 4 years, 11 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
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 26 matching lines...) Expand all
37 // Double operations detection based on target architecture. 37 // Double operations detection based on target architecture.
38 // Linux uses a 80bit wide floating point stack on x86. This induces double 38 // Linux uses a 80bit wide floating point stack on x86. This induces double
39 // rounding, which in turn leads to wrong results. 39 // rounding, which in turn leads to wrong results.
40 // An easy way to test if the floating-point operations are correct is to 40 // An easy way to test if the floating-point operations are correct is to
41 // evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then 41 // evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
42 // the result is equal to 89255e-22. 42 // the result is equal to 89255e-22.
43 // The best way to test this, is to create a division-function and to compare 43 // The best way to test this, is to create a division-function and to compare
44 // the output of the division with the expected result. (Inlining must be 44 // the output of the division with the expected result. (Inlining must be
45 // disabled.) 45 // disabled.)
46 // On Linux,x86 89255e-22 != Div_double(89255.0/1e22) 46 // On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
47 #if defined(_M_X64) || defined(__x86_64__) || \ 47 #if defined(_M_X64) || defined(__x86_64__) || defined(__ARMEL__) || \
48 defined(__ARMEL__) || defined(__aarch64__) || \ 48 defined(__aarch64__) || defined(__MIPSEL__)
49 defined(__MIPSEL__)
50 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 49 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
51 #elif defined(_M_IX86) || defined(__i386__) 50 #elif defined(_M_IX86) || defined(__i386__)
52 #if defined(_WIN32) 51 #if defined(_WIN32)
53 // Windows uses a 64bit wide floating point stack. 52 // Windows uses a 64bit wide floating point stack.
54 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 53 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
55 #else 54 #else
56 #undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 55 #undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
57 #endif // _WIN32 56 #endif // _WIN32
58 #else 57 #else
59 #error Target architecture was not detected as supported by Double-Conversion. 58 #error Target architecture was not detected as supported by Double-Conversion.
60 #endif 59 #endif
61 60
62
63 #if defined(_WIN32) && !defined(__MINGW32__) 61 #if defined(_WIN32) && !defined(__MINGW32__)
64 62
65 typedef signed char int8_t; 63 typedef signed char int8_t;
66 typedef unsigned char uint8_t; 64 typedef unsigned char uint8_t;
67 typedef short int16_t; // NOLINT 65 typedef short int16_t; // NOLINT
68 typedef unsigned short uint16_t; // NOLINT 66 typedef unsigned short uint16_t; // NOLINT
69 typedef int int32_t; 67 typedef int int32_t;
70 typedef unsigned int uint32_t; 68 typedef unsigned int uint32_t;
71 typedef __int64 int64_t; 69 typedef __int64 int64_t;
72 typedef unsigned __int64 uint64_t; 70 typedef unsigned __int64 uint64_t;
73 // intptr_t and friends are defined in crtdefs.h through stdio.h. 71 // intptr_t and friends are defined in crtdefs.h through stdio.h.
74 72
75 #else 73 #else
76 74
77 #include <stdint.h> 75 #include <stdint.h>
78 76
79 #endif 77 #endif
80 78
81 // The following macro works on both 32 and 64-bit platforms. 79 // The following macro works on both 32 and 64-bit platforms.
82 // Usage: instead of writing 0x1234567890123456 80 // Usage: instead of writing 0x1234567890123456
83 // write UINT64_2PART_C(0x12345678,90123456); 81 // write UINT64_2PART_C(0x12345678,90123456);
84 #define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) 82 #define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
85 83
86
87 // The expression ARRAY_SIZE(a) is a compile-time constant of type 84 // The expression ARRAY_SIZE(a) is a compile-time constant of type
88 // size_t which represents the number of elements of the given 85 // size_t which represents the number of elements of the given
89 // array. You should only use ARRAY_SIZE on statically allocated 86 // array. You should only use ARRAY_SIZE on statically allocated
90 // arrays. 87 // arrays.
91 #define ARRAY_SIZE(a) \ 88 #define ARRAY_SIZE(a) \
92 ((sizeof(a) / sizeof(*(a))) / \ 89 ((sizeof(a) / sizeof(*(a))) / \
93 static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) 90 static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
94 91
95 // A macro to disallow the evil copy constructor and operator= functions 92 // A macro to disallow the evil copy constructor and operator= functions
96 // This should be used in the private: declarations for a class 93 // This should be used in the private: declarations for a class
97 #ifndef DISALLOW_COPY_AND_ASSIGN 94 #ifndef DISALLOW_COPY_AND_ASSIGN
98 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 95 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
99 TypeName(const TypeName&); \ 96 TypeName(const TypeName&); \
100 void operator=(const TypeName&) 97 void operator=(const TypeName&)
101 #endif // DISALLOW_COPY_AND_ASSIGN 98 #endif // DISALLOW_COPY_AND_ASSIGN
102 99
103 // A macro to disallow all the implicit constructors, namely the 100 // A macro to disallow all the implicit constructors, namely the
104 // default constructor, copy constructor and operator= functions. 101 // default constructor, copy constructor and operator= functions.
105 // 102 //
106 // This should be used in the private: declarations for a class 103 // This should be used in the private: declarations for a class
107 // that wants to prevent anyone from instantiating it. This is 104 // that wants to prevent anyone from instantiating it. This is
108 // especially useful for classes containing only static methods. 105 // especially useful for classes containing only static methods.
109 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 106 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
110 TypeName() = delete; \ 107 TypeName() = delete; \
111 DISALLOW_COPY_AND_ASSIGN(TypeName) 108 DISALLOW_COPY_AND_ASSIGN(TypeName)
112 109
113 namespace WTF { 110 namespace WTF {
114 111
115 namespace double_conversion { 112 namespace double_conversion {
116 113
117 static const int kCharSize = sizeof(char); 114 static const int kCharSize = sizeof(char);
118 115
119 // Returns the maximum of the two parameters. 116 // Returns the maximum of the two parameters.
120 template <typename T> 117 template <typename T>
121 static T Max(T a, T b) { 118 static T Max(T a, T b) {
122 return a < b ? b : a; 119 return a < b ? b : a;
120 }
121
122 // Returns the minimum of the two parameters.
123 template <typename T>
124 static T Min(T a, T b) {
125 return a < b ? a : b;
126 }
127
128 inline int StrLength(const char* string) {
129 size_t length = strlen(string);
130 ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
131 return static_cast<int>(length);
132 }
133
134 // This is a simplified version of V8's Vector class.
135 template <typename T>
136 class Vector {
137 public:
138 Vector() : start_(NULL), length_(0) {}
139 Vector(T* data, int length) : start_(data), length_(length) {
140 ASSERT(length == 0 || (length > 0 && data != NULL));
141 }
142
143 // Returns a vector using the same backing storage as this one,
144 // spanning from and including 'from', to but not including 'to'.
145 Vector<T> SubVector(int from, int to) {
146 ASSERT(to <= length_);
147 ASSERT(from < to);
148 ASSERT(0 <= from);
149 return Vector<T>(start() + from, to - from);
150 }
151
152 // Returns the length of the vector.
153 int length() const { return length_; }
154
155 // Returns whether or not the vector is empty.
156 bool is_empty() const { return length_ == 0; }
157
158 // Returns the pointer to the start of the data in the vector.
159 T* start() const { return start_; }
160
161 // Access individual vector elements - checks bounds in debug mode.
162 T& operator[](int index) const {
163 ASSERT(0 <= index && index < length_);
164 return start_[index];
165 }
166
167 T& first() { return start_[0]; }
168
169 T& last() { return start_[length_ - 1]; }
170
171 private:
172 T* start_;
173 int length_;
174 };
175
176 // Helper class for building result strings in a character buffer. The
177 // purpose of the class is to use safe operations that checks the
178 // buffer bounds on all operations in debug mode.
179 class StringBuilder {
180 public:
181 StringBuilder(char* buffer, int size) : buffer_(buffer, size), position_(0) {}
182
183 ~StringBuilder() {
184 if (!is_finalized())
185 Finalize();
186 }
187
188 int size() const { return buffer_.length(); }
189
190 // Get the current position in the builder.
191 int position() const {
192 ASSERT(!is_finalized());
193 return position_;
194 }
195
196 // Set the current position in the builder.
197 void SetPosition(int position) {
198 ASSERT(!is_finalized());
199 ASSERT_WITH_SECURITY_IMPLICATION(position < size());
200 position_ = position;
201 }
202
203 // Reset the position.
204 void Reset() { position_ = 0; }
205
206 // Add a single character to the builder. It is not allowed to add
207 // 0-characters; use the Finalize() method to terminate the string
208 // instead.
209 void AddCharacter(char c) {
210 ASSERT(c != '\0');
211 ASSERT(!is_finalized() && position_ < buffer_.length());
212 buffer_[position_++] = c;
213 }
214
215 // Add an entire string to the builder. Uses strlen() internally to
216 // compute the length of the input string.
217 void AddString(const char* s) { AddSubstring(s, StrLength(s)); }
218
219 // Add the first 'n' characters of the given string 's' to the
220 // builder. The input string must have enough characters.
221 void AddSubstring(const char* s, int n) {
222 ASSERT(!is_finalized() && position_ + n < buffer_.length());
223 ASSERT_WITH_SECURITY_IMPLICATION(static_cast<size_t>(n) <= strlen(s));
224 memcpy(&buffer_[position_], s, n * kCharSize);
225 position_ += n;
226 }
227
228 // Add character padding to the builder. If count is non-positive,
229 // nothing is added to the builder.
230 void AddPadding(char c, int count) {
231 for (int i = 0; i < count; i++) {
232 AddCharacter(c);
123 } 233 }
234 }
124 235
236 // Finalize the string by 0-terminating it and returning the buffer.
237 char* Finalize() {
238 ASSERT(!is_finalized() && position_ < buffer_.length());
239 buffer_[position_] = '\0';
240 // Make sure nobody managed to add a 0-character to the
241 // buffer while building the string.
242 ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
243 position_ = -1;
244 ASSERT(is_finalized());
245 return buffer_.start();
246 }
125 247
126 // Returns the minimum of the two parameters. 248 private:
127 template <typename T> 249 Vector<char> buffer_;
128 static T Min(T a, T b) { 250 int position_;
129 return a < b ? a : b;
130 }
131 251
252 bool is_finalized() const { return position_ < 0; }
132 253
133 inline int StrLength(const char* string) { 254 DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
134 size_t length = strlen(string); 255 };
135 ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
136 return static_cast<int>(length);
137 }
138 256
139 // This is a simplified version of V8's Vector class. 257 // The type-based aliasing rule allows the compiler to assume that pointers of
140 template <typename T> 258 // different types (for some definition of different) never alias each other.
141 class Vector { 259 // Thus the following code does not work:
142 public: 260 //
143 Vector() : start_(NULL), length_(0) {} 261 // float f = foo();
144 Vector(T* data, int length) : start_(data), length_(length) { 262 // int fbits = *(int*)(&f);
145 ASSERT(length == 0 || (length > 0 && data != NULL)); 263 //
146 } 264 // The compiler 'knows' that the int pointer can't refer to f since the types
265 // don't match, so the compiler may cache f in a register, leaving random data
266 // in fbits. Using C++ style casts makes no difference, however a pointer to
267 // char data is assumed to alias any other pointer. This is the 'memcpy
268 // exception'.
269 //
270 // Bit_cast uses the memcpy exception to move the bits from a variable of one
271 // type of a variable of another type. Of course the end result is likely to
272 // be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
273 // will completely optimize BitCast away.
274 //
275 // There is an additional use for BitCast.
276 // Recent gccs will warn when they see casts that may result in breakage due to
277 // the type-based aliasing rule. If you have checked that there is no breakage
278 // you can use BitCast to cast one pointer type to another. This confuses gcc
279 // enough that it can no longer see that you have cast one pointer type to
280 // another thus avoiding the warning.
281 template <class Dest, class Source>
282 inline Dest BitCast(const Source& source) {
283 // Compile time assertion: sizeof(Dest) == sizeof(Source)
284 // A compile error here means your Dest and Source have different sizes.
285 static_assert(sizeof(Dest) == sizeof(Source), "sizes should be equal");
147 286
148 // Returns a vector using the same backing storage as this one, 287 Dest dest;
149 // spanning from and including 'from', to but not including 'to'. 288 memcpy(&dest, &source, sizeof(dest));
150 Vector<T> SubVector(int from, int to) { 289 return dest;
151 ASSERT(to <= length_); 290 }
152 ASSERT(from < to);
153 ASSERT(0 <= from);
154 return Vector<T>(start() + from, to - from);
155 }
156 291
157 // Returns the length of the vector. 292 template <class Dest, class Source>
158 int length() const { return length_; } 293 inline Dest BitCast(Source* source) {
159 294 return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
160 // Returns whether or not the vector is empty. 295 }
161 bool is_empty() const { return length_ == 0; }
162
163 // Returns the pointer to the start of the data in the vector.
164 T* start() const { return start_; }
165
166 // Access individual vector elements - checks bounds in debug mode.
167 T& operator[](int index) const {
168 ASSERT(0 <= index && index < length_);
169 return start_[index];
170 }
171
172 T& first() { return start_[0]; }
173
174 T& last() { return start_[length_ - 1]; }
175
176 private:
177 T* start_;
178 int length_;
179 };
180
181
182 // Helper class for building result strings in a character buffer. The
183 // purpose of the class is to use safe operations that checks the
184 // buffer bounds on all operations in debug mode.
185 class StringBuilder {
186 public:
187 StringBuilder(char* buffer, int size)
188 : buffer_(buffer, size), position_(0) { }
189
190 ~StringBuilder() { if (!is_finalized()) Finalize(); }
191
192 int size() const { return buffer_.length(); }
193
194 // Get the current position in the builder.
195 int position() const {
196 ASSERT(!is_finalized());
197 return position_;
198 }
199
200 // Set the current position in the builder.
201 void SetPosition(int position)
202 {
203 ASSERT(!is_finalized());
204 ASSERT_WITH_SECURITY_IMPLICATION(position < size());
205 position_ = position;
206 }
207
208 // Reset the position.
209 void Reset() { position_ = 0; }
210
211 // Add a single character to the builder. It is not allowed to add
212 // 0-characters; use the Finalize() method to terminate the string
213 // instead.
214 void AddCharacter(char c) {
215 ASSERT(c != '\0');
216 ASSERT(!is_finalized() && position_ < buffer_.length());
217 buffer_[position_++] = c;
218 }
219
220 // Add an entire string to the builder. Uses strlen() internally to
221 // compute the length of the input string.
222 void AddString(const char* s) {
223 AddSubstring(s, StrLength(s));
224 }
225
226 // Add the first 'n' characters of the given string 's' to the
227 // builder. The input string must have enough characters.
228 void AddSubstring(const char* s, int n) {
229 ASSERT(!is_finalized() && position_ + n < buffer_.length());
230 ASSERT_WITH_SECURITY_IMPLICATION(static_cast<size_t>(n) <= strlen(s) );
231 memcpy(&buffer_[position_], s, n * kCharSize);
232 position_ += n;
233 }
234
235
236 // Add character padding to the builder. If count is non-positive,
237 // nothing is added to the builder.
238 void AddPadding(char c, int count) {
239 for (int i = 0; i < count; i++) {
240 AddCharacter(c);
241 }
242 }
243
244 // Finalize the string by 0-terminating it and returning the buffer.
245 char* Finalize() {
246 ASSERT(!is_finalized() && position_ < buffer_.length());
247 buffer_[position_] = '\0';
248 // Make sure nobody managed to add a 0-character to the
249 // buffer while building the string.
250 ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
251 position_ = -1;
252 ASSERT(is_finalized());
253 return buffer_.start();
254 }
255
256 private:
257 Vector<char> buffer_;
258 int position_;
259
260 bool is_finalized() const { return position_ < 0; }
261
262 DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
263 };
264
265 // The type-based aliasing rule allows the compiler to assume that pointers of
266 // different types (for some definition of different) never alias each other .
267 // Thus the following code does not work:
268 //
269 // float f = foo();
270 // int fbits = *(int*)(&f);
271 //
272 // The compiler 'knows' that the int pointer can't refer to f since the type s
273 // don't match, so the compiler may cache f in a register, leaving random da ta
274 // in fbits. Using C++ style casts makes no difference, however a pointer t o
275 // char data is assumed to alias any other pointer. This is the 'memcpy
276 // exception'.
277 //
278 // Bit_cast uses the memcpy exception to move the bits from a variable of on e
279 // type of a variable of another type. Of course the end result is likely t o
280 // be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
281 // will completely optimize BitCast away.
282 //
283 // There is an additional use for BitCast.
284 // Recent gccs will warn when they see casts that may result in breakage due to
285 // the type-based aliasing rule. If you have checked that there is no break age
286 // you can use BitCast to cast one pointer type to another. This confuses g cc
287 // enough that it can no longer see that you have cast one pointer type to
288 // another thus avoiding the warning.
289 template <class Dest, class Source>
290 inline Dest BitCast(const Source& source) {
291 // Compile time assertion: sizeof(Dest) == sizeof(Source)
292 // A compile error here means your Dest and Source have different sizes.
293 static_assert(sizeof(Dest) == sizeof(Source), "sizes should be equal");
294
295 Dest dest;
296 memcpy(&dest, &source, sizeof(dest));
297 return dest;
298 }
299
300 template <class Dest, class Source>
301 inline Dest BitCast(Source* source) {
302 return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
303 }
304 296
305 } // namespace double_conversion 297 } // namespace double_conversion
306 298
307 } // namespace WTF 299 } // namespace WTF
308 300
309 #endif // DOUBLE_CONVERSION_UTILS_H_ 301 #endif // DOUBLE_CONVERSION_UTILS_H_
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/dtoa/strtod.h ('k') | third_party/WebKit/Source/wtf/dtoa_test.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698