OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project 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 V8_BASE_MACROS_H_ | 5 #ifndef V8_BASE_MACROS_H_ |
6 #define V8_BASE_MACROS_H_ | 6 #define V8_BASE_MACROS_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 // That gcc wants both of these prototypes seems mysterious. VC, for | 95 // That gcc wants both of these prototypes seems mysterious. VC, for |
96 // its part, can't decide which to use (another mystery). Matching of | 96 // its part, can't decide which to use (another mystery). Matching of |
97 // template overloads: the final frontier. | 97 // template overloads: the final frontier. |
98 template <typename T, size_t N> | 98 template <typename T, size_t N> |
99 char (&ArraySizeHelper(const T (&array)[N]))[N]; | 99 char (&ArraySizeHelper(const T (&array)[N]))[N]; |
100 #endif | 100 #endif |
101 | 101 |
102 #endif // V8_OS_NACL | 102 #endif // V8_OS_NACL |
103 | 103 |
104 | 104 |
105 // The COMPILE_ASSERT macro can be used to verify that a compile time | |
106 // expression is true. For example, you could use it to verify the | |
107 // size of a static array: | |
108 // | |
109 // COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES, | |
110 // content_type_names_incorrect_size); | |
111 // | |
112 // or to make sure a struct is smaller than a certain size: | |
113 // | |
114 // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); | |
115 // | |
116 // The second argument to the macro is the name of the variable. If | |
117 // the expression is false, most compilers will issue a warning/error | |
118 // containing the name of the variable. | |
119 #if V8_HAS_CXX11_STATIC_ASSERT | |
120 | |
121 // Under C++11, just use static_assert. | |
122 #define COMPILE_ASSERT(expr, msg) static_assert(expr, #msg) | |
123 | |
124 #else | |
125 | |
126 template <bool> | |
127 struct CompileAssert {}; | |
128 | |
129 #define COMPILE_ASSERT(expr, msg) \ | |
130 typedef CompileAssert<static_cast<bool>(expr)> \ | |
131 msg[static_cast<bool>(expr) ? 1 : -1] ALLOW_UNUSED_TYPE | |
132 | |
133 // Implementation details of COMPILE_ASSERT: | |
134 // | |
135 // - COMPILE_ASSERT works by defining an array type that has -1 | |
136 // elements (and thus is invalid) when the expression is false. | |
137 // | |
138 // - The simpler definition | |
139 // | |
140 // #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] | |
141 // | |
142 // does not work, as gcc supports variable-length arrays whose sizes | |
143 // are determined at run-time (this is gcc's extension and not part | |
144 // of the C++ standard). As a result, gcc fails to reject the | |
145 // following code with the simple definition: | |
146 // | |
147 // int foo; | |
148 // COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is | |
149 // // not a compile-time constant. | |
150 // | |
151 // - By using the type CompileAssert<static_cast<bool>(expr)>, we ensure that | |
152 // expr is a compile-time constant. (Template arguments must be | |
153 // determined at compile-time.) | |
154 // | |
155 // - The array size is (static_cast<bool>(expr) ? 1 : -1), instead of simply | |
156 // | |
157 // ((expr) ? 1 : -1). | |
158 // | |
159 // This is to avoid running into a bug in MS VC 7.1, which | |
160 // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. | |
161 | |
162 #endif | |
163 | |
164 | |
165 // bit_cast<Dest,Source> is a template function that implements the | 105 // bit_cast<Dest,Source> is a template function that implements the |
166 // equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in | 106 // equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in |
167 // very low-level functions like the protobuf library and fast math | 107 // very low-level functions like the protobuf library and fast math |
168 // support. | 108 // support. |
169 // | 109 // |
170 // float f = 3.14159265358979; | 110 // float f = 3.14159265358979; |
171 // int i = bit_cast<int32>(f); | 111 // int i = bit_cast<int32>(f); |
172 // // i = 0x40490fdb | 112 // // i = 0x40490fdb |
173 // | 113 // |
174 // The classical address-casting method is: | 114 // The classical address-casting method is: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 // code with the minimal amount of data movement. On a 32-bit system, | 150 // code with the minimal amount of data movement. On a 32-bit system, |
211 // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) | 151 // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) |
212 // compiles to two loads and two stores. | 152 // compiles to two loads and two stores. |
213 // | 153 // |
214 // I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1. | 154 // I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1. |
215 // | 155 // |
216 // WARNING: if Dest or Source is a non-POD type, the result of the memcpy | 156 // WARNING: if Dest or Source is a non-POD type, the result of the memcpy |
217 // is likely to surprise you. | 157 // is likely to surprise you. |
218 template <class Dest, class Source> | 158 template <class Dest, class Source> |
219 V8_INLINE Dest bit_cast(Source const& source) { | 159 V8_INLINE Dest bit_cast(Source const& source) { |
220 COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), VerifySizesAreEqual); | 160 static_assert(sizeof(Dest) == sizeof(Source), |
221 | 161 "source and dest must be same size"); |
222 Dest dest; | 162 Dest dest; |
223 memcpy(&dest, &source, sizeof(dest)); | 163 memcpy(&dest, &source, sizeof(dest)); |
224 return dest; | 164 return dest; |
225 } | 165 } |
226 | 166 |
227 | 167 |
228 // Put this in the private: declarations for a class to be unassignable. | 168 // Put this in the private: declarations for a class to be unassignable. |
229 #define DISALLOW_ASSIGN(TypeName) void operator=(const TypeName&) | 169 #define DISALLOW_ASSIGN(TypeName) void operator=(const TypeName&) |
230 | 170 |
231 | 171 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 | 355 |
416 template <> | 356 template <> |
417 inline bool is_fundamental<uint8_t>() { | 357 inline bool is_fundamental<uint8_t>() { |
418 return true; | 358 return true; |
419 } | 359 } |
420 | 360 |
421 } // namespace base | 361 } // namespace base |
422 } // namespace v8 | 362 } // namespace v8 |
423 | 363 |
424 #endif // V8_BASE_MACROS_H_ | 364 #endif // V8_BASE_MACROS_H_ |
OLD | NEW |