OLD | NEW |
1 // Copyright (c) 2005, Google Inc. | 1 // Copyright (c) 2005, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 13 matching lines...) Expand all Loading... |
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 #ifndef _BASICTYPES_H_ | 30 #ifndef _BASICTYPES_H_ |
31 #define _BASICTYPES_H_ | 31 #define _BASICTYPES_H_ |
32 | 32 |
33 #include <config.h> | 33 #include <config.h> |
| 34 #include <string.h> // for memcpy() |
34 #ifdef HAVE_INTTYPES_H | 35 #ifdef HAVE_INTTYPES_H |
35 #include <inttypes.h> // gets us PRId64, etc | 36 #include <inttypes.h> // gets us PRId64, etc |
36 #endif | 37 #endif |
37 | 38 |
38 // To use this in an autoconf setting, make sure you run the following | 39 // To use this in an autoconf setting, make sure you run the following |
39 // autoconf macros: | 40 // autoconf macros: |
40 // AC_HEADER_STDC /* for stdint_h and inttypes_h */ | 41 // AC_HEADER_STDC /* for stdint_h and inttypes_h */ |
41 // AC_CHECK_TYPES([__int64]) /* defined in some windows platforms */ | 42 // AC_CHECK_TYPES([__int64]) /* defined in some windows platforms */ |
42 | 43 |
43 #ifdef HAVE_INTTYPES_H | 44 #ifdef HAVE_INTTYPES_H |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 | 187 |
187 #define COMPILE_ASSERT(expr, msg) \ | 188 #define COMPILE_ASSERT(expr, msg) \ |
188 typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] | 189 typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] |
189 | 190 |
190 #define arraysize(a) (sizeof(a) / sizeof(*(a))) | 191 #define arraysize(a) (sizeof(a) / sizeof(*(a))) |
191 | 192 |
192 #define OFFSETOF_MEMBER(strct, field) \ | 193 #define OFFSETOF_MEMBER(strct, field) \ |
193 (reinterpret_cast<char*>(&reinterpret_cast<strct*>(16)->field) - \ | 194 (reinterpret_cast<char*>(&reinterpret_cast<strct*>(16)->field) - \ |
194 reinterpret_cast<char*>(16)) | 195 reinterpret_cast<char*>(16)) |
195 | 196 |
| 197 // bit_cast<Dest,Source> implements the equivalent of |
| 198 // "*reinterpret_cast<Dest*>(&source)". |
| 199 // |
| 200 // The reinterpret_cast method would produce undefined behavior |
| 201 // according to ISO C++ specification section 3.10 -15 -. |
| 202 // bit_cast<> calls memcpy() which is blessed by the standard, |
| 203 // especially by the example in section 3.9. |
| 204 // |
| 205 // Fortunately memcpy() is very fast. In optimized mode, with a |
| 206 // constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline |
| 207 // code with the minimal amount of data movement. On a 32-bit system, |
| 208 // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) |
| 209 // compiles to two loads and two stores. |
| 210 |
| 211 template <class Dest, class Source> |
| 212 inline Dest bit_cast(const Source& source) { |
| 213 COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), bitcasting_unequal_sizes); |
| 214 Dest dest; |
| 215 memcpy(&dest, &source, sizeof(dest)); |
| 216 return dest; |
| 217 } |
| 218 |
196 #ifdef HAVE___ATTRIBUTE__ | 219 #ifdef HAVE___ATTRIBUTE__ |
197 # define ATTRIBUTE_WEAK __attribute__((weak)) | 220 # define ATTRIBUTE_WEAK __attribute__((weak)) |
198 # define ATTRIBUTE_NOINLINE __attribute__((noinline)) | 221 # define ATTRIBUTE_NOINLINE __attribute__((noinline)) |
199 #else | 222 #else |
200 # define ATTRIBUTE_WEAK | 223 # define ATTRIBUTE_WEAK |
201 # define ATTRIBUTE_NOINLINE | 224 # define ATTRIBUTE_NOINLINE |
202 #endif | 225 #endif |
203 | 226 |
204 // Section attributes are supported for both ELF and Mach-O, but in | 227 // Section attributes are supported for both ELF and Mach-O, but in |
205 // very different ways. Here's the API we provide: | 228 // very different ways. Here's the API we provide: |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 # define ATTRIBUTE_SECTION(name) | 325 # define ATTRIBUTE_SECTION(name) |
303 # define DECLARE_ATTRIBUTE_SECTION_VARS(name) | 326 # define DECLARE_ATTRIBUTE_SECTION_VARS(name) |
304 # define INIT_ATTRIBUTE_SECTION_VARS(name) | 327 # define INIT_ATTRIBUTE_SECTION_VARS(name) |
305 # define DEFINE_ATTRIBUTE_SECTION_VARS(name) | 328 # define DEFINE_ATTRIBUTE_SECTION_VARS(name) |
306 # define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0)) | 329 # define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0)) |
307 # define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0)) | 330 # define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0)) |
308 | 331 |
309 #endif // HAVE___ATTRIBUTE__ and __ELF__ or __MACH__ | 332 #endif // HAVE___ATTRIBUTE__ and __ELF__ or __MACH__ |
310 | 333 |
311 #if defined(HAVE___ATTRIBUTE__) && (defined(__i386__) || defined(__x86_64__)) | 334 #if defined(HAVE___ATTRIBUTE__) && (defined(__i386__) || defined(__x86_64__)) |
312 # define CACHELINE_SIZE 64 | 335 # define CACHELINE_ALIGNED __attribute__((aligned(64))) |
313 # define CACHELINE_ALIGNED __attribute__((aligned(CACHELINE_SIZE))) | |
314 #else | 336 #else |
315 # define CACHELINE_ALIGNED | 337 # define CACHELINE_ALIGNED |
316 #endif // defined(HAVE___ATTRIBUTE__) && (__i386__ || __x86_64__) | 338 #endif // defined(HAVE___ATTRIBUTE__) && (__i386__ || __x86_64__) |
317 | 339 |
318 | 340 |
319 // The following enum should be used only as a constructor argument to indicate | 341 // The following enum should be used only as a constructor argument to indicate |
320 // that the variable has static storage class, and that the constructor should | 342 // that the variable has static storage class, and that the constructor should |
321 // do nothing to its state. It indicates to the reader that it is legal to | 343 // do nothing to its state. It indicates to the reader that it is legal to |
322 // declare a static nistance of the class, provided the constructor is given | 344 // declare a static nistance of the class, provided the constructor is given |
323 // the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a | 345 // the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a |
324 // static variable that has a constructor or a destructor because invocation | 346 // static variable that has a constructor or a destructor because invocation |
325 // order is undefined. However, IF the type can be initialized by filling with | 347 // order is undefined. However, IF the type can be initialized by filling with |
326 // zeroes (which the loader does for static variables), AND the destructor also | 348 // zeroes (which the loader does for static variables), AND the destructor also |
327 // does nothing to the storage, then a constructor declared as | 349 // does nothing to the storage, then a constructor declared as |
328 // explicit MyClass(base::LinkerInitialized x) {} | 350 // explicit MyClass(base::LinkerInitialized x) {} |
329 // and invoked as | 351 // and invoked as |
330 // static MyClass my_variable_name(base::LINKER_INITIALIZED); | 352 // static MyClass my_variable_name(base::LINKER_INITIALIZED); |
331 namespace base { | 353 namespace base { |
332 enum LinkerInitialized { LINKER_INITIALIZED }; | 354 enum LinkerInitialized { LINKER_INITIALIZED }; |
333 } | 355 } |
334 | 356 |
335 #endif // _BASICTYPES_H_ | 357 #endif // _BASICTYPES_H_ |
OLD | NEW |