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