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